默认配置
webpack 4 引入了零配置的概念,提供的默认配置来减少重复工作。
development 模式下,默认开启了NamedChunksPlugin 和NamedModulesPlugin方便调试,提供了更完整的错误信息,更快的重新编译的速度。
production 模式下,自动开启splitChunks和minimizer,所以基本零配置,代码就会自动分割、压缩、优化,同时 webpack 也会自动帮你 Scope Hoisting, Tree-shaking 。
注:v4.26后,minimizer等于true默认使用的插件已由UglifyJsPlugin变为TerserPlugin。
主要默认配置:
详细的mode默认配置,可以看这里。
几种hash
hash
hash 和每次 build有关,没有任何改变的情况下,每次编译出来的 hash都是一样的,但当你改变了任何一点东西,它的hash就会发生改变。
chunkhash
chunkhash是根据具体每一个模块文件自己的的内容包括它的依赖计算所得的hash,所以某个文件的改动只会影响它本身的hash,不会影响其它文件。
contenthash
当一个vue文件打包成一个js时,使用MiniCssExtractPlugin会让css样式单独提取为一个css文件,这个提取出的css文件,与vue编译的js文件,有相同的chunkid。而contenthash是根据css内容决定的,内容不变,contenthash不变,所以应该使contenthash作为部分文件名。
new MiniCssExtractPlugin({
filename: "static/css/[name]-css-[contenthash:5].css"
})
output:path 与 publicPath
path:指定输出文件的目标路径
publicPath:用于在生产模式下更新内嵌到css、html文件里的url值。
举个例子:
css中,这样引用一个图片
.image {
background-image: url('./test.png');
}
但在生产环境下,需要引用cdn中的图片,这时通过定义publicPath来改变引用路径。
module.exports = merge(baseConfig, {
mode: "production",
output: {
publicPath:'https://someCDN'
}
}
打包后
.image {
background-image: url('https://someCDN/test.png');
}
代码分割
webpack 4 的Code Splitting 它最大的特点就是配置简单,如果你的 mode 是 production,那么 webpack 4 就会自动开启 Code Splitting。
webpack内置分包策略:
- 新代码块可以被共享引用,或者这些模块都是来自node_modules文件夹里面
- 新代码块大于30kb(min+gziped之前的体积)
- 按需加载并发最大请求数, 应该小于或者等于5
- 初始加载的代码块,最大数量应该小于或等于3
配置
optimization: {
splitChunks: {
chunks: "async", // 必须三选一: "initial" | "all"(推荐) | "async" (默认就是async)
minSize: 30000, // 最小尺寸,30000
minChunks: 1, // 最小 chunk ,默认1,只要被引用一次就分割出来
maxAsyncRequests: 5, // 最大异步请求数, 默认5
maxInitialRequests : 3, // 最大初始化请求书,默认3
automaticNameDelimiter: '~',// 打包分隔符
name: function(){}, // 打包后的名称,此选项可接收 function
cacheGroups:{ // 这里开始设置缓存的 chunks
vendor: { // key 为entry中定义的 入口名称
chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是async)
test: /react|lodash/, // 正则规则验证,如果符合就提取 chunk
name: "vendor", // 要缓存的 分隔出来的 chunk 名称
priority: 0, // 缓存组优先级
minSize: 30000,
minChunks: 1,
enforce: true,
maxAsyncRequests: 5, // 最大异步请求数, 默认5
maxInitialRequests : 3, // 最大初始化请求书,默认3
reuseExistingChunk: true // 可设置是否重用该chunk
}
}
}
}
minChunks
最小 被引用的次数 ,默认1,只要被引用一次就分割出来。
maxAsyncRequests
表示能异步请求的最大数量。比如异步请求一个文件,文件中还异步请求另一个文件,这时两个文件会分开打包,如果设置为1,两个异步请求文件会打包在一起。详细解释可以看webpack4 maxAsyncRequests记录。
maxInitialRequests
代码分割以后,除去runtime所能生成的最多脚本数量。
chunks
表示参与代码分割的模块类型
demo里,如果chunks赋值为:
- initial:将所有非动态加载的模块放到vendor 里
- async:将所有动态加载的模块打包到vendor
- all:把动态和非动态模块同时进行优化打包,放到vendor里
详细讲解可以看这里。
cacheGroups
cacheGroups:缓存组,可以设置缓存的chunks。
注意:
- cacheGroups 会继承和覆盖splitChunks的配置项,但是test、priorty和reuseExistingChunk只能用于配置缓存组。
optimization.runtimeChunk
通过optimization.runtimeChunk: true选项,webpack会添加一个只包含运行时(runtime)额外代码块到每一个入口。
打包后的js包括webpackJsonp,checkDeferredModules,__webpack_require__,__webpack_require__.e等用于模块加载的方法。
其中jsonpScriptSrc,函数中存在chunkid与chunkname的映射,用于根据chunkid得到chunks的加载路径。因为这个映射会受chunk增加或减少的影响,经常变化,不单独打包会生成到每个非异步加载的chunk里,使得本来没变的chunk也不能缓存了。所以一般会单独打包或内嵌到html里。
异步加载打包模块
正常情况下,通过异步引用的模块会打包成一个chunk。如果引用路径是动态的,比如:
ret.component = () => import("@/views" + ret.path + ".vue");
会把views文件下,所有没有被引用的组件(被引用的是子组件),单独打包成chunk。
参考资料
手摸手,带你用合理的姿势使用webpack4
Webpack——解决疑惑,让你明白
没有了CommonsChunkPlugin,咱拿什么来分包(译)