1. 分包:将一个整体的代码,分布到不同的打包文件中;

  2. 为什么分包

    • 减少公共代码,降低总体积,特别是一些大型的第三方库;
    • 充分利用浏览器缓存;
  3. 什么时候分包

    • 多个 chunk 引入了相同的公共模块
    • 公共模块 体积较大改动较少

基本原理

  1. 先单独的打包公共模块,公共模块会被打包成为动态链接库(dll Dynamic Link Library),并生成资源清单

  2. 根据入口模块进行正常打包

    • 打包时,如果发现模块中使用了资源清单中描述的模块,则不会形成下面的代码结构
    // 源码,入口文件 index.js
    import $ from "jquery"
    import _ from "lodash"
    _.isArray($(".red"));
    
    • 由于资源清单中包含 jquerylodash 两个模块,因此打包结果的大致格式是:
    (function(modules){
      //...
    })({
      // index.js 文件的打包结果并没有变化
      "./src/index.js":
      function(module, exports, __webpack_require__){
        var $ = __webpack_require__("./node_modules/jquery/index.js")
        var _ = __webpack_require__("./node_modules/lodash/index.js")
        _.isArray($(".red"));
      },
      // 由于资源清单中存在,jquery 的代码并不会出现在这里,否则 jquery 源码会被打包进来
      "./node_modules/jquery/index.js":
      function(module, exports, __webpack_require__){
        module.exports = jquery; // 全局变量 jquery
      },
      // 由于资源清单中存在,lodash 的代码并不会出现在这里,否则 lodash 源码会被打包进来
      "./node_modules/lodash/index.js":
      function(module, exports, __webpack_require__){
        module.exports = lodash; // 全局变量 lodash
      }
    })
    

打包公共模块

打包公共模块是一个 独立的 打包过程

  1. 单独打包公共模块,暴露变量名

    // webpack.dll.config.js
    module.exports = {
      mode: "production",
      entry: {
        jquery: ["jquery"],
        lodash: ["lodash"]
      },
      output: {
        filename: "dll/[name].js",
        library: "[name]", // 暴露公共模块
      }
    };
    
  2. 利用 DllPlugin 生成资源清单

    // webpack.dll.config.js
    module.exports = {
      plugins: [
        new webpack.DllPlugin({
          path: path.resolve(__dirname, "dll", "[name].manifest.json"), // 资源清单的保存位置
          name: "[name]" // 资源清单中,暴露的变量名
        })
      ]
    };
    

使用公共模块

  1. 在页面中手动引入公共模块

    <script src="./dll/jquery.js"></script>
    <script src="./dll/lodash.js"></script>
    
  2. 重新设置 clean-webpack-plugin,如果使用了插件 clean-webpack-plugin,为了避免它把公共模块清除,需要做出以下配置

    new CleanWebpackPlugin({
      // 要清除的文件或目录,排除掉 dll 目录本身和它里面的文件
      cleanOnceBeforeBuildPatterns: ["**/*", '!dll', '!dll/*']
    })
    

    目录和文件的匹配规则使用的是 globbing patterns

  3. 使用 DllReferencePlugin 控制打包结果,这样 jquerylodash 才不会被打包到 index.js

    module.exports = {
      plugins:[
        new webpack.DllReferencePlugin({
          manifest: require("./dll/jquery.manifest.json")
        }),
        new webpack.DllReferencePlugin({
          manifest: require("./dll/lodash.manifest.json")
        })
      ]
    }
    

总结

手动打包的过程

  1. 开启 output.library 暴露公共模块

  2. DllPlugin 创建资源清单

  3. DllReferencePlugin 使用资源清单

手动打包的注意事项

  1. 资源清单不参与运行,可以不放到打包目录中

  2. 记得手动引入公共 JS ,以及避免被删除

  3. 不要对小型的公共 JS 库使用

优点

  1. 极大提升自身模块的打包速度

  2. 极大的缩小了自身文件体积

  3. 有利于浏览器缓存第三方库的公共代码

缺点

  1. 使用非常繁琐,麻烦

  2. 如果第三方库中包含了复杂的依赖关系,则效果不太理想

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于产品、设计、开发的问题和看法,还有技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程

了解更多

目录

  1. 1. 基本原理
  2. 2. 打包公共模块
  3. 3. 使用公共模块
  4. 4. 总结
    1. 4.1. 手动打包的过程
    2. 4.2. 手动打包的注意事项
    3. 4.3. 优点
    4. 4.4. 缺点