样式加载器如何与CSS加载器一起使用?

时间:2019-04-22 06:03:32

标签: webpack

我知道样式加载器通过注入标签将CSS添加到dom中。并且css-loader在遇到require('./style.css');时将css作为字符串获取。

但是,样式加载器如何与css-loader一起玩?

我正在阅读style-loader源代码和css-loader源代码。但是我不明白他们如何一起玩。

css-loader从style.css获取的css字符串如何传递到style-loader?

1 个答案:

答案 0 :(得分:1)

好问题。为了正确回答,我做了很多功课。这就是我发现的东西。

普通装载机

对webpack加载器的普遍理解是,它们是链接在一起以形成管道的单元。每个加载器处理输入的源代码,对其进行转换,然后将结果向下传递到管道中的下一个单元。重复此过程,直到最后一个单元完成工作为止。

但是上面只是整个图片的一部分,只有普通装载机适用。 style-loader不是普通的加载程序,因为它也具有 pitch 方法。


加载程序的pitch方法

请注意,没有 pitch loader 这样的东西,因为每个加载器都可以有“正常侧”和“ pitch侧”。

这不是很有帮助的webpack doc on pitching loader。最有用的信息是“音高阶段”和“正常阶段”的概念及其执行顺序。

|- a-loader `pitch`
  |- b-loader `pitch`
    |- c-loader `pitch`
      |- requested module is picked up as a dependency
    |- c-loader normal execution
  |- b-loader normal execution
|- a-loader normal execution

您已经看到style-loader的{​​{3}},导出内容如下:

module.exports = {}
module.exports.pitch = function loader(request) {
  /* ... */
  return [/* some string */].join('\n')
}

文档中与上述源代码唯一相关的部分:

  

如果装载机以音高法提供结果,则过程将转过来并跳过其余的装载机。

目前还不清楚这种音高到底是如何工作的。

深入挖掘

我终于遇到了source code(用汉语写的)有关细节的讨论。具体来说,它可以像style-loader这样分析确切的情况,其中pitch方法返回一些信息。

根据博客,pitch方法主要用于在加载程序过程的早期访问和修改元数据。从pitch方法返回的情况确实很少见,并且文献记载也很少。但是当它返回除undefined之外的其他值时,会发生以下情况:

# Normal execution order is disrupted.
|- style-loader `pitch` # <-- because this guy returns string early
# below steps are all canceled out
  |- css-loader `pitch`
    |- requested module is picked up as a dependency
  |- css-loader normal execution
|- style-loader normal execution

然后,styleLoader.pitch的返回值仅成为新的内存文件条目。然后,该文件将像普通文件一样进行加载,并使用全新的加载过程进行转换。

如果您检查,则styleLoader.pitch上此即时生成的文件的内容类似于

var content = require("!!./node_modules/css-loader/dist/cjs.js??ref--8-3!./index.css");

您会注意到,使用内联查询已完全配置了每个require请求。因此,这些请求将不会通过test中的任何webpackConfig.module.rules

结论

基本上,这是style-loader的作用:

  1. 它通过公开pitch方法来尽早捕获请求。
  2. 然后,它了解此请求的含义,读取所有后续加载程序的配置,将所有配置转换为内联查询的require(...)
  3. 然后它会即时发布一个新文件,这样做,原始请求被有效地取消了然后被替换为对该内存文件的新请求。

我不知道,所有真相都保存在loader-runner模块的blog post中。如果有人对参考文献的来源或理解程度更高,请发表评论,发布答案或编辑我的参考文献。