上一节实现了“babel-loader”,这节我来实现一个自己的loader,命名为“time-loader”,time-loader的用处是,在打包好的代码前添加时间,像这样:
//webppack.config.js
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "time-loader",
options: {
text: "new Date()",
filename: path.resolve(__dirname, "time.js") //此处我写filename的用意是自定义话(比如只要年,只要月,或者要毫秒数),没有这个字段的话,就使用test字段
}
}
}
]
}
// time.js
new Date().getFullYear(); // 假设我们只要年份
接下来,开始完成time-loader.js
// time-loader.js
let loaderUtils = require("loader-utils");
let validateOptions = require("schema-utils"); //这个工具是为了校验使用这个loader时,传递的options格式是否正确
let fs = require("fs");
function loader(source){
let options = loaderUtils.getOptions(this); // 先拿到用户配置的options
let cb = this.async();
this.cacheable && this.cacheable(); //添加缓存,cacheable方法可以传参--布尔值,但一般默认使用缓存,也就是不传参,或者传true
let schema = { // 配置校验规则
type: 'object',
properties: {
text: {
type: 'string'
},
filename: {
type: 'string'
}
}
}
validateOptions(schema, options, "time-loader"); // 用schema来校验options,如不通过,提示“time-loader”
if(options.filename){ // 如果有配置filename的话
this.addDependency(options.filename); // 将这个filename加到webpack的依赖中,如果webpack配置文件中配置了“watch:true”的话,那么更新“time.js”,也会实时打包
fs.readFile(options.filename, "utf-8", (err, data) => {
cb(err, `/**${eval(data)}${source}**/`)
})
}else{
cb(`/**${options.text}**/${source}`)
}
}
module.exports = loader;