@Dale-Lin
2022-09-09T12:01:29.000000Z
字数 2246
阅读 588
webpack5
Webpack5 提供了持久化缓存的用法(Webpack4 借助第三方 loader/Plugin 实现),能将首次构建的过程和结果数据保存到本地 fs,在下次执行构建时跳过解析、链接、编译等一系列非常消耗性能的操作,直接复用上次的 Module/ModuleGraph/Chunk 数据,迅速构建出 bundle。
Webpack5 会将首次构建出的 Module/ModuleGraph/Chunk 等对象序列化后保存到硬盘中,二次编译可以复用缓存数据。
从构建步骤来看,webpack 构建过程可以分成三个阶段:
entry
开始: 过程中存在许多 cpu 密集型操作,例如调用 Loader 链加载文件时,遇到 babel-loader、eslint-loader、ts-loader 等工具时可能需要重复生成 AST;分析模块依赖时需要遍历 AST 执行大量运算;Seal 阶段也存在大量 AST 遍历、代码转换、优化等。
Webpack5 的持久化缓存功能将 Module、Chunk、ModuleGraph 三类产物的状态序列化后保存到 fs 中,在下次编译时对比每一个文件的 contentHash 和 timestamp(timestamp 可以监听文件移动),未发生变化的文件跳过编译而直接使用缓存副本;发生变更的模块重新执行编译流程。
生成阶段完成后产生缓存;可以使用缓存的文件跳过构建阶段,即 初始化 -> 生成阶段 -> 写出;
webpack4 及之前版本只能通过第三方组件实现,包括:
babel-loader
、eslint-loader
自带的缓存能力cache-loader
将 Loader 处理结果保存到硬盘,下次运行时,若文件内容没有变化则直接返回缓存结果:
yarn add -D cache
必须将
cache-loader
放在loader
数组首位
module.exports = {
// ...
modules: {
rules: [{
test: /\.js$/,
use: [
'cache-loader',
'babel-loader',
'eslint-loader'
]
}]
}
}
cache-loader
只缓存了 Loader 执行结果,缓存范围和精度不如 Webpack5 内置缓存
hard-source-webpack-plugin 也是实现一种缓存功能的第三方组件,不仅缓存了 Loader 运行结果,还保存了 Webpack 构建过程中许多中间数据,包括:模块、模块关系、模块 Resolve 结果、chunk、assets 等,效果几乎与 webpack5 自带的 Cache 对齐:
yarn add -D hard-source-webpack-plugin
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
module.exports = {
// ...
plugins: [
new HardSourceWebpackPlugin(),
]
}
首次运行时,hard-source-webpack-plugin
会在 node_modules/.cache
写入一系列的日志文件,在下次运行时复用记录的数据,跳过一系列构建步骤。
hard-source-webpack-plugin
的底层逻辑和 webpack5 的持久化缓存相似,但优化效果稍微差一些;
除了上述方案,还可以使用 webpack 组件自带的缓存能力来提升特定领域的编译性能,这一类组件有:
开启 cacheDirectory = true
即可:
module.exports = {
// ...
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}]
}
}
默认情况下,缓存内容会被保存到
node_modules/.cache/babel-loader
目录,也可通过cacheDirectory = ${dir}
来设置缓存路径。
设置 options.cache
为 true
,会把 lint 的结果进行缓存到 .eslintcache
目录下;可以使用 options.cacheLocation
设置缓存路径。
设置 cache: true
会把 lint 结果缓存到 process.cwd()
的 ./.stylelintcache
目录下。