通过 Webpack 的 compiler 对象的 Hooks 学会编写 Webpack 插件的编写

发布于 2022-08-24 10:46:16 字数 6013 浏览 121 评论 0

webpack 的 Hooks

Webpack 的 Compiler 对象主要有以下 Hooks:

  • entryOption

webpack 处理完 entry 配置项后触发,这是一个同步串行的 SyncBailHook 钩子,只要监听函数有一个函数的返回值不为undefined,则直接跳过剩下逻辑

无参数

  • afterPlugins

处理完初始化插件后触发,这是一个同步的 SyncHook 钩子,不关心返回值

参数是 compiler 对象

  • afterResolvers

Resolve 安装完成后触发,这是一个同步的 SyncHook 钩子

参数是 compiler 对象

  • environment

environment 准备好后触发,这是一个 SyncHook 钩子

无参数

  • afterEnvironment

environment 安装完成后触发,这是一个 SyncHook 钩子

  • beforeRun

compiler.run 函数之前触发,这是一个异步串行 AsyncSeriesHook 钩子

参数是 compiler

  • run

开始读取 records 之前触发,这是一个异步串行 AsyncSeriesHook 钩子

参数是 compiler

  • watchRun

监听模式下,一个新的编译开始之前触发,这是一个异步串行的 AsyncSeriesHook 钩子

参数是 compiler

  • normalModuleFactory

normalModuleFactory 创建之后触发,这是一个同步 SyncHook 钩子

参数是 normalModuleFactory

  • contextModuleFactory

contextModuleFactory 创建之后触发,

参数是 contextModuleFactory

  • beforeCompile

编译参数创建之后触发,这是一个异步串行 AsyncSeriesHook 钩子

参数是 compilationParams

  • compile

一个新的编译创建之后触发,这是一个同步 SyncHook 钩子

参数是 compilationParams

  • thisCompilation

触发 compilation 之前触发,这个是一个同步 SyncHook 钩子

参数是 compilation

  • compilation

编译创建之后执行,这是一个同步 SyncHook 钩子

参数是 compilation

  • make

这是一个异步并发 AsyncParallelBailHook 钩子

参数是 compilation

  • afterCompile

这是一个异步串行 AsyncSeriesHook 钩子

参数是 compilation

  • shouldEmit

这是一个 SyncBailHook 钩子

参数是 compilation

  • emit

生成资源到 output 目录之前触发,这是一个异步串行 AsyncSeriesHook 钩子

参数是 compilation

  • afterEmit

生成资源到 output 目录之后,这是一个异步串行 AsyncSeriesHook 钩子

参数是 compilation

  • done

编译完成后触发,这是一个异步串行 AsyncSeriesHook 钩子

参数是 stats

  • failed

编译失败触发,这是一个同步 SyncHook 钩子

参数是 error

  • invalid

监听模式下,编译无效时触发,这是一个同步 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 为例,改造如下:

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('nn  ')}n*/n${source}`
                    }

                    compilation.assets[e].source = () => source
                    compilation.assets[e].size = () => source.size
                })
                resolve()
            })
        })
    }
}

module.exports = AuthorPlugin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

貪欢

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文