认识
一、认识
Webpack
中的 loader
本质上是一个函数, 接收文件内容源代码作为入参, 同时返回处理后的结果。
Webpack
的 loader-runner
核心逻辑为: 在 Webpack
进入构建阶段后,首先接受待处理的资源文件路径, 会通过 IO
接口读取文件内容,之后调用 LoaderRunner
并将文件内容以 source
参数形式传递到 Loader
数组,source
数据在 Loader
数组内首先经过pitch
阶段读取资源文件内容再经过normal
阶段处理资源文件内容,最终以标准 JavaScript
代码提交给 Webpack
主流程,以此实现内容翻译功能。
二、类型
2.1 inline loader
2.2 pre loader
2.3 normal loader
2.4 post loader
三、执行
loader
的执行阶段实际上分为两个阶段,webpack
在使用loader
处理资源时首先会经过loader.pitch
阶段,pitch
阶段结束后,读取资源文件, 将读取的资源文件内容交给 normal
阶段处理。
-
Pitching
阶段:loader
上的pitch
方法,按照 后置(post
)、行内(inline
)、普通(normal
)、前置(pre
) 的顺序调用。任意一个loader
的pitch
函数如果返回了非undefined
的任何值,会发生熔断效果, 不会读取资源文件内容, 直接将pitch
的返回值传递给normal
阶段loader
的函数。 -
Normal
阶段:loader
上的 常规方法,按照 前置(pre
)、普通(normal
)、行内(inline
)、后置(post
) 的顺序调用。loader
函数的返回值会在loader chain
中进行一层一层传递直到最后一个loader
处理后传递将返回值给webpack
进行传递。需要额外注意的是,在normal
阶段的最后一个loader
一定需要返回一个js
代码(一个module
的代码,比如包含module.exports
语句)
示例如下:
// webpack.config.js
module.exports = {
module: {
rules: [
// 普通loader
{
test: /\.js$/,
use: ['normal1-loader', 'normal2-loader'],
},
// 前置loader
{
test: /\.js$/,
use: ['pre1-loader', 'pre2-loader'],
enforce: 'pre',
},
// 后置loader
{
test: /\.js$/,
use: ['post1-loader', 'post2-loader'],
enforce: 'post',
},
],
},
};
// 入口文件中
import something from 'inline1-loader!inline2-loader!./title.js';
loader
的执行顺序:
纯函数.pitch
如果返回一个非 undefined
的值会发生熔断。 loader
执行链条会被阻断, 立马掉头执行, 直接掉头执行上一个已经执行的loader
的normal
阶段并且将pitch
的返回值传递给下一个normal loader
。如下图所示:
四、细节
4.1 runLoader
function runLoader(options,callback){
}
-
options
:-
resource
: 表示需要加载的资源路径 -
loaders
: 表示需要处理的loader绝对路径拼接成为的字符串,以!分割 -
context
:loader
上下文对象,webpack
会在进入loader
前创建一系列属性挂载在一个object
上,而后传递给loader
内部。 -
processResource
: 读取资源文件的方法
-
-
callback