webpack4中 splitChunks配置

虽然webpack5已经发布两年了,然而公司内部还有许多个项目仍然使用的是webpack4,最近一个小需求却导致打包结果发生了很大变化,于是重新研究了下splitChunks配置。

默认配置

splitChunks: {
  chunks: 'async',
  minSize: 30000,
  maxSize: 0,
  minChunks: 1,
  maxAsyncRequests: 5,
  maxInitialRequests: 3,
  automaticNameDelimiter: '~',
  automaticNameMaxLength: 30,
  name: true,
  cacheGroups: {
    vendors: {
      test: /[\\/]node_modules[\\/]/,
      priority: -10
    },
    default: {
      minChunks: 2,
      priority: -20,
      reuseExistingChunk: true
    }
  }
}

chunks: 'async'

代表仅对异步加载的chunk拆分

异步加载的chunk可以是通过import('./module')加载的路由组件,在没有做任何splitChunks的情况下每个路由组件最终都会成独立的chunk,也就是独立的js文件。和异步加载的chunk对应的是webpack entry 对应的文件生成的同步chunk。

name:true

true意味着根据chunk来生成名字。通过import()生成的chunk没有chunkName,最后会根据chunks和分组的key来生成文件名字,比如:7.2a8e96d850daca1383cf.chunk.js

设置为false在实际的使用中没有发现影响;

设置为字符串,如果匹配到多个module,这些module最后会合并到一个文件;

使用函数的话,就可以根据模块来定制最后chunk的名字,一般来说没必要,为了容易调试的情况下可以如此做;

maxAsyncRequests字段

maxAsyncRequests用来配置按需加载异步chunk数量的最大值;

比如有的页面异步chunks的数量大于了maxAsyncRequests,导致其引用的原本应该拆分出来的多个npm包被合并到同一个文件中;

1212

同样有些页面异步chunks没有大于maxAsyncRequests,引用的npm包分别拆分到独自文件中;
11

如果一个npm模块a被多个页面使用,有的页面的异步chunks大于maxAsyncRequests,有些小于maxAsyncRequests,这样就会出现这个a模块既被单独拆分成了一个js文件,又作为一个模块存在于另一个js文件中
11

所以合理设置maxAsyncRequests的大小对最终splitChunks的效果影响非常大,在实际工作中,甚至出现了因为maxAsyncRequests过小,一个2m大小的npm模块分散到使用它的16个chunk中,导致模块最后的bundle的总大小增加了一倍;

记录一个很有意思的例子:项目希望能够将npm包拆分成独立js,但是实际并没有,将项目中resolve.mainFields:['main']改为resolve.mainFields:['']就可以了,猜测是因为许多npm包的main字段指向的是commonjs模块或者umd模块,模块无法被treeShaking优化,导致最终页面的异步chunk变多,于是许多npm模块没有拆分成独立成js文件。改成module之后,一些第三方模块被treeShake掉, 满足了maxAsyncRequests,结果按照期望拆分了。

minSize:30000

用来限制拆分中模块的大小,大于这个值的模块才会参与到拆分中。这个30000值其实是有些小的,因为这是原始文件的大小,如果经过前端压缩和gzip压缩之后,通过网络的传输会减小80%以上,所以可以适当调大一些。

cacheGroups.

在这里可以设置拆分chunk的规则,这里的key并不是生成的chunk文件的名字,而是作为规则的一种描述;

  vendors: {
    test: /[\\/]node_modules[\\/]/,
    priority: -10
  },

比如上面的意思是将node_modules下的模块拆分成独立的chunk,vendors(翻译:厂商、第三方)只是描述这个规则是为了拆分第三方库,因为没有定义这些第三方库的chunkName,结果由webpack根据自己来决定。

cacheGroups.{key}.enforce

刚开始使用splitChunk的时候,不知道是什么原因(后来才知道因为maxAsyncRequests的缘故),无法把第三方模块打包出来;这个时候使用enforce:true之后就成功打包出来了,了解到这样配置可以无视minSize, minChunks, maxAsyncRequests and maxInitialRequests的配置,这才从maxAsyncRequests这里找到了原因。

所以在确定需要拆分但又受到那几个属性的限制的时候,使用exforce可以一步到位。

posted @ 2022-05-05 18:25  空山与新雨  阅读(1264)  评论(0编辑  收藏  举报