3-12 webpack 里面的插件是如何实现的?

webpack 插件 是一个 函数,这个函数的原型上必须携带一个 apply 的方法,供给 webpack 使用,webpack 会调用 apply 并传入一个 compiler

关注核心:Compiler和Compilation

在开发Plugin时最常用的两个对象是Compiler和Compilation,他们是Plugin和webpack之间的桥梁,Compiler和Compilation的含义如下:

  1. Compiler对象包含了Webpack所有的配置信息,包含options,loaders,plugins等信息,这个对象在Webpack启动的时候被初始化,在webpack4当中是唯一的实例,可以简单的认为他是webpack的实例(webpack5当中的已经改版了,已经允许多个webpack实例的存在)

  2. Compilation对象包含了当前的模块资源,编译生成资源,变化的文件,当webpack以开发模式运行时,每当检测到一个文件变化一次新的Compilation将被创建,Compilation对象也提供了很多事件回调提供插件做拓展,通过Compilation也能读取到整个Compiler对象。
    Compiler和Compilation的区别在于Compiler代表了整个Webpack从启动到关闭的声明周期,而Compilation只代表了一次新的编译。 或者换个更通俗的说法: Compiler说明了什么时间要做事,但是compilation说明了要做什么事情

事件流

webpack通过Tapable来组织这条生产线。 webpack的事件流机制用了观察者模式。 Compiler和Compilation都继承自Tabable可以直接在Compiler和Compilation对象上关闭和监听事件。

class Plugin {
    apply(compiler) {
       compiler.hooks.afterEmit.tap('testEmitAndAfterEmit', (compilation)=> {
            console.log('112')
       })
       compiler.hooks.emit.tap('testEmitAndAfterEmit', (compilation)=> {
            console.log('111')
       })
       compiler.hooks.emit.tapAsync('testEmitAndAfterEmit', (compilation,cb)=> {
        setTimeout(()=> {
           console.log('222')
           cb()
        },1000)
       })

    }
}
module.exports = Plugin
posted @ 2022-03-12 16:27  林见夕  阅读(295)  评论(0)    收藏  举报