跳至主要內容

Plugin

wzCoding大约 3 分钟综合知识webpack

Plugin

plugin 是 webpack 的另一项核心功能之一,它可以扩展增强 webpack 的功能以使其更加灵活强大,从而可以适应不同的应用场景。

使用 plugin

有两种方式来使用 plugin,以 HtmlWebpackPlugin 为例,它的使用方式如下:

  1. 配置文件:在 webpack.config.js 中配置好要使用的 plugin。即初始化 plugin 实例并传入相应的参数以供 webpack 在打包过程中调用。
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
       // ... 其他配置省略
       plugins: [
          new HtmlWebpackPlugin({ template: './src/index.html' }),
       ],
    };
    
  2. Node API 调用:直接访问 webpack 运行时并通过运行时调用 plugin。即获取打包时的 compiler 对象,通过 compiler 对象运行插件方法。
    const webpack = require('webpack'); // 访问 webpack 运行时(runtime)
    const configuration = require('./webpack.config.js');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    let compiler = webpack(configuration); // 获取 compiler 对象
    
    new webpack.HtmlWebpackPlugin({ template: './src/index.html' }).apply(compiler);
    
    compiler.run(function (err, stats) {
       // ... 处理过程省略
    });
    

编写 plugin

在简单了解了 plugin 的使用方式后,我们将探究如何编写一个 plugin,从而加深对 plugin 的理解。

compiler

compiler 对象是 webpack 在首次启动编译时传递给插件的参数,它是编写插件最常使用的参数之一,它包含了 webpack 打包配置的所有信息(options、loaders、plugins等),compiler 对象是全局唯一的,可以把它看作是 webpack 的实例。

compilation

compilation 对象是 webpack 在重新编译时传递给插件的参数,它也是编写插件最常使用的参数之一,它包含了当前的模块资源、编译生成的资源、发生变化的文件等。在开发模式下,每当 webpack 监听到文件发生变化后,就会重新创建 compilation 对象并重新编译文件。

compiler 与 compilation 的区别在于:compiler 代表了 webpack 从启动打包到退出的完整生命周期,compilation 则表示在 webpack 的生命周期中一次新的编译。

监听事件

webpack 会在打包编译的过程中广播出许多事件,插件可以通过监听这些事件从而加入到 webpack 的打包流程中并完成相应的工作。

//hooksName 可以替换为你想要监听的生命周期钩子函数
//tabAsync 用来注册插件事件,也可以替换成 tapPromise(需要返回一个 promise)

compiler.hooks["hooksName"]["tapAsync"]("myPlugin",function(compilation, callback){
   //...一些处理逻辑
   //在执行完处理逻辑后,需要执行 callback 方法通知 webpack 继续向后执行,否则打包流程会卡在这里
   callback()
})
ℹ️提示

webpack 在打包过程中的事件可以参考 打包过程 这一章节,更加详细的事件请参考 compiler 钩子

plugin 实现

plugin 的本质是一个有 apply() 方法的对象,apply() 方法会接收 compiler 对象作为参数。下面我们将使用上面介绍的知识来实现一个简单的 webpack 插件。

class myPlugin{
   constructor(){}

   apply(compiler){
      compiler.hooks.emit.tabAsync("myPlugin",function(coompilation,callback){
            console.log('这是一个示例插件!');
            console.log('资源的单次构建对象:', compilation);

            // 处理构建过程,例如添加模块
            // 可以从 compilation 对象上获取到 webpack 当前构建过程的所有资源
            compilation.addModule(/* ... */);

            // 调用 Webpack 提供的回调以继续向后执行
            callback();
      })
   }
}
ℹ️提示

更多 compilation 对象的详细请参考 compilation Object