webpack 自定义plugin

780 阅读2分钟

www.webpackjs.com/contribute/…

1.编写 MyPlugin

先看demo

  webpack配置如下:
  const BasicPlugin = require('./MyPlugin.js')
  ...
  plugins: [
    new HtmlWebpackPlugin({
      template: './examples/index.tpl',
      filename: './index.html',
      favicon: './examples/favicon.ico'
    }),
    new CopyWebpackPlugin([
      { from: 'examples/versions.json' }
    ]),
    new MyPlugin()
  ]

编写 MyPlugin

function MyPlugin() {}

MyPlugin.prototype.apply = function(compiler) {
  compiler.plugin('emit', function(compilation, callback) {
    // 检索每个(构建输出的)chunk:
    compilation.chunks.forEach(function(chunk) {
      // 检索 chunk 中(内置输入的)的每个模块:
      chunk.modules.forEach(function(module) {
        // 检索模块中包含的每个源文件路径:
        module.fileDependencies.forEach(function(filepath) {
          // 我们现在已经对源结构有不少了解……
        });
      });

      // 检索由 chunk 生成的每个资源(asset)文件名:
      chunk.files.forEach(function(filename) {
        // Get the asset source for each file generated by the chunk:
        var source = compilation.assets[filename].source();
      });
    });

    callback();
  });
};

module.exports = MyPlugin;

2.原理:

  • Webpack 启动后,在读取配置的过程中会先执行 new helloPlugin(options) 初始化一个 helloPlugin 获得其实例。
  • 在初始化 compiler 对象后,再调用 helloPlugin.apply(compiler) 给插件实例传入 compiler 对象。
  • 插件实例在获取到 compiler 对象后,就可以通过 compiler.plugin(事件名称, 回调函数) 监听到 Webpack 广播出来的事件。并且可以通过compiler 对象去操作 Webpack。

3.compiler和compilation对象

  • Compiler 对象包含了Webpack环境所有的的配置信息,包含options,loaders,plugins 这些信息,这个对象在Webpack启动时候被实例化,它是全局唯一的,可以简单地把它理解为 Webpack 实例;
  • Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当Webpack 以开发模式运行时,每当检测到一个文件变化,一次新的Compilation将被创建。Compilation 对象也提供了很多事件回调供插件做扩展。通过 Compilation 也能读取到 Compiler 对象。
  • Compiler 和 Compilation 的区别在于:Compiler 代表了整个 Webpack 从启动到关闭的生命周期,而 Compilation 只是代表了一次新的编译。

4.compiler.plugin事件

  • 发布 广播事件

compiler.apply('event-name',params);

  • 绑定 监听事件

compiler.plugin('event-name',function(params) {});