webpack4号称零配置开箱即用,那么来看看webpack4.x和3.x比较大的区别 webpack Release v4.0.0
webpack4引入了零配置的概念(实际配置下来还是要写不少配置),官方宣传能够提升构建速度60%-98%,听起来让人非常心动,那么接下来看看有哪些大的变化:
1.Node环境的升级:不在支持node 4.0的版本,最低支持6.11.5
2.配置项增加了mode:'production' | 'development' | 'none'
webpack 使用相应模式的内置优化
-
none
: 退出任何默认优化配置(此时所有配置都需要自定义) -
development
:会将 process.env.NODE_ENV 的值设为development
,启用optimization.nameModules、
optimization.namedChunks`(原nameModulesPlugin、NamedChunksPlugin 弃用)。
相当于如下配置:
// webpack.development.config.js
module.exports = {
+ mode: 'development'
- devtool: 'eval', //sourceMap为eval类型
//开发环境下默认启用cache,在内存中对已经构建的部分进行缓存
//避免其他模块修改,但是该模块未修改时重新构建
- cache: true,
- performance: {
- hints: false
- },
- output: {
- pathinfo: true//输入代码添加额外的路径注释,提高代码可读性
- },
- optimization: {
- namedModules: true,//取代插件中的 new webpack.NamedModulesPlugin()
- namedChunks: true,//取代插件中的 new webpack.NamedChunksPlugin()
- nodeEnv: 'development',
- flagIncludedChunks: false,
- occurrenceOrder: false,
- sideEffects: false,
- usedExports: false,
- concatenateModules: false,
- splitChunks: {
- hidePathInfo: false,
- minSize: 10000,
- maxAsyncRequests: Infinity,
- maxInitialRequests: Infinity,
- },
- noEmitOnErrors: false,
- checkWasmTypes: false,
- minimize: false,
- removeAvailableModules: false
- },
- plugins: [
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),//默认添加NODE_ENV为development
- ]
}
-
production
,会将 process.env.NODE_ENV 的值设为production
,启用FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin , OccurrenceOrderPlugin , SideEffectsFlagPlugin 和 TerserPlugin
TerserPlugin:
替代了uglifyjs-webpack-plugin
,作用依然是对构建输出的代码进行压缩FlagIncludedChunksPlugin:
检测并标记模块之间的从属关系。ModuleConcatenationPlugin:
可以让webpack根据模块间的关系依赖图中,将所有的模块连接成一个模块。SideEffectsFlagPlugin:
告诉webapck去清除一个大的模块文件中的未使用的代码,这个大的文件模块可以
是自定义的,也可以是第三方的(注意:一定要package.json
文件中添加"sideEffects": false
)。OccurrenceOrderPlugin:
告诉webapck各个模块间的先后顺序,这样可以实现最优的构建输出。NoEmitOnErrorsPlugin :
编译错误时不打印输出资源
相当于如下配置:
// webpack.production.config.js
module.exports = {
+ mode: 'production',
- performance: {
- hints: 'warning'
- },
- output: {
- pathinfo: false
- },
- optimization: {
- namedModules: false,
- namedChunks: false,
- nodeEnv: 'production',
- flagIncludedChunks: true,
- occurrenceOrder: true,
//识别package.json中的sideEffects以剔除无用的模块,用来做tree-shake
//依赖于optimization.providedExports和optimization.usedExports
- sideEffects: true,
- usedExports: true,
- concatenateModules: true, //取代 new webpack.optimize.ModuleConcatenationPlugin()
- splitChunks: {
- hidePathInfo: true,
- minSize: 30000,
- maxAsyncRequests: 5,
- maxInitialRequests: 3,
- },
- noEmitOnErrors: true,//取代 new webpack.NoEmitOnErrorsPlugin()
- checkWasmTypes: true,
- minimize: true,//告诉webpack使用TerserPlugin或optimization.minimizer中指定的插件最小化包。
- },
- plugins: [
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),//默认添加NODE_ENV为production
- ]
}
3.原生支持处理JSON文件格式,不需要json-loader
4.内置插件 uglifyjs-webpack-plugin
升级到了 V1支持并行处理压缩混淆JS,发挥多核CPU的优势
5.在 webpack4 以前,使用 extract-text-webpack-plugin
插件将 css 从 js 包中分离出来单独打包,现在需要换成 MiniCssExtractPlugin
6.CommonsChunkPlugin
废弃,代替的是optimization.splitChunks 和 optimization.runtimeChunk
-
optimization.runtimeChunk :object | string | boolean
,作用是分离出webpack runtime代码;
默认值:false
(默认不分离,就是全部打包进入口chunk里面),这样不利于缓存优化;
PS:
单页应用时不管设置'multiple' | true | 'single'
都没影响;
多页应用请设置为true | 'multiple'
,每个页面的runtime文件只会打包到对应页面,
同时注意插件HtmlWebpackPlugin
的chunks
参数要加入分离出的runtime块,true
时是`runtime~${chunk}`
single
时是`runtime`
runtime也是chunk,因此走out.filename,其他的非入口块走chunkfilename,htmlWebpackPlugin配置chunks需要声明所有入口块
optimization.runtimeChunk = 'single'
时效果等同于下面:
//打包出来的runtime文件形如 runtime.a3897b11.js
optimization: {
runtimeChunk: {
name: 'runtime'
}
}
optimization.runtimeChunk = true | 'multiple'
时效果等同于下面:
//打包出来的runtime文件形如 runtime~app.a3897b11.js
optimization: {
runtimeChunk: {
name: entrypoint => `runtime~${entrypoint.name}`
}
}
-
optimization.splitChunks
配置详解:
splitChunks: {
chunks: "async”,//决定哪些chunk被优化,默认作用于异步chunk,值为all/initial/async/function(chunk)
minSize: 30000, //生成块的最小大小,默认值是30kb
minChunks: 1, //被多少模块共享
maxAsyncRequests: 5, //所有异步请求不得超过5个
maxInitialRequests: 3, //初始话并行请求不得超过3个
name: true, //打包后的名称,默认是chunk的名字通过分隔符(默认是~)分隔开,如vendor~
cacheGroups: { //设置缓存组用来抽取满足不同规则的chunk,下面以生成common为例
common: {
name: 'common', //抽取的chunk的名字
chunks(chunk) { //同外层的参数配置,覆盖外层的chunks,以chunk为维度进行抽取
},
test(module, chunks) { //可以为字符串,正则表达式,函数,以module为维度进行抽取,只要是满足条件的module都会被抽取到该common的chunk中,为函数时第一个参数是遍历到的每一个模块,第二个参数是每一个引用到该模块的chunks数组。自己尝试过程中发现不能提取出css,待进一步验证。
},
priority: 10, //权重,一个chunk很可能满足多个缓存组,会被抽取到优先级高的缓存组中
minChunks: 2, //最少被几个chunk引用
reuseExistingChunk: true,// 如果该chunk中引用了已经被抽取的chunk,直接引用该chunk,不会重复打包代码
enforce: true // 如果cacheGroup中没有设置minSize,则据此判断是否使用上层的minSize,true:则使用0,false:使用上层minSize
}
}
}
本人使用的配置:
splitChunks: {
chunks: "all",
cacheGroups: {
libs: {
name: "chunk-libs",
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: "initial" // 只打包初始时依赖的第三方
},
elementUI: {
name: "chunk-elementUI", // 分割 elementUI 到单独的包
priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
test: /[\\/]node_modules[\\/]element-ui[\\/]/
},
commons: {
name: "chunk-commons",
test: resolve("src/components"), // 自定义公共业务组件的绝对路径
minChunks: 2, // 最小共用次数
priority: 5,
reuseExistingChunk: true
}
}
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。