在浏览网上各种webpack优化方案的时候,看到这样一个API
cache-loader
该loader的作用在于
如果某个文件内容不变,经过相同的 loader 解析后,解析的结果保持不变
使用 cache-loader 可以将 loader 的解析结果保存下来,让后续的解析可以直接使用保存后的结果
于是我在代码中使用了一遍
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [{
loader: "cache-loader",
options: {
cacheDirectory: "./cache" // 缓存文件保存的地方(默认系统提供临时文件)
}
}, ...loaders]
}
]
}
}
因为cache-loader需要在其他loader解析作用下,最后才将解析结果保存,因此会放到第一位
原因:一般情况下,loader的执行顺序为从右往左,从下往上。
这时候,问题出现了
既然 cache-loader 需要放到最后一位来进行缓存编译结果,但是到了二次编译的时候,loader的编译顺序也是从后往前,最后才到 cache-loader 起作用,按理说达到优化的效果就消失了,因为源代码又完完整整重新编译了一遍。
那它是如何跳过前面的 loaders 来直接输出缓存下来的编译结果的呢
原来,在 loader 的执行前,还有一个 .pitch 方法需要先执行
loader执行顺序
use: ["loader1", "loader2", "loader3"]
在loader真正处理代码前,会将文件地址依次传给 正方向 的loader.pitch方法,该方法可以通过是否return来决定能否进行下一步传递
function loader(source) {
return `new source`
}
loader.pitch = function(filePath) {
// 可返回可不返回
// 如果返回,则直接返回源代码,并控制下一步代码执行位置
}
因此可以整理出 cache-loader 的执行顺序:
第一次编译:
- 传入文件路径到loader.pitch,没有返回,正常执行后续操作
- 代码经过多层loader处理,并通过最后的 cache-loader(loader1)生成缓存文件
第二次编译
传入文件路径到loader.pitch,发现有对应缓存文件,则跳过后续执行,直接返回缓存文件代码
总结:
许多 webpack 的 loader 都会经过.pitch方法来处理,目的在于控制输出代码内容,和控制执行的流程;比如style-loader中同样使用了.pitch方法来处理动态执行的函数,算是一个扩展点吧~
本文通过一个 cache-loader 来引出 loader 执行顺序中比较隐藏的 .pitch 方法,难度不高,好理解。作为我的处子文章来提升一下自己,有不恰当的地方欢迎留言和评论~~~~~~~