开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
- Webpack 本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是 Tapable,webpack 中最核心的负责编译的 Compiler 和负责创建 bundle 的 Compilation 都是 Tapable 的实例
- 通过事件和注册和监听,触发 webpack 生命周期中的函数方法
Tapable是webpack打包的核心工具, 暴露了tap,tapAsync,tapPromise方法来实现hook封装调用。在webpack打包的过程中一些hook注入事件。
1. tapable分类
同步异步分类 Hook 类型可以分为同步Sync和异步Async,异步又分为并行和串行
按同步异步分类
- 同步: SyncHook, SyncBailHook, SyncWaterfallHook,SyncLoopHook
- 异步: AsyncParalleHook, AsyncParalleBailHook, AsyncSeriesHook, AsyncSeriesBailHook,AsyncSeriesWaterfallHook
按照返回值分类
1.1 Basic 执行每一个事件函数,不关心函数的返回值,有 SyncHook、AsyncParallelHook、AsyncSeriesHook
- SyncHook
- AsyncSeriesHook
- AsyncParalleHook
1.2 Bail 执行每一个事件函数,遇到第一个结果 result !== undefined 则返回,不再继续执行。有:SyncBailHook、AsyncSeriesBailHook, AsyncParallelBailHook
- SyncBailHook
- AsyncParalleBailHook
- AsyncSeriesBailHook
1.3 Waterfall 如果前一个事件函数的结果 result !== undefined,则 result 会作为后一个事件函数的第一个参数,有 SyncWaterfallHook,AsyncSeriesWaterfallHook
- SyncWaterfallHook
- AsyncSeriesWaterfallHook
1.4 Loop 不停的循环执行事件函数,直到所有函数结果 result === undefined,有 SyncLoopHook 和 AsyncSeriesLoopHook
- SyncLoopHook
2. plugin的配置,
//plugin都在plugins里面注册和实例化, plugin类实现apply方法,传入compiler,
// 会在webpack打包流程初始阶段循环调用插件的apply方法去注册事件
module.exports = {
mode: 'development',
devtool:false,
entry: './src/index.js',
plugins: [
new HtmlWebpackPlugin({
template:'./src/index.html'
}),
new DonePlugin(),
new ArchivePlugin()
]
}
//3. webpack打包流程初始化阶段,获取所有配置后,加载所有配置的插件将compiler传进去
const { plugins } = finalOptions;
for (let plugin of plugins) {
plugin.apply(compiler);
}
2.1 简单的plugin
- 插件是一个类
- 类上有一个apply的实例方法
- apply的参数是compiler
class DonePlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
}
}
- compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。
- compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。
3. compiler 钩子
Compiler 模块是 webpack 的主要引擎,它通过 CLI 或者 Node API 传递的所有选项创建出一个 compilation 实例。 它扩展(extends)自 Tapable 类,用来注册和调用插件。 大多数面向用户的插件会首先在 Compiler 上注册。
compiler.hooks.someHook.tap('MyPlugin', (params) => {
/* ... */
});
常用的compiler 钩子,compilation 钩子可参考官网的例子:
compilation 钩子