webpack(高级)--创建自己的loader 同步loader 异步loader loader参数校验

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类型"
		}
	}
}

文件目录
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_聪明勇敢有力气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值