Webpack的自定义Plugin

110 阅读2分钟

0

核心思想:看文档

1. 明确定义

在编写一个插件之前,首先要区分编译器和编译过程

编译器(compiler)

一般是一个对象,表示配置的Webpack环境,在启动的时候就进行构建,包括了选项,加载程序等信息

编译过程(compilation)

代表一次资源的构建过程,每次进行文件更改后都会生成一个新的编译过程,会显示有关模块资源、已编译资 源、已更改⽂件和已监视依赖项的当前状态的信息。

2. 编写方法

不考虑已经过时的原型方法

class No1WebpackPlugin {
  constructor (options) {
    this.options = options
  }
  apply (compiler) {
        complier.hooks.done.tap('HelloWorldPlugin', compilation => {
            console.log('hello world!!!!')
        })
  }
}
module.exports = No1WebpackPlugin;

可以观察到,核心在于编译器所使用的钩子以及其应用的过程

参数

简单来说,用到的参数,就是规定一个用于Webpack编译过程的钩子,文档

  • Hooks类表示的是钩子是哪一种类型的,比如上面用到的done,它就属于AsyncSeriesHook这个类

  • tap、tapAsync、tapPromise这三个方法是用于注入不同类型的自定义构建行为

3.使用

以一个生成文件列表的插件为例

class FilelistPulgin {
    constructor(options) {
        this.options = options
        this.filename = this.options.filename || "filelist.md"
    }
    apply (compiler) {
        compiler.hooks.emit.tapAsync("filelist", (compilation,callback) => {
            const filename = this.filename
            const fileListName = this.filename;
            let len = Object.keys(compilation.assets).length;
            let content = `# 一共有${len}个文件\n\n`;
            for (let filename in compilation.assets) {
                content += `- ${filename}\n`
            }
            compilation.assets[fileListName] = {
                // 7.
                source: function () {
                    return content;
                },
                // 8.
                size: function () {
                    return content.length;
                }
            }
            // 9.
            callback()
        })
    }
}

module.exports = FilelistPulgin

  • 通过compiler.hooks.emit.tapAsync()来触发生成资源到output目录之前的钩子,且回调函数会有两个参数,一个是compilation,一个是callback回调函数

  • 通过compilation.assets获取到所有待生成的文件,这里是获取它的长度

然后再config中编写下面的内容

添加引入const FilelistPulgin = require("./plugins/file-list")

new FilelistPulgin({ filename: "filelist.md" })

npm run build后就可以看到dist目录里出现了一个展示文件列表的md文件