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

 

图片[1]-通过 Webpack 的 compiler 对象的 Hooks 学会编写 Webpack 插件的编写-技术鸭(jishuya.cn)

 

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 对象中,否则这些变动是不会生效的

图片[2]-通过 Webpack 的 compiler 对象的 Hooks 学会编写 Webpack 插件的编写-技术鸭(jishuya.cn)

 

 

island-webpack-plugin

island-webpack-plugin 是一个在 bundle 中添加作者信息的插件,这个插件同样是在 emit 这个钩子上触发的,同样是获取 source 后对 source 添加作者信息的字符串。
data-canonical-src=https://upload-images.jianshu.io/upload_images/1641380-931e030193e6decb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

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
© 版权声明
THE END
喜欢就支持一下吧
点赞392 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容