浅谈Webpack 持久化缓存实践
前言
Webpack 是现代前端工程化不可或缺的重要工具。但是随着项目的复杂度增加,Webpack 的构建时间也会越来越长。为了优化构建时间,我们通常会启用持久化缓存(Persistent Cache)来避免重新构建。
本文将详细阐述 Webpack 持久化缓存实践中的一些细节和经验。
Webpack 持久化缓存如何提升构建效率
持久化缓存可以将与 Webpack 构建相关的数据全部或部分地持久化到磁盘中。这样,下一次构建时,只有发生变化的文件才会被重新处理,而那些文件仍会从缓存中读取。这大大减少了重新处理的文件数量,从而提高了构建效率。
在 Webpack 4 中,持久化缓存被默认开启。Webpack 5 中利用了 Content Hash 的实现大幅改进了持久化缓存。同时,Webpack 5 还引入了多进程编译、多种构建方式等性能优化特性,进一步提升了构建速度。
如何启用 Webpack 持久化缓存
首先,在 Webpack 配置文件中需要启用持久化缓存。在 module.exports 对象中增加 cache 配置项即可:
module.exports = {
// ...
cache: {
type: 'filesystem',
},
// ...
};
其中 type 属性指定使用哪种持久化缓存类型,文件系统缓存为一种常见类型。
除此之外,我们还需要保证 Webpack 的缓存 key 值不变。Webpack 已经将很多默认值做了缓存处理,比如 mode、entry 等字段,但是像 package.json 等配置文件并不会被默认缓存。因此,我们还需要手动设置 cache key:
module.exports = {
// ...
cache: {
// ...
cacheKey: (defaultCacheKey, { context, env }) => {
return env + ':' + defaultCacheKey;
},
},
// ...
};
上面的代码中,我们将缓存 key 中增加了环境变量作为前缀,这样就可以保证不同环境的缓存不会相互影响。
如何应对缓存失效问题
即使启用持久化缓存,有些情况下缓存仍可能失效或者无法使用。为了避免出现问题,我们需要做好以下几方面的工作:
稳定的 Hash 算法
持久化缓存的核心就是使用文件路径和文件内容的 hash 值计算每个文件的缓存 key。因此,在启用持久化缓存之前,我们需要确保文件路径和文件内容能够产生稳定的 hash 值。注意以下几点:
- 不要使用相对路径,使用绝对路径;
- 不要使用动态文件名;
- 尽可能避免使用动态制造文件内容的 loader。
cache-loader 的使用
cache-loader 可以使用缓存文件,避免一些 loader 不必要的计算。
使用示例:
{
test: /\.jsx?$/,
use: ['cache-loader', 'babel-loader'],
include: path.join(__dirname, 'src')
}
注意:cache-loader 记得在 babel-loader 等其他 loader 前面加上。
thread-loader 的使用
thread-loader 可以将一些耗时的 loader/插件交给 worker 模块处理,避免阻塞主线程,从而加速编译速度。
使用示例:
{
test: /\.jsx?$/,
use: ['thread-loader', 'babel-loader'],
include: path.join(__dirname, 'src')
}
注意:thread-loader 记得在 babel-loader 等其他 loader 前面加上。
示例
以下是一个简单的 Webpack 配置文件的示例:
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
use: ['cache-loader', 'babel-loader'],
include: path.resolve(__dirname, 'src'),
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
cache: {
type: 'filesystem',
cacheKey: (defaultCacheKey, { env }) => {
return 'v1:' + env + ':' + defaultCacheKey;
},
},
};
总结
Webpack 持久化缓存是提升构建效率的好工具,而正确使用缓存更是提升构建效率的关键。我们需要使用稳定的 hash 算法,使用 cache-loader 和 thread-loader 来加速编译速度,并时刻保证 Webpack 的缓存 key 值一致。