webpack插件开发

2,067 阅读2分钟

webpack作为前端最热门的打包工具,除了有丰富灵活的配置,还有强大的可扩展性(loader和plugin机制)。现在,我主要介绍下plugin的开发方式。

plugin的配置

我们知道,webpack配置plugin的方式很简单:

// webpack.config.js
var HelloWorldPlugin = require('hello-world');

module.exports = {
  // ... config settings here ...
  plugins: [new HelloWorldPlugin({ options: true })]
};

webpack配置维护了一个插件列表(plugins),webpack打包时会实例化插件,并传入参数来改变插件的行为。

plugin的写法

举一个简单的例子:

// A JavaScript class.
class MyExampleWebpackPlugin {
  // Define `apply` as its prototype method which is supplied with compiler as its argument
  apply(compiler) {
    // Specify the event hook to attach to
    compiler.hooks.emit.tapAsync(
      'MyExampleWebpackPlugin',
      (compilation, callback) => {
        console.log('This is an example plugin!');
        console.log('Here’s the `compilation` object which represents a single build of assets:', compilation);

        // Manipulate the build using the plugin API provided by webpack
        compilation.addModule(/* ... */);

        callback();
      }
    );
  }
}

一个webpack插件的基本模式包括几个要素:类名、apply方法、event hook、compilation的处理和hook type及其回调处理。

apply方法是必须有的,因为webpack运行的时候会调用plugin实例的apply方法。

compiler可以理解为全局的webpack实例,webpack在生命周期的不同阶段提供了不同的钩子,方便我们自定义webpack打包的行为。

compliation是webpack要进行处理的资源(js、css、html等),我们可以根据自己的需要对资源进行加工。

在上面,tapAsync是hook type的一种,第一个参数一般跟插件的类名一样,主要用来区分在该hook type上定义的不同的回调行为。

event hook

webpack plugin的event hook很多,如:entryOptionruncompilemakeemitdone等等。具体可以参照官方文档,这里不一一介绍。这些钩子在webpack编译的不同阶段会依次触发,开发插件的时候只要选择自己需要的钩子做处理就可以了。

hook type

webpack的事件机制是基于tapable这个库实现的。tapable的具体使用方式可以参考它的README

开发webpack plugin主要用到的hook type是:taptapAsynctapPromise,它们的区别可以简单理解为:

hook type 特点
tap 同步
tapAsync 异步,callback写法
tabPromise 异步,promise写法

总结

webpack插件开发其实不难,我们平时如果遇到webpack的问题或者想优化打包,也可以尝试写一个小插件去解决。我最近写了一个开源的webpack plugin(webpack-alioss-upload-plugin),大家如果觉得好用,可以给个star,手动笔芯💕哦。

参考资料