最基础的插件语法
class BasicPlugin {
// 在构造函数中获取用户为该插件传入的配置
constructor(options){}
// webpack 会调用 BasicPlugin 实例的 apply 方法为插件实例传入 compiler 对象
apply(compiler) {
compiler.plugin('beforeRun', (compiler)=>{})
compiler.plugin('compilation', (compilation)=>{})
compiler.plugin('done', ()=>{})
}
}
// 导出插件
module.exports = BasicPlugin;
使用插件
const BasicPlugin = require(./BasicPlugin.js)
module.exports = {
plugins: [
new BasicPlugin(options),
]
}
Compiler 和 Compilation
- Compiler 对象包含了 webpack 环境的所有配置信息,包含 options、loaders、plugins等信息,这个对象在 webpack 启动时被实例化,它是全局唯一的,可以简单的理解为 webpack 实例
- Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当 webpack 以开发模式运行时,每当检测到一个文件发生变化,便有一次新的 compilation 被创建。compilation 对象也提供了很多事件回调供插件进行扩展。通过Compilation 也可以读取到 Compiler 对象
- Compiler 代表了整个 webpack 从启动到关闭的生命周期
- Compilation 只代表一次新的编译
事件流
webpack 通过 Tapable(https://github.com/webpack/tapable) 来组织这条复杂的生产线。
webpack 在运行的过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条生成线中,去改变生产线中的运作
webpack 的事件流机制应用了观察者模式,和 Node中的 EventEmitter 非常相似。
Compiler 和 Compilation 都继承自 Tapable,可以直接在 Compiler 和 Compilation 对象上广播和监听事件
/**
* 广播事件
* event-name: 事件名称,注意不要和现有事件重名
* params 为附带的参数
**/
compiler.apply('event-name', params)
/**
* 监听名称为 event-name 的事件,当 event-name 事件发生时,函数就会被执行
* 同时函数中的 params 参数为广播事件时附带的参数
**/
compiler.plugin('event-name', function(params) {
})
处理异步事件:
compiler.plugin('emit', function(compilation, callback) {
// 支持处理逻辑
// 处理完毕后执行 callback 以通知 webpack
// 如果不执行 callback,运行流程将会一直卡在这里而不往后执行
callback();
});