如何写一个webpack plugin,帮你升职加薪
我们经常使用到webpack的插件功能,那如何开发一个自定义的插件呢?首先创建插件比创建 loader 更加高级,webpack 插件由以下组成:
- 一个 JavaScript 命名函数。
- 在插件函数的 prototype 上定义一个 apply 方法。
- 指定一个绑定到 webpack 自身的事件钩子。
- 处理 webpack 内部实例的特定数据。
- 功能完成后调用 webpack 提供的回调。
下面就一点点的带你开发一个自定义的webpack plugin.
先说说webpack插件中的两位重要人物,Compiler和Compliation
- compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。
- compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。
基础插件架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ///src/plugins/helloPlugin.js // 命名函数。 function HelloPlugin(options) { // 使用 options 设置插件实例…… console.log(options); } //插件函数的 prototype 上定义一个 apply 方法 HelloPlugin.prototype.apply = compiler => { //hooks compiler.hooks.done.tap( 'HelloPlugin' , status => { console.log(status.toJson()); }) // 旧版本的相关钩子 //compiler.plugin('done' , () => { // console.log('hello world'); //}) // 设置回调来访问 compilation 对象: //compiler.plugin('compilation', compilation => { // 现在,设置回调来访问 compilation 中的步骤: // compilation.plugin('optimize', () => { console.log( 'optimize' ); //}) //}) } module.exports = HelloPlugin |
1 2 3 4 5 6 | //webpack.config.js const HelloPlugin = require( './src/plugins/helloPlugin' ) plugins: [ new HelloPlugin({options: true }) ] |
这样基础架构就搭建完成了.
认识一下事件钩子
生命周期钩子函数,是由 compiler 暴露,可以通过如下方式访问:
1 | compiler.hooks.someHook.tap(...) |
取决于不同的钩子类型,也可以在某些钩子上访问 tapAsync 和 tapPromise。
例如
1 2 3 4 | // 在处理来自webpack选项的entry配置后调用 compiler.hooks.entryOption.tap( 'HelloPlugin' , (context, entry) => { console.log(1,context, entry); }) |
也支持自定义钩子函数
1 2 3 4 5 6 7 | // 自定义hook const SyncHook = require( 'tapable' ).SyncHook; // 具有 `apply` 方法…… if (compiler.hooks.myCustomHook) throw new Error( 'Already in use' ); compiler.hooks.myCustomHook = new SyncHook([ 'a' , 'b' , 'c' ]) // 在你想要触发钩子的位置/时机下调用…… compiler.hooks.myCustomHook.call(a, b, c); |
学会了webpack的事件生命周期钩子函数,那么下面我们就开始着手写一个webpack插件.
生成一个展示打包完成后的文件列表,ok,直接上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // 命名函数。 function HelloPlugin(options) { // 使用 options 设置插件实例…… console.log(options); } //插件函数的 prototype 上定义一个 apply 方法 HelloPlugin.prototype.apply = compiler => { // 在将资产释放到输出目录后调用。 compiler.hooks.emit.tapAsync( 'HelloPlugin' , (compilation, callback) => { let fileList = ` ## in this build:\n\n` console.log(compilation.assets); const assets = compilation.assets for ( let key in assets){ console.log(key); fileList+=`${key}\n` } compilation.assets[ 'fileList.md' ] = { source:()=>{ return fileList}, size:() => { return fileList.length} } callback() }) } module.exports = HelloPlugin |
看,根据不同的webpack生命周期事件钩子函数,处理不同的逻辑,就可以完成一个webpack的plugin了,你学会了吗?
关于深入学习请参考:
如果觉得文章不错,可以给小编发个红包给予鼓励.
你要觉得这篇文章比较好,记得点推荐!
标签:
工程化工具
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通