webpack原理分析——loader(二)
前言
这一篇主要写了loader的分类以及一些常用的loader API
loader 分类
loader主要有四种分别为:同步loader,异步loader,Raw Loader,Pitching Loader,具体写法如下!
同步 loader
方法一
module.exports = function loader(content) {
console.log("这是我的第一个loader");
return content;
};
方法二
通过this.callback
方法,这个方法可以接收4个参数,写法如下:
/**
* callback接受的参数
* 第一个参数为err,有错误为错误,没有即为null
* 第二个参数为content,处理后的内容
* 第三个参数传递source-map
* 第四个参数为meat,给其他的loader传递的参数
*/
module.exports = function (content, map, meta) {
this.callback(null, content, map, meta);
};
用第二种写法的可以更好地将参数传递下去,方便接下来的loader继续进行处理,所以当需要多个loader处理一个文件时更推荐用第二种写法!
异步 loader
module.exports = function (content, map, meta) {
const callback = this.async();
// 进行异步操作
setTimeout(() => {
callback(null, content, map, meta);
}, 1000);
};
tips
如下,同步loader中是不可以执行异步操作的,因为同步loader不会等待异步操作完成之后再往下执行,当同步操作完成之后就表示callback被调用了,如此再次调用就会报错!
module.exports = function (content, map, meta) {
setTimeout(() => {
this.callback(null, content, map, meta);
})
};
Raw Loader
Raw Loader写法如下,它可以执行异步操作,也可以执行同步操作,主要就是需要在暴露时添加一个属性raw = true
,Raw Loader接收到的content为Buffer数据流,主要用于处理图片、字体图标等使用!
module.exports = function (content) {
// content是一个Buffer数据
console.log(content);
return content;
};
module.exports.raw = true; // 开启 Raw Loader
Pitching Loader
写法如下,主要是需要在暴露的对象中添加一个pich方法,pich方法会在loader执行之前执行,执行顺序如下图!
module.exports = function (content) {
console.log("loader");
return content;
};
module.exports.pitch = function (remainingRequest, precedingRequest, data) {
console.log("pich");
};
执行顺序
loader是从右到左从下到上执行,pich方法是从左到右从上到下执行。所以webpack会按顺序先去执行loader链中的pich方法(有就执行,没有跳过),在按照顺序执行loader!
在执行过程中如果任何一个 pitch 有返回值,loader链就会被阻断。webpack 会跳过后面所有的的 pitch 和 loader,直接进入上一个 loader。
常用 loader API
下面是一些常用的loader API,更多的loader API可以参考官方文档
方法名 | 含义 | 用法 |
---|---|---|
this.async | 异步回调 loader,返回 this.callback | const callback = this.async() |
this.callback | 可以同步或者异步调用的并返回多个结果的函数 | this.callback(err, content, sourceMap?, meta?) |
this.getOptions(schema) | 提取给定的 loader 选项,接受一个可选的 JSON schema 作为参数 | this.getOptions(schema) |
this.emitFile | 产生一个文件 | this.emitFile(name, content, sourceMap) |
this.utils.contextify | 返回一个相对路径 | this.utils.contextify(context, request) |
this.utils.absolutify | 返回一个绝对路径 | this.utils.absolutify(context, request) |
小结
通过上面的学习,学会了四种loader的用法以及一下loader API,接下来就开始要学习写一些loader了,期待!
转载自:https://juejin.cn/post/7176536394519543866