优化webpack时挖到的loader.pitch

712 阅读2分钟

在浏览网上各种webpack优化方案的时候,看到这样一个API

cache-loader

该loader的作用在于

如果某个文件内容不变,经过相同的 loader 解析后,解析的结果保持不变
使用 cache-loader 可以将 loader 的解析结果保存下来,让后续的解析可以直接使用保存后的结果

于是我在代码中使用了一遍

module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [{
                    loader: "cache-loader",
                    options: {
                        cacheDirectory: "./cache" // 缓存文件保存的地方(默认系统提供临时文件)
                    }
                }, ...loaders]
            }
        ]
    }
}

1617182355699.jpg
因为cache-loader需要在其他loader解析作用下,最后才将解析结果保存,因此会放到第一位
原因:一般情况下,loader的执行顺序为从右往左,从下往上。

这时候,问题出现了

既然 cache-loader 需要放到最后一位来进行缓存编译结果,但是到了二次编译的时候,loader的编译顺序也是从后往前,最后才到 cache-loader 起作用,按理说达到优化的效果就消失了,因为源代码又完完整整重新编译了一遍。
那它是如何跳过前面的 loaders 来直接输出缓存下来的编译结果的呢

原来,在 loader 的执行前,还有一个 .pitch 方法需要先执行

loader执行顺序

use: ["loader1", "loader2", "loader3"]
1.jpg

在loader真正处理代码前,会将文件地址依次传给 正方向 的loader.pitch方法,该方法可以通过是否return来决定能否进行下一步传递

function loader(source) {
    return `new source`
}

loader.pitch = function(filePath) {
    // 可返回可不返回
    // 如果返回,则直接返回源代码,并控制下一步代码执行位置
}

因此可以整理出 cache-loader 的执行顺序:

第一次编译:

  1. 传入文件路径到loader.pitch,没有返回,正常执行后续操作
  2. 代码经过多层loader处理,并通过最后的 cache-loader(loader1)生成缓存文件
    第二次编译
    传入文件路径到loader.pitch,发现有对应缓存文件,则跳过后续执行,直接返回缓存文件代码

总结:
许多 webpack 的 loader 都会经过.pitch方法来处理,目的在于控制输出代码内容,和控制执行的流程;比如style-loader中同样使用了.pitch方法来处理动态执行的函数,算是一个扩展点吧~

本文通过一个 cache-loader 来引出 loader 执行顺序中比较隐藏的 .pitch 方法,难度不高,好理解。作为我的处子文章来提升一下自己,有不恰当的地方欢迎留言和评论~~~~~~~