使用入口拆分

conf:

  1. const splitChunkConf = {
  2. mode: "development",
  3. entry: {
  4. shared: ["lodash"],
  5. app: {
  6. import: "./src/index.js",
  7. dependOn: "shared"
  8. },
  9. },
  10. output: {
  11. path: pathResolve("out"),
  12. filename: "[name].[contenthash].js",
  13. clean: true
  14. },
  15. module: {
  16. rules: moduleRules
  17. },
  18. plugins: [
  19. plugins.html
  20. ]
  21. };
  22. // html.就是html-webpack-plugin, rules就是对js和css源文件的处理
  23. export default splitChunkConf1;

结果:

asset shared.a81d67a3747b764a5c0f.js 556 KiB [emitted] [immutable] (name: shared)
asset app.87dd7732ede1523a6f5a.js 1.96 KiB [emitted] [immutable] (name: app)
asset index.html 311 bytes [emitted]
runtime modules 3.08 KiB 6 modules
cacheable modules 532 KiB  ./src/index.js 595 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
webpack 5.64.4 compiled successfully in 344 ms

shared会被单独打包,指定app依赖的模块存在shared,也可以写成数组

使用dll

conf:

function dll() {
  webpack({
    entry: {
      lodash: "lodash",
      // react: ["react", "react-dom"]
    },
    output: {
      filename: "[name].dll.js",
      path: resolve(dirname(""), "dll"),
      clean: true
    },
    plugins: [
      new webpack.DllPlugin({
        context: dirname(""),
        format: true,
        path: join(resolve(dirname(""), 'dll'), "manifest.json"),
      })
    ]
  },
    (_, stats) => {
      console.log(stats.toJson().assets);
    }
  );
}

dll();


webpack.config.js
 new DllReferencePlugin({
   context: resolve(dirname(".")),
   manifest: resolve(dirname("."), "dll/manifest.json")
 })

这种拆分可以理解为缓存,把第三方模块单独抽离出来,在开发或者打包时不会再会dll进行处理,只会处理源文件。

使用dll比如react类库,在开始时建议指定dev环境,以为内部的警告只会在dev环境发出

但是dll这个拆分的方法在webpack4以后已经不推荐了。 因为有了新的东西可以替代。像vue-cli,reac都已经去掉了dll的使用

splitChunksPlugins

optimizationsplitchunks原本是一个独立的插件,后来webpack内置了,可以在optimization.splitChunks 中指定配置

const splitChunkConf1 = {
  mode: "development",
  entry: "./src/index.js",
  output: {
    path: pathResolve("out"),
    filename: "[name].[contenthash].js",
    clean: true
  },
  module: {
    rules: moduleRules
  },
  plugins: [
    plugins.html
  ],
  optimization: {
    runtimeChunk: 'single',
    splitChunks: {
      chunks: 'all',
    }
  }
};

结果:

assets by status 556 KiB [cached] 2 assets
assets by path . 2.46 KiB
    asset app.fbb4c2f9700c2af37967.js 2.06 KiB [emitted] [immutable] (name: app)
  asset index.html 403 bytes [emitted]
# 换行
Entrypoint app 559 KiB = runtime.674bb4c53b2070c042f3.js 6.66 KiB
vendors-node_modules_lodash_lodash_js.6bd6a6c81827d0950780.js 550 KiB 
app.fbb4c2f9700c2af37967.js 2.06 KiB

runtime modules 3.08 KiB 6 modules
cacheable modules 532 KiB
  ./src/index.js 595 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
webpack 5.64.4 compiled successfully in 324 ms
// 对于splitChunks配置
 const splitChunks =  {
      // chunks: 'all',
  cacheGroups: {
    shared: {
      test: /[\\/]node_modules[\\/]/,
      name: "[name].[contenthash:8].js",
      chunks: 'all',
    }
  }
}

// 这种可以更细粒度的拆分, 比如指定某一个模块进行拆分。 这里把node_modules中所有的包全部合为一个

拆分是必要的,一些第三方库不会频繁改动,我们加入了content:hash 只会在内容变化的时候才会去重新生成。

对于一个项目而言,不管是开发还是生产环境,对于第三方库都需要单独处理。 在dev可以指定缓存。在生产环境也可以采用CDN