webpack基本配置项总结

webpack是一个用于web项目的模板打包工具。在大部分的使用场景中,我们将它看作是一个web前端模块打包工具,它将资源的本身当做模块,这些模块可以被导入和操作,最后打包到指定的文件中

下面详细讲解各个配置项的配置方法
首先写一个简单的webpack.config.js文件

module.exports = {
    entry:'./src/index.js',
    output:{
        path:'builds',
        filename:'bundle.js',
    },
}

为了在配置文件中使用的路径全部是相对于该配置文件的具体路径,可以引入path模块

var path = require('path')
module.exports = {
    entry: path.resolve(__dirname, './src/index.js'),
    output:{
        path: path.resolve(__dirname,'builds'),
        filename:'bundle.js',
    },
}

entry

entry配置项标识了项目的入口文件,该配置项的值可以为字符串、数组和对象三种形式。字符串和数组类型相当于json对象的简写

对象entry

对象entry的主要形式如下

entry: {
    <key>: <value>
}

key可以是简单的字符串,比如:’app’, ‘main’, ‘entry-1’等。并且对应着output.filename配置中的[name]变量

entry: {
    'index': './src/index.js'
},
output: {
    path: './build',
    filename: '[name]-build.js'
}

value的值可以为字符串或数组。如果是字符串的话,可以为字符串路径,也可以为安装的npm包;如果是数组,则数组中元素需要是合理字符串值。数组中的文件一般是没有相互依赖关系的,但是又处于某些原因需要将它们打包在一起

数组entry和字符串entry

数组entry是对象entry中的value值组成的数组,可以用于多入口文件的配置,字符串entry只能用于单入口文件的配置

//字符串entry文件配置
entry: './src/index.js'

//数组entry文件配置
entry: [
    './src/index1.js',
    './src/index2.js'
]

output

output项告诉webpack怎样存储输出结果以及存储到哪里。output常用配置项如下:

  • path:必须配置项,表示生成文件的根目录,需要传入一个绝对路径。
  • filename:必须配置项,表示生成文件的文件名,规则有以下三种
    • [name]:指代入口文件的name,也就是上面提到的entry参数的key
    • [hash]:指代本次编译的一个hash版本。值得一提的是,只要是在同一次编译过程中生成的文件,这个[hash]值就是一样的,对于文件名相当于一次全量的替换,从缓存的层面来说,每次编译的文件都需要重新加载
    • [chunkhash]:指代的是当前chunk的一个hash版本。也就是说,在同一次编译中,每一个chunk的hash都是不一样的;而在两次编译中,如果某个chunk根本没发生变化,那么该chunk的hash也就不会发生变化。从缓存层面来讲,就是把缓存的粒度精细到具体某个chunk,只要chunk不变,该chunk的浏览器缓存就可以继续使用。
entry: {
    index:'./src/index.js'
},
output:{
    path:'./builds',
    filename:'[name]-[chunkhash:8]-bundle.js',
},
  • publishPath: 表示一个URL路径(指向生成文件的根目录),用于生成css/js/image/字体文件等资源的路径。

publicPath参数跟path参数的区别是:path参数其实是针对本地文件系统的,而publicPath则针对的是浏览器;因此,publicPath既可以是一个相对路径,如示例中的’../../../../build/’,也可以是一个绝对路径如http://www.xxxxx.com/。一般来说,我还是更推荐相对路径的写法,这样的话整体迁移起来非常方便。那什么时候用绝对路径呢?其实也很简单,当你的html文件跟其它资源放在不同的域名下的时候,就应该用绝对路径了,这种情况非常多见于后端渲染模板的场景。

  • chunkFilename: 指定除入口文件外的chunk的命名方法,其参数与filename的参数类似

Loaders和rules

Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件(如jsx、图片、css等文件),就需要使用 loader 进行转换。loader可以通过管道方式链式调用。每个loader可以把资源转换成任意格式并传递给下一个loader,但是最后一个loader必须返回JavaScript

一般情况下,Loader一般以xxx-loader的方式命名,xxx代表了这个loader要做的转换功能。在引用loader的时候可以使用全名xxx-loader,或者使用短名xxx。

