📄Webpack loader执行流程

type
status
date
slug
summary
tags
category
icon
password
Status
webpack 的 loader分为四种:pre、normal、inline、post。
执行顺序分为两个步骤:
  1. pitch 阶段,loaders的 pitching 过程从后到前(post → inline → normal → pre
  1. normal 阶段,loaders的 normal 过程从前到后(pre → normal → inline → post
注意这个是关于 loader 级别的,即rule中指定enforce,如果全是normal即没有设置enforce,则遵循从上到下pitching、从下到上normal执行。
常规的执行很容易理解,不过loader还可以通过一些方式改变执行流:
  1. 当pitch时loader存在非undefined的返回值时,则会将返回值传入上一个loader,并跳过pitch阶段进入normal阶段(即往回执行)。如果是第一个pitch loader,则直接将返回值传给webpack。 这个特性被称之为pitch loader的熔断效果。
  1. inline loader应该是由其他loader产生的,比如在loader在pitch阶段返回一个指定inline loader处理某个文件的任务(require一个模块)。具体地,可以在这个任务中指定使用哪些级别的loader:
    1. !表示不执行normal loader,执行pre、post和inline loader
    2. -!表示不执行pre、normal loader,执行post和inline loader
    3. !! 表示只执行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就是一个二进制的Buffer
less-loader
css-loader
style-loader
如果我们在style-loader的pitch函数中直接返回值的话,会发生熔断效果,此时的执行顺序如下:
notion image
notion image
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

© 2021-2024 Tabing | 萌ICP备20240819号