Javascript 网页包加载程序:缓存时是否考虑了选项?
我正在写一个可以缓存的网页包加载程序。报告说: 当输入和依赖项未更改时,可缓存加载程序必须具有确定性结果 现在我想知道:从这个意义上讲,加载程序的选项算是“输入”吗 假设我有一个Webpack构建,它在一个模块上使用带有选项Javascript 网页包加载程序:缓存时是否考虑了选项?,javascript,webpack,Javascript,Webpack,我正在写一个可以缓存的网页包加载程序。报告说: 当输入和依赖项未更改时,可缓存加载程序必须具有确定性结果 现在我想知道:从这个意义上讲,加载程序的选项算是“输入”吗 假设我有一个Webpack构建,它在一个模块上使用带有选项{foo:1}的加载程序。在下一次编译中,它在同一模块上使用相同的加载程序,但带有选项{foo:2}。第一次编译的输出是否会被重新使用,或者Webpack(正确地)是否会意识到加载程序的选项已更改,从而重新加载模块 假设Webpack确实比较了选项对象,它们是如何比较的?参考
{foo:1}
的加载程序。在下一次编译中,它在同一模块上使用相同的加载程序,但带有选项{foo:2}
。第一次编译的输出是否会被重新使用,或者Webpack(正确地)是否会意识到加载程序的选项已更改,从而重新加载模块
假设Webpack确实比较了
选项
对象,它们是如何比较的?参考?使用深度比较?比较逻辑将规定哪些类型的数据可以安全地用作加载程序选项。如果您更改加载程序的输入,则实际上是在创建一个新的实例,因此它不应使用具有不同选项的加载程序的缓存
如果你看这里,它看起来只是设置了一个标志,表明是否请求可缓存,缓存结果取决于你。不管发生什么,它都会呼叫你的加载器 短版: Webpack通过其
请求字符串识别模块。此字符串包含文件路径以及所有相关加载程序的路径和选项。这实际上意味着更改一个加载程序上的选项将导致不同的请求字符串,因此不会重复使用以前的加载结果
长版本:
请求字符串以“!”分隔,并由创建
考虑以下请求字符串:
"/Users/wolf/dev/webpack-test/test-loader.js!/Users/wolf/dev/webpack-test/patch-loader.js??ref--0-0!/Users/wolf/dev/webpack-test/src/foo.js"
这意味着(从右到左)首先使用加载程序/Users/wolf/dev/webpack test/src/foo.js
加载文件/Users/wolf/dev/webpack test/patch loader.js
,使用选项ref--0-0
,然后使用加载程序/Users/wolf/dev/webpack test/test loader.js
,不使用任何选项
现在,相关的问题是Webpack在创建请求字符串时如何序列化加载程序的选项。答案如下:
将loaderData
作为此表单的对象:
{
loader: string, // Path to loader
options: string | object | null | undefined,
ident: string | null | undefined
}
- 如果
loaderData.options
是字符串,则按原样使用
- 否则,如果
loaderData.ident
为真值,则使用此值
- 否则,
loaderData.options
将使用JSON.stringify
进行字符串化
似乎当加载程序启动时,Webpack知道它们的选项不会改变。因此RuleSet.normalizeRule()
为它们分配固定的ident
属性。这就是上面示例中使用ref--0-0
时发生的情况
这里的一个关键洞察是加载程序选项应该是相当简单的对象,以便对它们调用JSON.stringify
,不会丢失任何信息。否则,Webpack可能会无意中重复使用使用不同加载程序选项的缓存结果。或者,您可以显式地将loaderData.ident
设置为唯一标识选项的字符串(例如哈希代码)。这也是我的希望,但我找不到任何文档或相关的源代码。你能解释一下具体的行为吗(请看我的问题)?如果你想看看加载器的逻辑,它在这里:另外,一个很好的系列读物是:。这里有4个部分…老实说,最简单的方法可能就是进行实验,看看配置更改是否会导致缓存。只需几个日志语句就可以很容易地分辨出来。如果你看这里,它看起来就像是在设置一个标志,表明是否请求可缓存,缓存结果取决于你。不管发生什么,它都会呼叫你的加载器。