loader
loader就是一个函数,当wenbpack解析资源是,会调用相应的loader去处理。
loader接受大文件内容作为参数,返回处理后的内容出去
- content 文件内容
- map sourceMap
- meta别的loader传递的数据
- 分类
- pre:前置loader
- normal:普通loader
- inline:内联loader
- post:后置loader
- 执行顺序 pre > normal > inline > post
普通loader:从右到左,从下到上
- 使用loader方式
分类
同步loader
// test-loader.js
// 方式一
module.exports = funtcion(content, map, meta) {
let res;
// ……………… 进行处理
return res;
}
// 方式二
module.exports = funtcion(content, map, meta) {
/*
第一个参数,err 标识是否有错误
第二个参数,content 处理后的内容
第三个参数,source map继续传递source-map
第四个参数,meta给下一个loader的参数
*/
this.callback(null, content, map, mata)
}
异步loader
module.exports = function(content) {
const callback = this.async();
setTimeout(() => {
console.log('test2');
callback(null, content, map, meta)
}, 1000)
}
raw-loader
处理图片、字体图标等,接收到的数据buffer数据流
// test3-loader.js
module.exports = function(content) {
return content;
}
modile.exports.raw = true;
pitch-loader
同时对外暴露了pictch方法,比如我们配置了三个normal-loser,loader: [A, B, C]
,ABC三个loader都是pitch方法(没有返回值),则执行顺序为 A的pitch方法,B的pitch方法,C的pitch方法,然后在按CBA执行loader。
如果B的picth方法有return,那么执行是A的pitch,B的pitch,loader A【熔断机制】
// test4-loader
module.exports = function(content) {
return content
}
module.exports.pitch = function() {
}
loader API
方法名 | 含义 | 用法 |
---|---|---|
this.async | 异步回调loader,返回this.callback | const callback = this.async() |
this.callback | 可以同步或者一步调用的并返回多个结果的函数 | this.callback(err, content, map?, meta?) |
this.getOptions(schema) | 获取loader的options | this.getOptions(schema) |
this.emitFile | 产生一个文件 | this.emitFile(name, content, sourceMap) |
this.utils.contextify | 产生一个相对路径 | this.utils.contextify(context, map) |
this.utils.absolutify | 产生一个绝对路径 | this.utils.absolutify(context, map) |
编写一个clean-log-loader
清除所有的console.log
moduel.exports = function(content) {
return content.replace(/console\.log\(*\);?/g, '');
}
Plugin
通过插件我们可以扩展webpack,为了方便我们直接介入和控制编译过程,webpack把编译过程中触发的各类关键时间封装成事件借口暴露出来,这些借口被很形象的称作为hooks(钩子),开发插件,离不开这些钩子。
运行
- weboack加载webpack.conf.js中所有配置,此时就会new TestPlugin(),执行插件的constructor
- webpack创建compiler对象
- 遍历所有的plugins插件,调用插件的apply方法
- 执行剩下编译流程(触发各个hooks事件)
class TestPlugin{
constructor() {}
apply(compiler) {
compiler.hook.environment.tap('testPlugin', () => {})
}
}