我们在面试 webpack 的时候,感觉已经熟背了八股文,抗住了 webpack 的十连问,最后面试官来了句:『有没有手写过 loader?』,直接懵逼,灵魂深处被深深痛击。
项目目录下创建一个 loaders 文件
命名 replaceLoader.js(叫啥随便你)
1、什么是 loader
众所周知,webpack只能理解js,json等文件,那么除了js,json之外的文件就需要通过loader去顺利加载,因此loader在其中担任的就是翻译工作。loader可以看作一个node模块,实际上就是一个函数,但他不能是一个箭头函数,因为它需要继承webpack的this,可以在loader中使用webpack的方法。
2、手写 loader 的原则
- 单一原则,一个loader只做一件事
- 调用方式,loader是从右向左调用,遵循链式调用
- 统一原则,输入输出都是字符串或者二进制数据
3、loader代码
// source:表示当前要处理的内容
const reg = /(console.log()(.*)())/g;
module.exports = function (source) {
// 通过正则表达式将当前处理内容中的console替换为空字符串
source = source.replace(reg, "")
// 再把处理好的内容return出去,坚守输入输出都是字符串的原则,并可达到链式调用的目的供下一个loader处理
this.callback(null, source)
return
}
4、使用 loader
直接在 module 的规则中按照路径导入即可,
再看一遍 loader 的代码
- source:就是当前要处理的内容,因为我的 demo 中年用到了 JSX,所以要先用 babel-loader 转一下。
因为 loader 的执行顺序是从右往左的,所以会先执行 babel-loader。 这里只是我个人项目举例,没有用到 TSX,JSX 的自行忽略,不影响。 关于 babel干了啥可以参考好基友的文章:Babel 分享。后续有时间我也整理一篇。
转完之后的 source 就是babel处理后的 js 代码了(es5的?)
如下
继续执行 replace 正则替换,请空所有 console
- this.query:返回webpack的参数即options的对象,在 loader 中打印this.query,就是上文中的 {name:'123'}
- this.callback:同步模式,可以把自定义处理好的数据传递给webpack。
- this.async():异步模式,可以大致的认为是this.callback的异步版本,因为最终返回的也是this.callback
到此为止,看上去是不是很简单呢~
以后面试官再问你有没有手写过 loader,直接告诉他,写过!顺便介绍下这几个关键参数,具体逻辑看情况吹