从 Tapable 源码解析 Webpack 事件流核心
2024-02-15 14:21:58
Tapable 是 Webpack 中一个重要的模块,它提供了事件流机制,使我们能够在不同的时机触发自定义事件。本文将带大家从源码的角度来深入剖析 Tapable 的实现,以了解它的工作原理和使用方法。
Tapable 源码解析
Tapable 的源码位于 webpack/lib/Tapable.js
,它是一个类,主要提供了以下几个方法:
apply()
: 用于应用插件。callAsync()
: 用于异步调用插件。call()
: 用于同步调用插件。tap()
: 用于注册一个插件。tapAsync()
: 用于异步注册一个插件。tapPromise()
: 用于注册一个返回 Promise 的插件。
其中,apply()
方法是 Tapable 的核心方法,它负责调用所有已注册的插件。它的实现如下:
apply(options) {
const fn = this._createCallback(options);
this._plugins.forEach((plugin) => {
fn(plugin);
});
}
apply()
方法首先调用 _createCallback()
方法来创建一个回调函数,然后遍历所有已注册的插件,并调用该回调函数。回调函数的实现如下:
_createCallback(options) {
if (this.taps.length === 0) {
return () => {};
}
if (options.async) {
return (plugin) => {
plugin.apply(options.args, (err, result) => {
if (err) {
this.applyPluginsBailResult("error", err);
return;
}
this.applyPluginsAsyncSeriesBailResult("async", result);
});
};
}
if (options.promise) {
return (plugin) => {
plugin.apply(options.args).then(
(result) => {
this.applyPluginsAsyncSeriesBailResult("async", result);
},
(err) => {
this.applyPluginsBailResult("error", err);
}
);
};
}
return (plugin) => {
plugin.apply(options.args);
};
}
_createCallback()
方法根据 options
参数的不同,创建不同的回调函数。如果 options.async
为 true,则创建一个异步回调函数,该回调函数会在插件执行完毕后调用 applyPluginsAsyncSeriesBailResult()
方法。如果 options.promise
为 true,则创建一个返回 Promise 的回调函数,该回调函数会在插件执行完毕后调用 applyPluginsAsyncSeriesBailResult()
方法。否则,创建一个同步回调函数,该回调函数会在插件执行完毕后立即返回。
Tapable 使用示例
Tapable 的使用非常简单,我们只需要注册一个插件,然后调用 apply()
方法即可。例如,我们可以注册一个插件来监听 compilation
事件:
const webpack = require('webpack');
const compiler = webpack({
plugins: [
new webpack.CompilationPlugin({
name: 'my-plugin',
apply(compiler) {
compiler.hooks.compilation.tap('my-plugin', (compilation) => {
console.log('Compilation started!');
});
},
}),
],
});
compiler.run();
当我们运行这个脚本时,我们会看到 "Compilation started!" 信息被打印到控制台。
总结
Tapable 是 Webpack 中一个重要的模块,它提供了事件流机制,使我们能够在不同的时机触发自定义事件。本文从源码的角度分析了 Tapable 的实现,并给出了一个使用示例。希望本文能够帮助您更好地理解 Tapable 的工作原理和使用方法。