Plugin
Plugin
plugin 是 webpack 的另一项核心功能之一,它可以扩展增强 webpack 的功能以使其更加灵活强大,从而可以适应不同的应用场景。
使用 plugin
有两种方式来使用 plugin,以 HtmlWebpackPlugin
为例,它的使用方式如下:
- 配置文件:在
webpack.config.js
中配置好要使用的 plugin。即初始化 plugin 实例并传入相应的参数以供 webpack 在打包过程中调用。const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { // ... 其他配置省略 plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), ], };
- 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