共计 1167 个字符,预计需要花费 3 分钟才能阅读完成。
1.plugin 的概念
插件是 webpack 的“支柱”功能,他在构建流程里注入钩子来实现。
在 webpack 运行的声明周期中会广播许多事件,plugin 可以监听这些事件,在特定的时刻调用 webpack 提供的 API 执行相应的操作。
2. 具体应用
webpack 插件是一个具有 apply 方法的 JavaScript 对象。apply 方法会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问。
先贴一个我们项目中在使用的 plugin 例子
源码 webpack.js
所以不用担心,我们写的插件中的 apply 方法,都肯定会被 webpack 调用。
那么 compiler 是什么呢?
webpack 的 Compiler 模块是主引擎,它通过 webpack CLI 或 webpack API 或 webpack 配置文件传递的所有选项,创建出一个 compilation 实例。同时它是 tabpabled(一个库)的一个扩展类。
同时我们也需要知道 compilation,这个重要的概念。
Compilation 实例继承于 compiler。例如,compiler.compilation 是对所有 require 图 (graph) 中对象的字面上的编译。这个对象可以访问所有的模块和它们的依赖(大部分是循环依赖)。在编译阶段,模块被加载,封闭,优化,分块,哈希和重建等等。这将是任何编译操作中,重要的生命周期。
我们接着看源码 complier.js 中
所以上面例子中 compiler.hooks 就是找到所有钩子函数,compiler.hooks.compilation 中的 compilation 就是对应的 webpack 编译过程中的一个钩子函数,我们可以看到 compilation 就是一个 new SyncHook 的一个实例
compiler.hooks.compilation.tap,中的 tap 是什么意思呢?
贴上简化后的代码
这里的 tap 就是给这个钩子函数中注册事件,钩子函数中都是会有各种 task(任务),通过 tap(name,task)就传入了对应的任务名和任务具体方法。同步的钩子函数使用 tap, 异步的可以使用 tap tapAsync tapPromise。
讲到这里,如果大家理解了上面的描述的话,我们可以知道,最开始贴的那个例子是在做什么了,就是找到 compiler 的生命周期中的 compilation 钩子函数,给它注册了一个叫 add-cross-origin 的方法。
这个方法执行的时候会在 compliation (注意这里的 compliation 是 compiler 创建的实例对象,而不是刚刚说的那个钩子函数)的 htmlWebpackPluginAlterAssetTags 钩子函数上注册 add-cross-origin-content 事件。