在项目文件夹下创建一个文件error-loader.js
Loader本质上是一个函数,参数content是一段字符串,存储着文件的内容,最后将loader函数导出就可以提供给webpack使用了.
//error-loader.js
//loader函数
module.exports = function (content){
console.log(this.query); // { name: 'hello' }
return content;
}
webpack的配置文件在设置rules时(代码如下),只需要将use里的loader指向上面导出的loader函数的文件路径,这样webpack就能顺利引用loader了.另外我们还可以添加options属性给loader函数传参.
//webpack.config.js
//webpack配置
const path = require('path')
module.exports = {
module:{
rules:[
{
test:/\.js$/,
use:[
{
loader:path.resolve(__dirname,"./error-loader.js"),
options:{
name:"hello"
}
}
]
}
]
}
}
//还可以这样写
module.exports = {
entry:‘index.js’//指定某一个文件
mode:‘development’
module:{
rules:[
{
test:/\.js$/,
use:[‘error-loader’]
}
]
},
resolveLoader:{
modules:[path.resolve(_dirname,"laoders")] //laoders同文件夹下的loader
}
}
项目一旦启动打包,webpack检测到.js文件,它就会把文件的代码字符串传递给error-loader.js导出的loader函数执行.
我们上面编写的loader函数并没有对代码字符串content做任何操作,直接返回了结果.那么我们自定义loader的目的就是为了对content源代码做各种数据操作,再将操作完的结果返回.
比如我们可以使用正则表达式将content中所有的console.log语句全部去掉,那么最后我们生成的打包文件里就不会包含console.log.
另外我们在开发一些功能复杂的loader时,可以接收配置文件传入的参数.例如上面webpack.config.js中给error-loader传入了一个对象{name:“hello”},那么在自定义的loader函数中可以通过this.query获取到参数.
loader函数除了直接使用return将content返回之外,还可以使用this.callback(代码如下)达到相同的效果.
this.callback能传递以下四个参数.第三个参数和第四个参数可以不填.this.callback传递的参数会发送给下一个loader函数接受,每一个loader函数形成了流水线上的一道道工序,最终将代码处理成期待的结果.
第一个参数为错误信息,没有出错可以填null
第二个参数为content,也是要进行数据操作的目标
第三个参数为sourceMap,选填项.它将打包后的代码与源码链接起来,方便开发者调试,一般通过babel生成.
第四个参数为meta额外信息,选填项.
module.exports = function (content){
this.callback(null,content);
}
以上介绍的内容都是使用同步的方式编写,万一loader函数里面需要做一些异步的操作就要采用如下方式.
this.async()调用后返回一个callback函数,等到异步操作完,就可以继续使用callback将content返回.
//上一个loader可能会传递sourceMap和meta过来,没穿就为空
module.exports = function (content,sourceMap,meta){
const callback = this.async();
setTimeout(()=>{ // 模拟异步操作
callback(null,content);
},1000)
}
参考:https://zhuanlan.zhihu.com/p/397174187(此处有详细的异常捕捉的loader编写)