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很多,如:entryOption,run,compile,make,emit,done等等。具体可以参照官方文档,这里不一一介绍。这些钩子在webpack编译的不同阶段会依次触发,开发插件的时候只要选择自己需要的钩子做处理就可以了。
hook type
webpack的事件机制是基于tapable这个库实现的。tapable的具体使用方式可以参考它的README。
开发webpack plugin主要用到的hook type是:tap,tapAsync,tapPromise,它们的区别可以简单理解为:
| hook type | 特点 |
|---|---|
| tap | 同步 |
| tapAsync | 异步,callback写法 |
| tabPromise | 异步,promise写法 |
总结
webpack插件开发其实不难,我们平时如果遇到webpack的问题或者想优化打包,也可以尝试写一个小插件去解决。我最近写了一个开源的webpack plugin(webpack-alioss-upload-plugin),大家如果觉得好用,可以给个star,手动笔芯💕哦。