美文网首页
Webpack 的SplitChunks

Webpack 的SplitChunks

作者: 冷暖自知_zjz | 来源:发表于2023-03-22 17:25 被阅读0次

    什么是SplitChunks

    Splitchunks是webpack的一个功能,用于优化打包后的文件大小,特别是对于多页面应用时可以将公共的代码打包成一个独立的chunk,从而避免重复加载,提升加载速度。

    默认值

    module.exports = {
      //...
      optimization: {
        splitChunks: {
          chunks: 'async',
          minSize: 20000,
          minRemainingSize: 0,
          minChunks: 1,
          maxAsyncRequests: 30,
          maxInitialRequests: 30,
          enforceSizeThreshold: 50000,
          cacheGroups: {
            defaultVendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
              reuseExistingChunk: true,
            },
            default: {
              minChunks: 2,
              priority: -20,
              reuseExistingChunk: true,
            },
          },
        },
      },
    };
    

    用法

    // main.js

    import b from './testB';
    console.log('main',b);
    

    // testA.js

    import b from './testB';
    console.log('main',b);
    

    // testB.js

    import b from './testB';
    console.log('main',b);
    

    // testC.js

    console.log('testC');
    export default 'testC';
    

    // testF.js

    import b from './testB';
    import c from './testC';
    import { isEmpty } from 'lodash';
    if(isEmpty("")) {
        console.log('iftestF', b, c);
    }else{
        console.log('elsetestF', b, c);
    }
    // console.log('testF', b, c);
    export default 'testF';
    

    依赖关系如下图

    splitchunk.jpg splitchunk.jpg

    使用默认值打包后的样子

    default.jpg default.jpg

    可以看出 每一个html对应一个 js 从上面的依赖关系可以看出 3个页面之间是有公用的代码的。如果能把公用的代码抽离出来会更好,
    现在是每个一页面对应的js包含所以来的所有代码,也就是说 main.js,testA.js,testF.js都包含testB这个模块的代码,如下图

    contain.jpg contain.jpg

    问题1 怎么把公共代码提取出来作为一个单独的js呢? 如下图

    抽取公共代码.jpg 抽取公共代码.jpg

    只需要把chunks:async => chunks:all (all - 提取所有模块中的公共代码。 async - 只提取异步加载的模块公共代码。 initial - 只提取同步加载的模块公共代码) minSize:20000=>minSize:0 (只有大于该数值的模块才会被提取) ,可以看到在defaultVendors 下新增加了一个name 有该选项后 打包出的chunk 用改名字

    问题2 在多页面中,node_modules 里面的所有模块都打包到一个chunk下了,不管在具体的那一个页面都会加载全部的的公共依赖chunk-vendors,从上面的依赖关系图可以看出 lodash 只有testF.js模块在使用 ,应该只在 testF.html 加载,不应该放到
    chunk-vendors里面,那么我们如何把lodash分离出来呢。如下图

    lodash.png lodash.png

    图上的配置表示priority(priority:一个模块可以属于多个缓存组。优化将优先考虑具有更高 priority(优先级)的缓存组。默认组的优先级为负,以允许自定义组获得更高的优先级(自定义组的默认值为 0) 因为上面的chunk-lodash 的priority值为-5 大于另外两个的 -10和-20 所以优先执行改配置,所以 会从node_modules 里面分离出lodash.

    特点

    • 1.通过optimization.splitChunks.minSize参数可以设置模块的最小大小,只有大于该数值的模块才会被提取。

    • 2.optimization.splitChunks.chunks参数控制对哪些模块进行处理,有三个可选方案: all - 提取所有模块中的公共代码。 async - 只提取异步加载的模块公共代码。 initial - 只提取同步加载的模块公共代码。

    • 3.通过maxInitialRequests、maxAsyncRequests参数限制异步加载模块分别最多分离出多少个chunk。

    • 4.同构应用需要设置optimization.splitChunks.name,此选项尤其重要,它可以避免由于缺失 chunk 名导致相同 chunk 被重复引入。

    • 5.splitChunks.cacheGroups 缓存组可以继承和/或覆盖来自 splitChunks.* 的任何选项。但是 test、priority 和 reuseExistingChunk 只能在缓存组级别上进行配置。将它们设置为 false以禁用任何默认缓存组。

      • a. priority:一个模块可以属于多个缓存组。优化将优先考虑具有更高 priority(优先级)的缓存组。默认组的优先级为负,以允许自定义组获得更高的优先级(自定义组的默认值为 0)
      • b. test:控制此缓存组选择的模块。省略它会选择所有模块。它可以匹配绝对模块资源路径或 chunk 名称。匹配 chunk 名称时,将选择 chunk 中的所有模块
      • c. reuseExistingChunk: 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块。这可能会影响 chunk 的结果文件名。

    参考 https://webpack.docschina.org/plugins/split-chunks-plugin/

    相关文章

      网友评论

          本文标题:Webpack 的SplitChunks

          本文链接:https://www.haomeiwen.com/subject/nphbrdtx.html