webpack
创建自己的loader
loader是用于对模块的源代码进行转换(处理) 我们使用过很多loader 比如css-loader style-loader babel-loader
我么如果想要自己创建一个loader
首先创建webpack环境
pnpm add webpack webpack-cli -D
之后创建loader模块
loader本质上是一个导出为函数的javascript模块
loader runner库会调用这个函数 然会将上一个loader产生的结果或者资源文件传入进去
编写一个m-loader-01.js模块 这个函数会接收三个参数
content:资源文件的内容
map:sourcemap相关的数据
meta:一些元数据
module.exports = function (content, map, meta) {
console.log("01" + content);
return content;
};
建立webpack.config.js文件
并使用自己的loader
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "./build"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.js$/,
use: [
"./m-loader/m-loader-01.js",
"./m-loader/m-loader-02.js",
"./m-loader/m-loader-03.js",
],
},
],
},
};
具体文件目录
打包后的效果
同步的loader
什么是同步的loader
默认创建的loader就是同步的loader
这个loader必须通过return 或者this.callback来返回结果 交给下一个loader来处理
通常在有错误的情况下 我们会使用this.callback
返回值传递给下一个loader
module.exports = function (content) {
console.log("03" + content);
return content + 'aaaa';
};
module.exports = function (content) {
console.log("02" + content);
return content + "bbbb";
};
module.exports = function (content, map, meta) {
console.log("01" + content);
return content;
};
但是当如果有异步操作时 是不会等待的 会返回undefined
module.exports = function (content) {
setTimeout(() => {
console.log("03" + content);
return content + "aaaa";
}, 10000);
};
解决方法 使用异步loader (后面会提到)
使用callback传递 优点是可以处理错误信息
第一个参数:错误信息
第二个参数:传递给下一个loader的内容
module.exports = function (content) {
//this绑定对象
const callback = this.callback;
callback(null, "哈哈哈");
};
异步loader
什么是异步loader
有时候我们使用loader时会进行一些异步操作
我们希望在异步操作完成后 在返回这个loader处理的结果
这时候我们就要使用异步的loader
loader-runner已经在执行loader时给我们提供了方法 让loader变成一个异步的loader
module.exports = function (content) {
//this绑定对象
const callback = this.async();
setTimeout(() => {
console.log("03" + content);
callback(null, content + "aaaa");
}, 2000);
};
给loader传递参数
我们可以使用getOptions
module.exports = function (content) {
//1.获取使用loader时 传递进来的参数
const options = this.getOptions();
console.log(options);
console.log("04", content);
return content;
};
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "./build"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.js$/,
use: [
// "./m-loader/m-loader-01.js",
// "./m-loader/m-loader-02.js",
// "./m-loader/m-loader-03.js",
{
loader: "./m-loader/m-loader-04.js",
options: {
name: "kobe",
age: 24,
},
},
],
},
],
},
};
校验参数
我们可以通过一个webpack官方提供的校验库schema-utils 安装对应的库
pnpm add schema-utils
const { validate } = require("schema-utils");
const loader04Schema = require("../schema/loader-04-schema.json");
module.exports = function (content) {
//1.获取使用loader时 传递进来的参数
const options = this.getOptions();
console.log(options);
//2.校验参数是否符合规则
validate(loader04Schema, options);
console.log("04", content);
return content;
};
创建schema文件与规则文件
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "请输入名称,并且是string类型"
},
"age": {
"type": "number",
"description": "请输入年龄,并且是number类型"
}
}
}
文件目录