解析loader:
webpack.config.js:
module.exports = {
module:{
rules:[
{
test: /\.js$/
use:[
'loader1',
'laoder2',
{
loader: 'loader3',
options: {}
}
]
}
]
}
}
loader本质是一个函数:
module.exports = function (content, map, data){
return content
}
module.exports.pitch = function(prevPath, nextPath){
console.log(prevPath, nextPath)
}
众所周知,loader执行顺序是从后向前,其实它还可以挂载一个pitch方法,执行顺序是从前向后,接收的参数是执行本loader之前和之后的参数的绝对路径。
同步loader写法:2种
module.exports = function (content){
// 1.return
return content
// 2.this.callback
this.callback(null, content)
}
异步loader写法:1种
module.exports = function(content){
const callback = this.async()
setTimeout(()=>{
callback(null, content)
},1000)
}
推荐使用异步loader,可以处理一些事情
获取传给loader的options:loader-utils
验证传给loader的options:schema-utils,校验规则是配置schema.json
Loader3.js:
const {getOptions} = require('loader-utils')
const {validate} = require('schema-utils')
const schema = require('./schema')
module.exports = function(content){
// 获取传入的optionss
const options = getOptions(this)
// 规则,参数,规则报错时的提示
validate(schema, options, {
name:'loader3'
})
}
schema.json:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "名称"
}
}
// 配置时是否可以添加除了name外的其他属性
"additionalProperties": false
}
loader实战:
先安装:npm i loader-utils schema-utils @babel/core @babel/preset-env -D
// 获取传入的option
const { getOptions } = require("loader-utils");
// 校验options
const { validate } = require("schema-utils");
// 本loader核心:编译js
const babel = require("@babel/core");
// nodejs内置工具函数,使用其promisify将普通异步函数转为promise方式
const util = require("util");
// 校验规则
const schema = require("./babelSchema");
// babel的转换规则
const transform = util.promisify(babel.transform);
module.exports = function (content) {
// 获取options
const options = getOptions(this);
validate(schema, options, {
name: "loader4",
});
const callback = this.async();
transform(content, options)
.then(({ code, map }) => {
callback(null, code, map);
})
// 第一个参数有就不继续执行后面的参数
.catch((code) => callback(code));
};
config配置:
···
rules: [
{
test: /\.js$/,
use: [
{
loader: "loader4",
options: {
presets: ["@babel/preset-env"],
},
},
],
},
],
···