Open huruji opened 5 years ago
Webpack 的 Compiler 对象主要有以下 Hooks:
webpack 处理完 entry 配置项后触发,这是一个同步串行的 SyncBailHook 钩子,只要监听函数有一个函数的返回值不为undefined,则直接跳过剩下逻辑
无参数
处理完初始化插件后触发,这是一个同步的 SyncHook 钩子,不关心返回值
参数是 compiler 对象
Resolve 安装完成后触发,这是一个同步的 SyncHook 钩子
environment 准备好后触发,这是一个 SyncHook 钩子
environment 安装完成后触发,这是一个 SyncHook 钩子
compiler.run 函数之前触发,这是一个异步串行 AsyncSeriesHook 钩子
compiler.run
参数是 compiler
开始读取 records 之前触发,这是一个异步串行 AsyncSeriesHook 钩子
监听模式下,一个新的编译开始之前触发,这是一个异步串行的 AsyncSeriesHook 钩子
normalModuleFactory 创建之后触发,这是一个同步 SyncHook 钩子
normalModuleFactory
参数是 normalModuleFactory
contextModuleFactory 创建之后触发,
contextModuleFactory
参数是 contextModuleFactory
编译参数创建之后触发,这是一个异步串行 AsyncSeriesHook 钩子
参数是 compilationParams
一个新的编译创建之后触发,这是一个同步 SyncHook 钩子
触发 compilation 之前触发,这个是一个同步 SyncHook 钩子
参数是 compilation
编译创建之后执行,这是一个同步 SyncHook 钩子
这是一个异步并发 AsyncParallelBailHook 钩子
这是一个异步串行 AsyncSeriesHook 钩子
这是一个 SyncBailHook 钩子
生成资源到 output 目录之前触发,这是一个异步串行 AsyncSeriesHook 钩子
生成资源到 output 目录之后,这是一个异步串行 AsyncSeriesHook 钩子
编译完成后触发,这是一个异步串行 AsyncSeriesHook 钩子
参数是 stats
编译失败触发,这是一个同步 SyncHook 钩子
参数是 error
监听模式下,编译无效时触发,这是一个同步 SyncHook 钩子
参数是 fileName,changeTime
+ watchClose
监听模式停止,一个同步 SyncHook 钩子
通过实例学习是最快的,让我们看一个最简单的例子,webpack-clear-console,这个插件是去除输出里的 console 调用,里面插件的写法是 webpack4 之前的写法,不过基本上是一致的,通过源码可以看到插件在 emit 这个钩子上(生成资源到output目录之前)触发,通过 compilation 对象的 assets 对象的 source 方法获取文件内容,然后进行正则匹配。 最后需要将 source 和 size 的变动归回原来的 compilation 对象中,否则这些变动是不会生效的
console
emit
compilation
assets
source
island-webpack-plugin 是一个在 bundle 中添加作者信息的插件,这个插件同样是在 emit 这个钩子上触发的,同样是获取 source 后对 source 添加作者信息的字符串。
emit 是一个异步的钩子,可以使用 promise 的 如下,可以使用 promise 对上面的插件进行简单改造,以 island-webpack-plugin 为例,改造如下:
class AuthorPlugin { constructor(options) { this.options = options; } apply(compiler) { compiler.hooks.emit.tap('author-plugin', (compilation) => { const options = this.options return new Promise((resolve, reject) => { const assets = compilation.assets Object.keys(assets).forEach(e => { let source = assets[e].source() let info = [] if (options.author) info.push(`@Author: ${options.author}`) if (options.email) info.push(`@Email: ${options.email}`) if (options.homepage) info.push(`@Homepage: ${options.homepage}`) if (info.length) { info.push(`@Date: ${new Date()}`) source = `/*\n ${info.join('\n\n ')}\n*/\n${source}` } compilation.assets[e].source = () => source compilation.assets[e].size = () => source.size }) resolve() }) }) } } module.exports = AuthorPlugin
webpack 的 Hooks
Webpack 的 Compiler 对象主要有以下 Hooks:
webpack 处理完 entry 配置项后触发,这是一个同步串行的 SyncBailHook 钩子,只要监听函数有一个函数的返回值不为undefined,则直接跳过剩下逻辑
无参数
处理完初始化插件后触发,这是一个同步的 SyncHook 钩子,不关心返回值
参数是 compiler 对象
Resolve 安装完成后触发,这是一个同步的 SyncHook 钩子
参数是 compiler 对象
environment 准备好后触发,这是一个 SyncHook 钩子
无参数
environment 安装完成后触发,这是一个 SyncHook 钩子
compiler.run
函数之前触发,这是一个异步串行 AsyncSeriesHook 钩子参数是 compiler
开始读取 records 之前触发,这是一个异步串行 AsyncSeriesHook 钩子
参数是 compiler
监听模式下,一个新的编译开始之前触发,这是一个异步串行的 AsyncSeriesHook 钩子
参数是 compiler
normalModuleFactory
创建之后触发,这是一个同步 SyncHook 钩子参数是 normalModuleFactory
contextModuleFactory
创建之后触发,参数是 contextModuleFactory
编译参数创建之后触发,这是一个异步串行 AsyncSeriesHook 钩子
参数是 compilationParams
一个新的编译创建之后触发,这是一个同步 SyncHook 钩子
参数是 compilationParams
触发 compilation 之前触发,这个是一个同步 SyncHook 钩子
参数是 compilation
编译创建之后执行,这是一个同步 SyncHook 钩子
参数是 compilation
这是一个异步并发 AsyncParallelBailHook 钩子
参数是 compilation
这是一个异步串行 AsyncSeriesHook 钩子
参数是 compilation
这是一个 SyncBailHook 钩子
参数是 compilation
生成资源到 output 目录之前触发,这是一个异步串行 AsyncSeriesHook 钩子
参数是 compilation
生成资源到 output 目录之后,这是一个异步串行 AsyncSeriesHook 钩子
参数是 compilation
编译完成后触发,这是一个异步串行 AsyncSeriesHook 钩子
参数是 stats
编译失败触发,这是一个同步 SyncHook 钩子
参数是 error
监听模式下,编译无效时触发,这是一个同步 SyncHook 钩子
参数是 fileName,changeTime
+ watchClose
监听模式停止,一个同步 SyncHook 钩子
插件编写实例
webpack-clear-console
通过实例学习是最快的,让我们看一个最简单的例子,webpack-clear-console,这个插件是去除输出里的
console
调用,里面插件的写法是 webpack4 之前的写法,不过基本上是一致的,通过源码可以看到插件在emit
这个钩子上(生成资源到output目录之前)触发,通过compilation
对象的assets
对象的source
方法获取文件内容,然后进行正则匹配。 最后需要将source
和 size 的变动归回原来的compilation
对象中,否则这些变动是不会生效的island-webpack-plugin
island-webpack-plugin 是一个在 bundle 中添加作者信息的插件,这个插件同样是在
emit
这个钩子上触发的,同样是获取source
后对source
添加作者信息的字符串。emit
是一个异步的钩子,可以使用 promise 的 如下,可以使用 promise 对上面的插件进行简单改造,以 island-webpack-plugin 为例,改造如下: