最基础的插件语法

  1. class BasicPlugin {
  2. // 在构造函数中获取用户为该插件传入的配置
  3. constructor(options){}
  4. // webpack 会调用 BasicPlugin 实例的 apply 方法为插件实例传入 compiler 对象
  5. apply(compiler) {
  6. compiler.plugin('beforeRun', (compiler)=>{})
  7. compiler.plugin('compilation', (compilation)=>{})
  8. compiler.plugin('done', ()=>{})
  9. }
  10. }
  11. // 导出插件
  12. module.exports = BasicPlugin;

使用插件

  1. const BasicPlugin = require(./BasicPlugin.js)
  2. module.exports = {
  3. plugins: [
  4. new BasicPlugin(options),
  5. ]
  6. }

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 对象上广播和监听事件

  1. /**
  2. * 广播事件
  3. * event-name: 事件名称,注意不要和现有事件重名
  4. * params 为附带的参数
  5. **/
  6. compiler.apply('event-name', params)
  1. /**
  2. * 监听名称为 event-name 的事件,当 event-name 事件发生时,函数就会被执行
  3. * 同时函数中的 params 参数为广播事件时附带的参数
  4. **/
  5. compiler.plugin('event-name', function(params) {
  6. })

处理异步事件:

  1. compiler.plugin('emit', function(compilation, callback) {
  2. // 支持处理逻辑
  3. // 处理完毕后执行 callback 以通知 webpack
  4. // 如果不执行 callback,运行流程将会一直卡在这里而不往后执行
  5. callback();
  6. });