自定义编写webpack loader

什么是webpack loader?

webpack loader相当于一个翻译官,你输入的内容,经过它的翻译,变成另外你想要的内容,并且可以是链式的,就是一个接一个的翻译下去。

loader基础

因为webpack是运行在node.js之上的,一个loader其实就是一个node.js模块
这个模块的主要工作就是获得处理前的原内容,处理后,返回处理后的内容。

一个最简单的Loader源码如下:

1
2
3
4
5
module.exports = function(source) {
// source 为 compiler 传递给 Loader 的一个文件的原内容
// 该函数需要返回处理后的内容,这里简单起见,直接把原内容返回了,相当于该 Loader 没有做任何转换
return source;
};

webpack中的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let webpackConfig = {
//...
module: {
rules: [{
test: /\.js$/,
use: [{
//这里写 loader 名即可
loader: 'a-loader',
options: {/* ... */}
}, {
loader: 'b-loader',
options: {/* ... */}
}]
}]
},
resolveLoader: {
// 告诉 webpack 该去那个目录下找 loader 模块
modules: ['node_modules', path.resolve(__dirname, 'loaders')]
}
}

Loader的加载顺序

Loader的加载顺序是从后往前的,上例中的调用顺序是
b-loader -> a-loader

获得 Loader 的 options

我们如果获得上例中的options里的配置呢?
可以通过loader-utils包,它提供了很多有用的工具,最常用的就是获取传入loader的options。

1
2
3
4
5
6
const loaderUtils = require('loader-utils');
module.exports = function(source) {
// 获取到用户给当前 Loader 传入的 options
const options = loaderUtils.getOptions(this);
return source;
};

同步与异步

Loader分为同步和异步,上面介绍的Loader是同步的,但是有些场景下需要通过网络请求才能得出结果,异步的写法如下:

1
2
3
4
5
6
7
8
module.exports = function(source) {
// 告诉 Webpack 本次转换是异步的,Loader 会在 callback 中回调结果
var callback = this.async();
someAsyncOperation(source, function(err, result, sourceMaps, ast) {
// 通过 callback 返回异步执行后的结果
callback(err, result, sourceMaps, ast);
});
};

如何加载本地Loader?

我们本地开发Loader的时候,可以参考我的另一篇文章
模块调试技巧npm-link软链

参考资料

其他Loader
深入Webpack-编写Loader
手把手教你撸一个 Webpack Loader

实战源码-marked转html的loader

md-to-html-loader


自定义编写webpack loader
https://thaneyang.github.io/2019/07/自定义编写webpack-loader.html
作者
live威
发布于
2019年7月15日
许可协议