自创一个banner-loader
本章节我们自己创造一个loader。
自创banner-loader功能介绍
在打包的代码中生成一些额外的注释,比如作者,打包时间等。
写的稍微复杂一点,配置一些属性。
安装插件,校验自己的属性,看配置的对不对
shell
yarn add schema-utils@^1.2.3 -D
代码
添加banner-loader
js
// webpack\webpack-loader\loaders\banner-loader.js
let loaderUtils = require('loader-utils') // 获取loader的配置参数,options等
let validateoptions = require('schema-utils') // 校验数据格式的
let fs = require('fs')
function loader(source) {
console.log('banner-loader 加载了');
// 打包的时候开启缓存(默认是开启的,如果传入false 就是关闭缓存)
// this.cacheable(false)
this.cacheable && this.cacheable()
let cb = this.async() // 异步回调返回结果的回调函数
// 获取loader配置的options
let optios = loaderUtils.getOptions(this)
// 校验options数据格式
let schema = {
type: 'object',
properties: {
text: {
type: 'string'
},
filename: {
type: 'string'
}
}
}
// 比对 schema 和 optios 数据格式是否一致,不一致就会报错
// banner-loader 是标识
validateoptions(schema, optios, 'banner-loader')
/*
如果有filename,就用filename里的文本
如果没有,就用text中的文本
*/
if (optios.filename) {
// 把这个文件增加到webpack打包依赖中,一旦变更 可以出发重新打包
this.addDependency(optios.filename) // 自动添加文件依赖
fs.readFile(optios.filename, 'utf8', (err, data) => {
cb(err, `/**${data} ${new Date().toLocaleString()}*/ ${source}`)
})
} else {
cb(err, `/**${optios.text} ${new Date().toLocaleString()}*/ ${source}`)
}
return source
}
module.exports = loader
修改配置文件
js
// webpack\webpack-loader\webpack.config.js
let path = require('path')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
watch: true, // 边写边打包
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'banner-loader', // 自创一个banner-loader
// 给所有匹配到的js模块,增加一个额外的注释
// 比如 /** cheny && xzz 2022-02-06 17:08 */
options: {
text: 'cheny && xzz', // 默认作者的名字
filename: path.resolve(__dirname, 'banner.txt'), // 如果没有给text,那么就读取这个文件中的内容
}
}
}
]
},
resolveLoader: {
// 找loader的时候,先从node_modules中找,找不到再从我们的loaders目录下找
modules: ['node_modules', path.resolve(__dirname, 'loaders')]
/* alias: { // loader的别名
loader1: path.resolve(__dirname, 'loaders', 'loader1.js')
} */
}
}
添加banner.txt
cheny hhhh
打包看下结果 npx webpack,成功
总结
本节编写了一个自创的loader,banner-loader,功能是给打包后的代码添加一段额外的注释,创建时间和作者名,为了复杂点,还增加了一些配置项,在外部创建一个txt文本,如果有文本,作者名就以文本中的内容为准,涉及到下面几个技术点。
配置方式遵循规范,根babel-loader的配置类似,配置项也一样
jsmodule: { rules: [ { test: /\.js$/, use: { loader: 'banner-loader', // 自创一个banner-loader // 给所有匹配到的js模块,增加一个额外的注释 // 比如 /** cheny && xzz 2022-02-06 17:08 */ options: { text: 'cheny && xzz', // 默认作者的名字 filename: path.resolve(__dirname, 'banner.txt'), // 如果没有给text,那么就读取这个文件中的内容 } } } ] }, resolveLoader: { // 找loader的时候,先从node_modules中找,找不到再从我们的loaders目录下找 modules: ['node_modules', path.resolve(__dirname, 'loaders')] /* alias: { // loader的别名 loader1: path.resolve(__dirname, 'loaders', 'loader1.js') } */ }
引入了 schema-utils 来对配置项进行校验,校验的数据格式如果根自己定义的规则不同,会直接抛出错误
jslet loaderUtils = require('loader-utils') // 获取loader的配置参数,options等 let validateoptions = require('schema-utils') // 校验数据格式的 // 获取loader配置的options let optios = loaderUtils.getOptions(this) // 校验options数据格式 let schema = { type: 'object', properties: { text: { type: 'string' }, filename: { type: 'string' } } } // 比对 schema 和 optios 数据格式是否一致,不一致就会报错 // banner-loader 是标识 validateoptions(schema, optios, 'banner-loader')
在编写loader的时候,如果想实现配置文件变更,也能触发重新打包,需要将配置文件增加到webpack依赖中
js// 把这个文件增加到webpack打包依赖中,一旦变更 可以出发重新打包 this.addDependency(optios.filename) // 自动添加文件依赖
默认loader是开启缓存的,也可以关闭缓存,一般都是开启的
js// 打包的时候开启缓存(默认是开启的,如果传入false 就是关闭缓存) // this.cacheable(false) this.cacheable && this.cacheable()
banner-loader的全部代码
js// webpack\webpack-loader\loaders\banner-loader.js let loaderUtils = require('loader-utils') // 获取loader的配置参数,options等 let validateoptions = require('schema-utils') // 校验数据格式的 let fs = require('fs') function loader(source) { console.log('banner-loader 加载了'); // 打包的时候开启缓存(默认是开启的,如果传入false 就是关闭缓存) // this.cacheable(false) this.cacheable && this.cacheable() let cb = this.async() // 异步回调返回结果的回调函数 // 获取loader配置的options let optios = loaderUtils.getOptions(this) // 校验options数据格式 let schema = { type: 'object', properties: { text: { type: 'string' }, filename: { type: 'string' } } } // 比对 schema 和 optios 数据格式是否一致,不一致就会报错 // banner-loader 是标识 validateoptions(schema, optios, 'banner-loader') /* 如果有filename,就用filename里的文本 如果没有,就用text中的文本 */ if (optios.filename) { // 把这个文件增加到webpack打包依赖中,一旦变更 可以出发重新打包 this.addDependency(optios.filename) // 自动添加文件依赖 fs.readFile(optios.filename, 'utf8', (err, data) => { cb(err, `/**${data} ${new Date().toLocaleString()}*/ ${source}`) }) } else { cb(err, `/**${optios.text} ${new Date().toLocaleString()}*/ ${source}`) } return source } module.exports = loader
参考
https://www.bilibili.com/video/BV1a4411e7Bz?p=43&spm_id_from=pageDriver