使用 webpack 提取公共代码

在开发过程中,我们会有很多公用的模块组件,可能有多个模块依赖同一个模块。

例如: A 和 B 同时都依赖于 C ,用户来浏览器访问了这两个模块,那么 C 就会被加载两次。如果我们把 C 提取出来,当加载 A 的时候, C 就已经加载了,到加载 B 的时候,就可以直接使用 C ,而不用去重新加载。

提取公共代码的好处?

  • 减少代码的冗余
  • 提高加载速度

使用 CommonsChunkPlugin 插件提取公共代码

webpack 4.x 版本后,此插件已被删除,使用了新的配置项,optimization.splitChunks, 此配置项和 plugins 同级,官方文档

配置

在 plugins 中增加一个插件的实例

{
  plugins: [new webpack.optimize.CommonsChunkPlugin(options)]
}
  • options.name or options.names
    chunk 的名称
  • options.filename
    打包后的文件名
  • options.minChunks
    同样代码重复出现的最小次数,大于此配置就提取为公共代码
  • options.chunks
    指定提取代码的范围
  • options.children
    是否在子模块中查找依赖
  • options.deepChildren
    是否在所有模块中查找依赖
  • options.async
    创建一个异步公共代码流

场景

  • 单页应用
  • 单页应用 + 第三方依赖
  • 单页应用 + 第三方依赖 + webpack 生成代码

实际配置操作

  • 新建项目文件,并初始化 npm init

  • webpack 安装到项目依赖中, npm i -D webpack webpack-cli

  • 创建 src目录,并在下面创建子文件,编辑内容如下:

    • pageA.js

      import './subPageA'
      import './subPageB'
      export default 'pageA'
      
    • subPageA.js

      import './moduleA'
      export default 'subPageB'
      
    • subPageB.js

      import './moduleA'
      export default 'subPageB'
      
    • moduleA.js

      export default 'moduleA'
      
  • 在项目根目录创建 webpack.config.js 配置文件

    • webpack.config.js

      // webpack 3.x
      
      const webpack = require('webpack')
      const path = require('path')
      
      module.exports = {
        entry: {
          pageA: './src/pageA.js'
        },
        output: {
          path: path.resolve(__dirname, './dist'),
          filename: '[name].bundle.js',
          chunkFilename: '[name].chunk.js'
        },
        plugins: [
          new webpack.optimize.CommonsChunkPlugin({
            name: 'common',
            minChunks: 2
          })
        ]
      }
      
      // webpack 4.x
      
      const webpack = require('webpack')
      const path = require('path')
      
      module.exports = {
        mode: 'development',
        entry: {
          pageA: './src/pageA.js'
        },
        output: {
          path: path.resolve(__dirname, './dist'),
          filename: '[name].bundle.js',
          chunkFilename: '[name].chunk.js'
        },
        plugins: [],
        optimization: {
          splitChunks: {
            cacheGroups: {
              commons: {
                chunks: 'initial',
                name: 'common',
                minChunks: 2
              }
            }
          }
        }
      }
      
  • 运行 webpack

      PS D:\test\my-webpack\3-5> webpack
      Hash: 48b815fbe7f5424484b7
      Version: webpack 3.10.0
      Time: 69ms
                 Asset     Size  Chunks             Chunk Names
       pageA.bundle.js  1.21 kB       0  [emitted]  pageA
      common.bundle.js  5.81 kB       1  [emitted]  common
         [0] ./src/moduleA.js 24 bytes {0} [built]
         [1] ./src/pageA.js 64 bytes {0} [built]
         [2] ./src/subPageA.js 45 bytes {0} [built]
         [3] ./src/subPageB.js 45 bytes {0} [built]
    
  • 编译成功