【问题标题】:Webpack loaders: Are options considered when caching?Webpack 加载器:缓存时是否考虑选项?
【发布时间】:2018-02-26 16:14:11
【问题描述】:

我正在编写一个应该可以缓存的 Webpack 加载器。 documentation for this.cacheable 说:

当输入和依赖没有改变时,一个可缓存的加载器必须有一个确定的结果。

现在我想知道:从这个意义上说,加载程序的选项是否算作“输入”?

假设我有一个 Webpack 构建,它在模块上使用带有选项 { foo: 1 } 的加载器。在下一次编译中,它在同一个模块上使用相同的加载器,但带有选项{ foo: 2 }。第一次编译的输出会被重用,还是 Webpack(正确地)意识到加载器的选项已经改变,从而重新加载模块?

假设 Webpack 比较 options 对象,它们是如何比较的?引用?使用深度比较?比较逻辑将决定我可以安全地将哪些类型的数据用作加载器选项。

【问题讨论】:

    标签: javascript webpack


    【解决方案1】:

    短版:

    Webpack 通过其request 字符串识别模块。该字符串包含文件路径以及所有相关加载程序的路径和选项。这实际上意味着更改一个加载器上的选项将导致不同的请求字符串,因此之前的加载结果不会被重复使用。

    加长版:

    请求字符串以“!”分隔并由this code 创建。

    考虑这个请求字符串:

    "/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 将首先使用带有选项 ref--0-0 的加载器 /Users/wolf/dev/webpack-test/patch-loader.js 加载,然后是不带任何选项的加载器 /Users/wolf/dev/webpack-test/test-loader.js

    现在,相关的问题是 Webpack 在创建请求字符串时如何序列化加载器的选项。答案可以在in this code找到:

    loaderData成为这种形式的对象:

    {
      loader: string, // Path to loader
      options: string | object | null | undefined,
      ident: string | null | undefined
    }
    
    • 如果loaderData.options 是字符串,则按原样使用。
    • 否则,如果loaderData.ident 为真,则使用此值。
    • 否则,loaderData.options 将使用 JSON.stringify 进行字符串化。

    似乎当加载器是specified statically 时,Webpack 知道它们的选项不会改变。所以RuleSet.normalizeRule() 为它们分配了固定的ident 属性。这就是上面示例中发生的ref--0-0

    这里的一个关键见解是加载器选项应该是相当简单的对象,以便在它们上调用JSON.stringify 不会丢失任何信息。否则,Webpack 可能会无意中重用使用不同加载器选项的缓存结果。或者,您可以将loaderData.ident 显式设置为唯一标识选项的字符串(例如哈希码)。

    【讨论】:

      【解决方案2】:

      如果您更改加载器的输入,那么您实际上是在创建它的一个新实例,因此它不应该使用来自加载器的缓存和不同的选项。

      如果您看这里,它似乎只是设置了一个标志,说明是否请求可缓存,并且由您决定是否缓存结果。无论如何,它总是会调用你的加载器。 https://github.com/webpack/loader-runner/blob/master/lib/LoaderRunner.js#L270

      【讨论】:

      • 这也是我的希望,但我找不到任何文档或找到相关的源代码。您能否阐明确切的行为(请参阅我的问题)?
      • 如果你想看加载器逻辑,在这里:github.com/webpack/loader-runner/blob/master/lib/…
      • 另外,了解 webpack 的一个很好的系列是:medium.com/webpack/…。有 4 个部分...
      • 老实说,最简单的做法可能只是试验一下,看看您的配置更改是否会导致缓存。只需几条日志语句就应该很容易分辨。
      • 如果你看这里,看起来它只是设置了一个标志,说明是否请求可缓存,缓存结果取决于你。无论如何,它总是会调用你的加载器。 github.com/webpack/loader-runner/blob/master/lib/…
      猜你喜欢
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      • 1970-01-01
      • 2017-01-04
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多