Loader的常用配置项如下:
* test: 指示当前配置项针对哪些资源,该值一般是一个正则表达式,用来指定文件名
* exclude: 表示需要忽略的资源,该值一般是一个正则表达式
* include: 表示该配置项针对的文件目录,该值一般是正则表达式,include和test的配置项共同构成了该loader的作用范围
* loader/loaders: 表示用哪个或哪些loader来处理目标资源,loader的值一般是一个字符串,laoders的值一般是一个数组

module: {
    loaders: [
      {
          test: /\.css$/, 
          include: /src/
          exclude: /node_modules/
          loader: 'style-loader!css-loader'
      }
    ]
  }

上述例子的loader执行顺序是将src文件夹下的css文件内容先经过css-loader处理(路径处理、import处理等),然后经过style-loader处理(包装成JS文件,运行的时候直接将样式插入DOM中。)

值得注意的是loaders的配置项是在webpack1.X版本中使用的,在webpack2.X中引入了更加强大的rules,当然在2.X中loaders的属性名依然可以被解析
2.X将loaders配置项修改为了rules,将loader/loaders改为use,并且在rules中不能使用链式书写,loader引用loader必须使用全名

  module: {
   rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: "style-loader"
          },
          {
            loader: "css-loader",
            options: {
              modules: true
            }
          }
        ]
      },
    ]
  }

Plugins

插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。
Loaders和plugins是两个完全不同的东西。Loaders是在打包构建过程中用来处理源文件的(JSX、SCSS、LESS等),一次处理一种文件;Plugins并不直接操作单个文件,它直接作用于整个构建过程
和Plugins

插件使用方法及常用插件

要使用某个插件,我们需要通过npm安装它,然后在webpack配置中的plugins关键字部分添加该插件的一个实例。
下面介绍一下常用的插件
extract-text-webpack-plugin

const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("styles.css"),
  ]
}

该插件会将所有的入口chunk中引入的css文件移动到分哭的css文件。因此,样式不会内联到JavaScript中,但会放到一个单独的css包文件中。
其主要配置项如下

  • id:字符串,表示此插件实例的唯一ID。(仅限高级用途,默认情况下自动生成)
  • filename: 字符串,必填。表示生成恩建的文件名。会包含[name]、[id]和[contenthash]
  • allChunks:布尔值。表示向所有额外的chunk提取(默认肢体去初始加载模块)
  • disable:布尔值。禁用插件
  • ignoreOrder:禁用顺序检查,默认false

ExtractTextPlugin.extract(options: loader | object)从一个已存在的加载器 (loader) 中创建一个 提取 (extracting) 加载器。主要配置项

  • options.use: (必填), 加载器 (Loader), 被用于将资源转换成一个输出的 CSS 模块
  • options.fallback: 加载器 (例如 ‘style-loader’), 应用于当 css 没有被提取(也就是一个额外的 chunk,当 allChunks: false)
  • options.publicPath:对加载器的 publicPath 配置重写

HtmlWebpackPlugin

HtmlWebpackPlugin简化了HTML文件的创建,以便为您的webpack包提供服务。 这对于在文件名中包含每次会随着变异会发生变化的哈希的webpack bundle尤其有用。

const HtmlWebpackPlugin = require('html-webpack-plugin');
module: {
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'src/app/index.html',
            inject: true,
            chunks: ['vendor', 'index'], //会自动将js文件插入html中
            chunksSortMode: 'dependency',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeRedundantAttributes: true,
                useShortDoctype: true,
                removeEmptyAttributes: true,
                removeStyleLinkTypeAttributes: true,
                keepClosingSlash: true,
                minifyJS: true,
                minifyCSS: true,
                minifyURLs: true,
            },
        }),
    ]
}

该插件常用配置项如下:
* filename: 输出文件的文件名称,默认为index.html。此外,还可以为输出文件制定目录位置

