刚接触 webpack 时,应用 webpack 打包后只会生成一个被称为 bundle 的文件,在缓缓相熟 webpack 后,如果同时对于前端优化有肯定的理解,就会尝试将臃肿的 bundle 拆分成多个小文件并按需加载。
本文心愿通过对 webpack 的局部配置进行阐明,让读者对相干的操作有肯定理解和把握。以下操作均是在 webpack@4 环境下的阐明。
webpack 中通过配置的 optimization.splitChunks
来实现这样的成果,该配置也是 SplitChunksPlugins
插件的配置。
webpack 为 optimization.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
通过配置该项,开发者能够抉择须要进行优化的 chunk,被选中的 chunk,其中的 modules 将被剖析,并依照肯定的策略生成新的 chunk。
容许 all
、async
、initial
、(chunkname) => boolean
四种值,具体成果如下:
- initial: 所有的立刻加载的 chunk(例如 bundle 文件)将被查看
- async: 所有提早加载的 chunk 将被查看
- all: 等价于
initial
+async
成果,所有的 chunk 都将被查看 - (chunkname) => boolean: 函数模式能够提供更细粒度的管制
默认状况为 async
,所以咱们的 bundle 不会被优化,这里能够尝试批改为initial
之后再进行一次编译。
{chunks: 'initial',}
除了生成 bundle 之外,可能还会有名为 vendors~xxx.js
的文件。(如果没有生成的话,能够尝试在代码中引入 node_modules
中的包,再从新编译后查看后果。)
两次编译后果的变动,即 chunks
从async
变为 initial
后,bundle 文件
因作为一个立刻加载的 chunk 而被优化了。
minSize、maxSize
见名知意,minSize
和 maxSize
限定了新生成的 chunk 的文件的最小 / 最大尺寸。只有当筹备生成的 chunk 的最大和最小文件尺寸,只有在这个尺寸内的 chunk 文件才会被生成,否则代码会放弃原样。
minSize=30000
示意 chunk 最小应该有 30000bytes。maxSize=0
示意不限度 chunk 的最大尺寸。如果设置为一个其余的正当值,例如 150000
,生成的 chunk 超过了maxSize
的状况下,该 chunk 将被进一步拆分成更小的 chunk。
cacheGroups
cacheGroups 是 splitChunks 配置的一个要害配置,其决定了 module
应该如何合并成一个新的 chunk。
{
vendors: {test: /[\\/]node_modules[\\/]/,
priority: -10
},
}
在 cacheGroups
配置下的每一个对象,都能够认为是一个 cacheGroup
,例如下面的代码中是 key 为vendors
的对象。
cacheGroup.test
test
用于对所有的 module
进行筛选,筛选过的 module 将被放入这个 cacheGroup
所对应的 chunk 文件中。上例中通过 [\\/]node_modules[\\/]
对于 module
的门路进行测试,最终所有的 node_modules 门路
下的模块都将放在 vendors
这个 chunk 下,这也是下面生成 vendors~xxx.js
的起因。
cacheGroup.priority
定义 cacheGroup
的优先级。因为对于每个 module
来说,有可能同时匹配了多个 cacheGroup
的test
规定,此时就须要依据优先级来决定须要放到哪个 cacheGroup
中。
name
name
决定了生成的 chunk 文件的名字。默认为 true
状况下,生成的名字格局为为 cacheGroup 名字~chunk1 名字~chunk2 名字.js
,其中chunk1 名字
和chunk2 名字
是因为这个 cacheGroup
中蕴含了这两个 chunk 相干的代码,如果有更多的 chunk 的话以此类推。
automaticNameDelimiter
可能有仔细的读者会留神到上一大节中用于连贯 chunk 名称的 ~
,其实是automaticNameDelimiter
这个配置项设置的。开发者能够通过该配置项来设置本人想用的连接符。
automaticNameMaxLength
默认状况下,会限度 name
大节中的 chunk1 名字~chunk2 名字
局部长度,超出了限度状况下将进行截断。
例如:设为 3 状况下,vendors-chunk1 名字~chunk2 名字.js
将变成 vendors~chu~21737d60.js
,仅仅保留了长度 = 3 的chu
局部。在呈现截断状况下,会在前面补充一段额定的字符,可能是一种防止文件名反复的机制。
minChunks
当和一个 cacheGroup
相干的 chunk 数量超过 minChunks
时,新的 chunk 文件才能够生成。
例如,在默认配置中:
{
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
可能有仔细的读者又会问了:当初说的不是 splitChunks.minChunks
吗,和 cacheGroup.minChunks
有什么关系呢?
其实在 splitChunks 下的所有配置,在 cacheGroup 中都会继承或者笼罩。所以对于 key 为 vendors
的 cacheGroup 来说,其 minChunks 为 1,根本就是不限度,所以 node_modules 文件夹下的内容都会被放入到 vendors
这个 chunk。
所以咱们晓得,key 为 default
的 cacheGroup,其中会放入至多两个 chunk 所援用的 module。如果须要尝试的,能够通过在两个 entry 所生成的 bundle 文件中,援用雷同的 module,之后再打包,应该就会发现该 module 被放到了名为 default~chunk1 名字~chunk2 名字
这样的文件中。
(至此心愿大家曾经对于 chunk 的生成逻辑有了大抵的理解。)
一些对于 webpack 的其余文章:
- webpack 的加载