📄Webpack loader执行流程
type
status
date
slug
summary
tags
category
icon
password
Status
webpack 的 loader分为四种:pre、normal、inline、post。
执行顺序分为两个步骤:
- pitch 阶段,loaders的 pitching 过程从后到前(
post → inline → normal → pre
)
- normal 阶段,loaders的 normal 过程从前到后(
pre → normal → inline → post
)
注意这个是关于 loader 级别的,即rule中指定enforce,如果全是normal即没有设置enforce,则遵循从上到下pitching、从下到上normal执行。
常规的执行很容易理解,不过loader还可以通过一些方式改变执行流:
- 当pitch时loader存在非undefined的返回值时,则会将返回值传入上一个loader,并跳过pitch阶段进入normal阶段(即往回执行)。如果是第一个pitch loader,则直接将返回值传给webpack。 这个特性被称之为pitch loader的熔断效果。
- inline loader应该是由其他loader产生的,比如在loader在pitch阶段返回一个指定inline loader处理某个文件的任务(require一个模块)。具体地,可以在这个任务中指定使用哪些级别的loader:
!
表示不执行normal loader,执行pre、post和inline loader-!
表示不执行pre、normal loader,执行post和inline loader!!
表示只执行inline loader
常见 loader 的大致实现
babel-loader
在webpack5中,已经在
loaderContext
中添加了这个getOptions
方法,webpack5之前并不存在this.getOptions
方法,需要额外通过loader-utils
这个包实现获取外部loader
配置参数。file-loader
webpack5以前加载图片等二进制文件需要使用file-loader或者 url-loader, 但是在webpack5中不再需要了。
url-loader
如果你不希望webpack帮你把内容转成字符串的的话需要加上
loader.raw=true;
,这样的话content就是一个二进制的Bufferless-loader
css-loader
style-loader
如果我们在style-loader的pitch函数中直接返回值的话,会发生熔断效果,此时的执行顺序如下:
webpack获取到style-loader pitch的返回值,然后进行解析,webpack发现里面存在import语句,
然后就再次使用loader去编译引入的文件,此时remainingRequest的值为
css-loader!index.css
。为什么我们要加上!!
前缀呢?加上这个前缀代表我们不再找配置中的loader,仅仅使用这里的inline loader,这里也就是css-loader normal。如果不加的话又会去找配置文件中的style-loader,又会重新执行其pitch函数,这样就会发生死循环。通过上述
style-loader
的实现过程,我们可以发现如果在loader开发的过程中你需要依赖上一个loader,然后上一个loader的normal函数返回的并不是处理后的资源文件内容而是一串js脚本,那么此时相较于normal loader将你的loader编写为一个pitch loader应该是更好的方式- Twikoo