webpack-loader和plugin

131 阅读2分钟

loader

loader就是一个函数,当wenbpack解析资源是,会调用相应的loader去处理。
loader接受大文件内容作为参数,返回处理后的内容出去

  • content 文件内容
  • map sourceMap
  • meta别的loader传递的数据
  1. 分类
  • pre:前置loader
  • normal:普通loader
  • inline:内联loader
  • post:后置loader
  1. 执行顺序 pre > normal > inline > post

普通loader:从右到左,从下到上

  1. 使用loader方式

image.png

分类

同步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.callbackconst callback = this.async()
this.callback可以同步或者一步调用的并返回多个结果的函数this.callback(err, content, map?, meta?)
this.getOptions(schema)获取loader的optionsthis.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)

更多文档,webpack官方loader api 文档

编写一个clean-log-loader

清除所有的console.log

moduel.exports = function(content) {
    return content.replace(/console\.log\(*\);?/g, '');
}

Plugin

通过插件我们可以扩展webpack,为了方便我们直接介入和控制编译过程,webpack把编译过程中触发的各类关键时间封装成事件借口暴露出来,这些借口被很形象的称作为hooks(钩子),开发插件,离不开这些钩子。

weboack官网 compiler-hooks

运行

  1. weboack加载webpack.conf.js中所有配置,此时就会new TestPlugin(),执行插件的constructor
  2. webpack创建compiler对象
  3. 遍历所有的plugins插件,调用插件的apply方法
  4. 执行剩下编译流程(触发各个hooks事件)
class TestPlugin{
    constructor() {}
    apply(compiler) {
        compiler.hook.environment.tap('testPlugin', () => {})
    }
}