为了找出答案,我编写了自己的加载器a-loader.js
到h-loader.js
,它们接受内容,打印日志,然后返回内容。每个加载器文件都有一个正常阶段和一个 pitching 阶段以保证完整性。您可以在此处阅读关于 pitching 加载器的信息:https://webpack.js.org/api/loaders/#pitching-loader。
a-loader.js
:
module.exports = function(content) {
console.log('Loader A, normal phase.');
return content;
};
module.exports.pitch = function(remainingRequest, precedingRequest, data) {
console.log('Loader A, pitching phase.');
}
所有的加载程序代码都是一样的,除了我将日志记录语句更改为记录加载程序的内容。
我的webpack-config.js
是这样的:
module: {
rules: [
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/a-loader.js')}],
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/b-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/c-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/d-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/e-loader.js')}],
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/f-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/g-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/h-loader.js')}]
},
]
}
输出:
Loader A, pitching phase.
Loader B, pitching phase.
Loader C, pitching phase.
Loader D, pitching phase.
Loader E, pitching phase.
Loader F, pitching phase.
Loader G, pitching phase.
Loader H, pitching phase.
Loader H, normal phase.
Loader G, normal phase.
Loader F, normal phase.
Loader E, normal phase.
Loader D, normal phase.
Loader C, normal phase.
Loader B, normal phase.
Loader A, normal phase.
没有意外。先运行 pitching 阶段,然后再运行正常阶段。正如你所指出的那样,普通阶段的加载器是从右往左应用的。h
在普通阶段中是首先处理的,因为它在数组(链)中最靠右。我有一个有用的方法来记住 pitching 的顺序。只需想象一下正常阶段的顺序,并想象一个在正常顺序上方投影的镜像图像。这个镜像图像就是 pitching 的顺序。
接下来,我调整了 webpack.config.js
如下:
module: {
rules: [
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/a-loader.js')}],
enforce: "pre"
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/b-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/c-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/d-loader.js')}],
enforce: "post"
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/e-loader.js')}],
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/f-loader.js')}],
enforce: "post"
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/g-loader.js')}]
},
{
test: /\.js$/,
use: [{loader: path.resolve('loaders/h-loader.js')}],
enforce: "pre"
},
]
}
输出:
Loader D, pitching phase.
Loader F, pitching phase.
Loader B, pitching phase.
Loader C, pitching phase.
Loader E, pitching phase.
Loader G, pitching phase.
Loader A, pitching phase.
Loader H, pitching phase.
Loader H, normal phase.
Loader A, normal phase.
Loader G, normal phase.
Loader E, normal phase.
Loader C, normal phase.
Loader B, normal phase.
Loader F, normal phase.
Loader D, normal phase.
暂时忽略分块阶段,因为它们只是正常阶段的镜像反映。将enforce: pre
和post
视为分组。"pre"是第一组,然后是未标记的"normal"组,最后是"post"组。在正常阶段中,第一个加载器是h
,因为它在"pre"组中并且在数组中最右边。接下来是a
,因为它是另一个在"pre"组中的加载器。接下来是"未分组"的g
、e
、c
、b
,从右到左依次运行。最后是"post"组,f
和d
从右到左顺序运行。
我不知道为什么这在webpack网站上没有更好的文档说明。