简介
其实也可以理解加加载器,比如你的ts,用tsloader去加载,里面的ts通过loader的ast变成js 他有几种类型,按照执行优先级:
- pre 前置loader
- normal 普通
- inline 内联
- post 后置相同优先级顺序为,从右到左,从上到下
// 此时loader执行顺序:loader3 - loader2 - loader1
module: {
rules: [
{
test: /\.js$/,
loader: "loader1",
},
{
test: /\.js$/,
loader: "loader2",
},
{
test: /\.js$/,
loader: "loader3",
},
],
},
// 此时loader执行顺序:loader1 - loader2 - loader3
module: {
rules: [
{
enforce: "pre",
test: /\.js$/,
loader: "loader1",
},
{
// 没有enforce就是normal
test: /\.js$/,
loader: "loader2",
},
{
enforce: "post",
test: /\.js$/,
loader: "loader3",
},
],
},
写一个试试吧,
写
// loaders/loader1.js
module.exports = function loader1(content, map, meta) {
console.log("hello loader");
return content;
};
或者
module.exports = function (content, map, meta) {
// 传递map,让source-map不中断
// 传递meta,让下一个loader接收到其他参数
this.callback(null, content, map, meta);
return; // 当调用 callback() 函数时,总是返回 undefined
};
或者
module.exports = function (content, map, meta) {
const callback = this.async();
// 进行异步操作
setTimeout(() => {
callback(null, result, map, meta);
}, 1000);
};
简简单单一个loader
- content 源文件的内容
- map SourceMap 数据
- meta 数据,可以是任何内容### 使用:
row-loader
这时候接受的是原始buffer,不然默认是utf-8字符串
module.exports = function (content) {
// content是一个Buffer数据
return content;
};
module.exports.raw = true; // 开启 Raw Loader
pitching loader
webpack 会先从左到右执行 loader 链中的每个 loader 上的 pitch 方法(如果有),然后再从右到左执行 loader 链中的每个 loader 上的普通 loader 方法。
module.exports = function (content) {
return content;
};
module.exports.pitch = function (remainingRequest, precedingRequest, data) {
console.log("do somethings");
return 1;
};
在这个过程中如果任何 pitch 有返回值,则 loader 链被阻断。webpack 会跳过后面所有的的 pitch 和 loader,直接进入上一个 loader
loader API
| 方法名 | 含义 | 用法 |
|---|---|---|
this.async | 异步回调 loader。返回 this.callback | const callback = this.async(),侧重于异步返回结果,更多用到 |
this.callback | 可以同步或者异步调用的并返回多个结果的函数 | this.callback(err, content, sourceMap?, meta?),**侧重于异步多次返回结果,例如抛错** |
this.getOptions | 获取 loader 的 options | 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) |
简单实现
function myRawLoader(source) {
// 提取给定的 loader 选项,
// 从 webpack 5 开始,this.getOptions 可以获取到 loader 上下文对象。它用来替代来自 loader-utils 中的 getOptions 方法。
const { esModule } = this.getOptions();
console.log('esModule:', esModule);
// 这里一定要返回字符串或者 buffer
if (!esModule) {
return `module.exports = ${JSON.stringify(source)}`;
}
return `export default ${JSON.stringify(source)}`;
module.exports = myRawLoader;
简单用
const path = require('path');
module.exports = {
//...
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: path.resolve('./myRawLoader.js'),
options: {
/* ... */
},
},
],
},
],
},
// 多个loaders情况
resolveLoader: {
modules: ['node_modules', path.resolve(__dirname, 'loaders')],
},
};