3
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文件只会打包到对应页面,
同时注意插件HtmlWebpackPluginchunks参数要加入分离出的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
    }
  }
};

renbuzhudek
1 声望0 粉丝

落魄前端,在线炒粉,5元一份!