1、filename配置的html文件目录是相对于webpackConfig.output.path路径而言的,不是相对于当前项目目录结构的。
2、指定生成的html文件内容中的link和script路径是相对于生成目录下的,写路径的时候请写生成目录下的相对路径。

  • template:本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等),比如 handlebars!src/index.hbs;为template指定的模板文件没有指定任何loader的话,默认使用ejs-loader。如template: ‘./index.html’,若没有为.html指定任何loader就使用ejs-loader
  • templateContent: string|function,可以指定模板的内容,不能与template共存。配置值为function时,可以直接返回html字符串,也可以异步调用返回html字符串。
  • inject:向template或者templateContent中注入所有静态资源,不同的配置值注入的位置不经相同。

    1、true或者body:所有JavaScript资源插入到body元素的底部
    2、head: 所有JavaScript资源插入到head元素中
    3、false: 所有静态资源css和JavaScript都不会注入到模板文件中

  • hash: true|false,是否为所有注入的静态资源添加webpack每次编译产生的唯一hash值,添加hash形式如下所示

html <script type="text/javascript" src="common.js?a3e1396b501cdd9041be"></script>
  • chunks:允许插入到模板中的一些chunk,不配置此项默认会将entry中所有的thunk注入到模板中。在配置多个页面时,每个页面注入的chunk应该是不相同的,需要通过该配置为不同页面注入不同的chunk;
  • excludeChunks: 这个与chunks配置项正好相反,用来配置不允许注入的thunk。
  • chunksSortMode: none | auto| function,默认auto; 允许指定的thunk在插入到html文档前进行排序。

    function值可以指定具体排序规则;auto基于thunk的id进行排序; none就是不排序

  • xhtml: true|fasle, 默认false;是否渲染link为自闭合的标签,true则为自闭合标签

  • cache: true|fasle, 默认true; 如果为true表示在对应的thunk文件修改后就会emit文件
  • showErrors: true|false,默认true;是否将错误信息输出到html页面中。这个很有用,在生成html文件的过程中有错误信息,输出到页面就能看到错误相关信息便于调试。
  • minify:{….}|false,传递 html-minifier 选项给 minify 输出,false就是不使用html压缩。
    html-webpack-plugin的一个实例生成一个html文件,如果单页应用中需要多个页面入口,或者多页应用时配置多个html时,那么就需要实例化该插件多次;即有几个页面就需要在webpack的plugins数组中配置几个该插件实例:
    plugins: [
        new HtmlWebpackPlugin({
             template: 'src/html/index.html',
              excludeChunks: ['list', 'detail']
        }),
        new HtmlWebpackPlugin({
            filename: 'list.html',
            template: 'src/html/list.html',
            thunks: ['common', 'list']
        }), 
        new HtmlWebpackPlugin({
          filename: 'detail.html',
          template: 'src/html/detail.html',
           thunks: ['common', 'detail']
        })
    ]

如上例应用中配置了三个入口页面:index.html、list.html、detail.html;并且每个页面注入的thunk不尽相同;类似如果多页面应用,就需要为每个页面配置一个;

CommonsChunkPlugin

CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件(又称作 chunk)的功能,这个文件包括多个入口 chunk 的公共模块。通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存起来到缓存中供后续使用。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。

 plugins: [
    new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor',
                filename: 'vendor.bundle.js' //gave the chunk a different name
            }),
]

resolve

resolve的配置标识模块如何解析。例如,当在 ES2015 中调用 import “lodash”,resolve 选项能够对 webpack 查找 “lodash” 的方式去做修改(查看模块)。
resolve.alias改配置对象键名为模块名,键值为新的路径。类似于替换但是更比替换更好

const path = require('path')
const resolveApp = relativePath => path.resolve(appDirectory, relativePath),
    appSrc = resolveApp('src'),
    appUrl = resolveApp('src/app'),

    appImages = resolveApp('src/assets/images'),
    appComponents = resolveApp('src/app/components'),
    appPages = resolveApp('src/app/pages'),
    appUtils = resolveApp('src/app/util');

resolve: {
        alias: {
            Src: appSrc,
            Images: appImages,
            Components: appComponents,
            Util: appUtils
        },
    },

参考文献

  1. 令人困惑的 webpack 之 entry
  2. webpack多页应用架构系列(二):webpack配置常用部分有哪些?
  3. 入门Webpack,看这篇就够了
  4. ExtractTextWebpackPlugin
  5. html-webpack-plugin详解
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值