Loader就是一个函数, 声明式函数 ,不能⽤箭头函数(因为要上到上下文的this,⽤到this的数据,该函数接受一个参数, 是源码)
拿到源代码,作进⼀步的修饰处理,再返回处理后的源码就可以了
//replaceLoader.js
module.exports = function(source) {
console.log(source, this, this.query);
return source.replace('kkb','开课吧') };
//需要使用node核⼼模块path来处理路径
const path = require('path')
module: {
rules: [ {
test: /\.js$/,
use: path.resolve(__dirname, "./loader/replaceLoader.js")
}
]
},
如何给loader配置参数,loader如何接受参数?
this.query
loader-utils
//webpack.config.js
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: path.resolve(__dirname,"./loader/replaceLoader.js"),
options: {
name: "我是自定义loader"
}
}
]
}
]
},
//replaceLoader.js
//const loaderUtils = require("loader-utils");//官方推荐处理 loader,query的工具
module.exports = function(source) {
//this.query 通过this.query来接受配置⽂件传递进来的参数
//return source.replace("哈哈", this.query.name);
const options = loaderUtils.getOptions(this);
const result = source.replace("哈哈", options.name);
return source.replace("哈哈", options.name);
}
this.callback:
如何返回多个信息,不止是处理好的源码呢,可以使用 this.callback来处理
//replaceLoader.js
const loaderUtils = require("loader-utils");//官方推荐处理loader,query 的⼯具
module.exports = function(source) {
const options = loaderUtils.getOptions(this);
const result = source.replace("哈哈", options.name);
this.callback(null, result);
};
//this.callback(
err: Error | null,
content: string | Buffer,
sourceMap?: SourceMap,
meta?: any
);
this.async :如果loader⾥面有异步的事情要怎么处理呢
const loaderUtils = require("loader-utils");
module.exports = function(source) {
const options = loaderUtils.getOptions(this);
setTimeout(() => {
const result = source.replace("哈哈", options.name);
return result;
}, 1000);
};
//先⽤setTimeout处理下试,发现会报错
<!--我们使⽤this.asycn来处理,他会返回this.callback-->
const loaderUtils = require("loader-utils");
module.exports = function(source) {
const options = loaderUtils.getOptions(this);
//定义⼀个异步处理,告诉webpack,这个loader⾥有异步事件,在⾥⾯调用下这个异步
//callback 就是 this.callback 注意参数的使用
const callback = this.async();
setTimeout(() => {
const result = source.replace("哈哈", options.name);
callback(null, result);
}, 3000);
};
多个loader的使用 注意顺序
顺序,⾃下而上,⾃右到左
//replaceLoader.js
module.exports = function(source) {
return source.replace("哈哈", "word");
};
//replaceLoaderAsync.js
const loaderUtils = require("loader-utils");
module.exports = function(source) {
const options = loaderUtils.getOptions(this); //定义⼀一个异步处理,告诉webpack,这个loader⾥有异步事件,在⾥面调⽤下这个异步
const callback = this.async();
setTimeout(() => {
const result = source.replace("哈哈", options.name);
callback(null, result);
}, 3000);
};
//webpack.config.js
module: {
rules: [
{
test: /\.js$/,
use: [
path.resolve(__dirname, "./loader/replaceLoader.js"),
{
loader: path.resolve(__dirname,"./loader/replaceLoaderAsync.js"),
options: { name: "哈哈"}
}
]
// use: [path.resolve(__dirname,"./loader/replaceLoader.js")]
}
]
},
处理loader的路径问题
resolveLoader: {
modules: ["node_modules", "./loader"]
},
module: {
rules: [ {
test: /\.js$/,
use: [
"replaceLoader",
{
loader: "replaceLoaderAsync",
options: { name: "哈哈"}
}]
// use: [path.resolve(__dirname,"./loader/replaceLoader.js")]
} ]
},
参考:loader API