源码太多,边听歌曲边看吧!

理解插件的书写格式:

// 简单插件
class MyPlugin {constructor (options) {console.log(options)}apply (compiler) {compiler.hooks.done.tap('MyPlugin', () => {console.log('构建结束')})}
}
// 复杂插件
class AssetPlugin {constructor(options) {this.options = options;}apply(compiler) {compiler.hooks.compilation.tap('AssetPlugin', (compilation) => {compilation.hooks.chunkAsset.tap('AssetPlugin', (chunk, filename) => {console.log(chunk.name || chunk.id, filename);});});}
}

compiler 对象代表了完整的 webpack 环境配置,这个对象在启动 webpack 时被一次性建立。compilation 对象代表了一次资源版本构建,每次 watch 会重新生成。

compiler.hooks.done.tap 这个怎么来的,我们怎么知道有哪些钩子?

class Compiler {/*** @param {string} context the compilation path*/constructor(context) {this.hooks = Object.freeze({/** @type {SyncHook<[]>} */initialize: new SyncHook([]),/** @type {SyncBailHook<[Compilation], boolean>} */shouldEmit: new SyncBailHook(["compilation"]),/** @type {AsyncSeriesHook<[Stats]>} */done: new AsyncSeriesHook(["stats"]),/** @type {SyncHook<[Stats]>} */afterDone: new SyncHook(["stats"]),/** @type {AsyncSeriesHook<[]>} */additionalPass: new AsyncSeriesHook([]),/** @type {AsyncSeriesHook<[Compiler]>} */beforeRun: new AsyncSeriesHook(["compiler"]),/** @type {AsyncSeriesHook<[Compiler]>} */run: new AsyncSeriesHook(["compiler"]),/** @type {AsyncSeriesHook<[Compilation]>} */emit: new AsyncSeriesHook(["compilation"]),/** @type {AsyncSeriesHook<[string, AssetEmittedInfo]>} */assetEmitted: new AsyncSeriesHook(["file", "info"]),/** @type {AsyncSeriesHook<[Compilation]>} */afterEmit: new AsyncSeriesHook(["compilation"]),/** @type {SyncHook<[Compilation, CompilationParams]>} */thisCompilation: new SyncHook(["compilation", "params"]),/** @type {SyncHook<[Compilation, CompilationParams]>} */compilation: new SyncHook(["compilation", "params"]),/** @type {SyncHook<[NormalModuleFactory]>} */normalModuleFactory: new SyncHook(["normalModuleFactory"]),/** @type {SyncHook<[ContextModuleFactory]>}  */contextModuleFactory: new SyncHook(["contextModuleFactory"]),/** @type {AsyncSeriesHook<[CompilationParams]>} */beforeCompile: new AsyncSeriesHook(["params"]),/** @type {SyncHook<[CompilationParams]>} */compile: new SyncHook(["params"]),/** @type {AsyncParallelHook<[Compilation]>} */make: new AsyncParallelHook(["compilation"]),/** @type {AsyncParallelHook<[Compilation]>} */finishMake: new AsyncSeriesHook(["compilation"]),/** @type {AsyncSeriesHook<[Compilation]>} */afterCompile: new AsyncSeriesHook(["compilation"]),/** @type {AsyncSeriesHook<[Compiler]>} */watchRun: new AsyncSeriesHook(["compiler"]),/** @type {SyncHook<[Error]>} */failed: new SyncHook(["error"]),/** @type {SyncHook<[string | null, number]>} */invalid: new SyncHook(["filename", "changeTime"]),/** @type {SyncHook<[]>} */watchClose: new SyncHook([]),/** @type {AsyncSeriesHook<[]>} */shutdown: new AsyncSeriesHook([]),/** @type {SyncBailHook<[string, string, any[]], true>} */infrastructureLog: new SyncBailHook(["origin", "type", "args"]),// TODO the following hooks are weirdly located here// TODO move them for webpack 5/** @type {SyncHook<[]>} */environment: new SyncHook([]),/** @type {SyncHook<[]>} */afterEnvironment: new SyncHook([]),/** @type {SyncHook<[Compiler]>} */afterPlugins: new SyncHook(["compiler"]),/** @type {SyncHook<[Compiler]>} */afterResolvers: new SyncHook(["compiler"]),/** @type {SyncBailHook<[string, Entry], boolean>} */entryOption: new SyncBailHook(["context", "entry"])});

打开源码看到如此多的钩子,我们看到的 SyncHook 和 SyncBailHook 等等这样的 hook 又来自哪里,这个是 tapable 库里面的。

每当 compiler 开始一次新的构建,创建一个新的 compilation 实例,会触发一次钩子事件,所以必须在 compiler.hooks.compilation.tap 里面拿到 compilation。

class Compilation {createCompilation() {this._cleanupLastCompilation();return (this._lastCompilation = new Compilation(this));}/*** @param {CompilationParams} params the compilation parameters* @returns {Compilation} the created compilation*/newCompilation(params) {const compilation = this.createCompilation();compilation.name = this.name;compilation.records = this.records;this.hooks.thisCompilation.call(compilation, params);this.hooks.compilation.call(compilation, params);return compilation;}

那么 compilation 里面有哪些钩子呢?

class Compilation {this.hooks = Object.freeze({/** @type {SyncHook<[Module]>} */buildModule: new SyncHook(["module"]),/** @type {SyncHook<[Module]>} */rebuildModule: new SyncHook(["module"]),/** @type {SyncHook<[Module, WebpackError]>} */failedModule: new SyncHook(["module", "error"]),/** @type {SyncHook<[Module]>} */succeedModule: new SyncHook(["module"]),/** @type {SyncHook<[Module]>} */stillValidModule: new SyncHook(["module"]),/** @type {SyncHook<[Dependency, EntryOptions]>} */addEntry: new SyncHook(["entry", "options"]),/** @type {SyncHook<[Dependency, EntryOptions, Error]>} */failedEntry: new SyncHook(["entry", "options", "error"]),/** @type {SyncHook<[Dependency, EntryOptions, Module]>} */succeedEntry: new SyncHook(["entry", "options", "module"]),/** @type {SyncWaterfallHook<[(string[] | ReferencedExport)[], Dependency, RuntimeSpec]>} */dependencyReferencedExports: new SyncWaterfallHook(["referencedExports","dependency","runtime"]),/** @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */executeModule: new SyncHook(["options", "context"]),/** @type {AsyncParallelHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */prepareModuleExecution: new AsyncParallelHook(["options", "context"]),/** @type {AsyncSeriesHook<[Iterable<Module>]>} */finishModules: new AsyncSeriesHook(["modules"]),/** @type {AsyncSeriesHook<[Module]>} */finishRebuildingModule: new AsyncSeriesHook(["module"]),/** @type {SyncHook<[]>} */unseal: new SyncHook([]),/** @type {SyncHook<[]>} */seal: new SyncHook([]),/** @type {SyncHook<[]>} */beforeChunks: new SyncHook([]),/** @type {SyncHook<[Iterable<Chunk>]>} */afterChunks: new SyncHook(["chunks"]),/** @type {SyncBailHook<[Iterable<Module>]>} */optimizeDependencies: new SyncBailHook(["modules"]),/** @type {SyncHook<[Iterable<Module>]>} */afterOptimizeDependencies: new SyncHook(["modules"]),/** @type {SyncHook<[]>} */optimize: new SyncHook([]),/** @type {SyncBailHook<[Iterable<Module>]>} */optimizeModules: new SyncBailHook(["modules"]),/** @type {SyncHook<[Iterable<Module>]>} */afterOptimizeModules: new SyncHook(["modules"]),/** @type {SyncBailHook<[Iterable<Chunk>, ChunkGroup[]]>} */optimizeChunks: new SyncBailHook(["chunks", "chunkGroups"]),/** @type {SyncHook<[Iterable<Chunk>, ChunkGroup[]]>} */afterOptimizeChunks: new SyncHook(["chunks", "chunkGroups"]),/** @type {AsyncSeriesHook<[Iterable<Chunk>, Iterable<Module>]>} */optimizeTree: new AsyncSeriesHook(["chunks", "modules"]),/** @type {SyncHook<[Iterable<Chunk>, Iterable<Module>]>} */afterOptimizeTree: new SyncHook(["chunks", "modules"]),/** @type {AsyncSeriesBailHook<[Iterable<Chunk>, Iterable<Module>]>} */optimizeChunkModules: new AsyncSeriesBailHook(["chunks", "modules"]),/** @type {SyncHook<[Iterable<Chunk>, Iterable<Module>]>} */afterOptimizeChunkModules: new SyncHook(["chunks", "modules"]),/** @type {SyncBailHook<[], boolean>} */shouldRecord: new SyncBailHook([]),/** @type {SyncHook<[Chunk, Set<string>, RuntimeRequirementsContext]>} */additionalChunkRuntimeRequirements: new SyncHook(["chunk","runtimeRequirements","context"]),/** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext]>>} */runtimeRequirementInChunk: new HookMap(() => new SyncBailHook(["chunk", "runtimeRequirements", "context"])),/** @type {SyncHook<[Module, Set<string>, RuntimeRequirementsContext]>} */additionalModuleRuntimeRequirements: new SyncHook(["module","runtimeRequirements","context"]),/** @type {HookMap<SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext]>>} */runtimeRequirementInModule: new HookMap(() => new SyncBailHook(["module", "runtimeRequirements", "context"])),/** @type {SyncHook<[Chunk, Set<string>, RuntimeRequirementsContext]>} */additionalTreeRuntimeRequirements: new SyncHook(["chunk","runtimeRequirements","context"]),/** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext]>>} */runtimeRequirementInTree: new HookMap(() => new SyncBailHook(["chunk", "runtimeRequirements", "context"])),/** @type {SyncHook<[RuntimeModule, Chunk]>} */runtimeModule: new SyncHook(["module", "chunk"]),/** @type {SyncHook<[Iterable<Module>, any]>} */reviveModules: new SyncHook(["modules", "records"]),/** @type {SyncHook<[Iterable<Module>]>} */beforeModuleIds: new SyncHook(["modules"]),/** @type {SyncHook<[Iterable<Module>]>} */moduleIds: new SyncHook(["modules"]),/** @type {SyncHook<[Iterable<Module>]>} */optimizeModuleIds: new SyncHook(["modules"]),/** @type {SyncHook<[Iterable<Module>]>} */afterOptimizeModuleIds: new SyncHook(["modules"]),/** @type {SyncHook<[Iterable<Chunk>, any]>} */reviveChunks: new SyncHook(["chunks", "records"]),/** @type {SyncHook<[Iterable<Chunk>]>} */beforeChunkIds: new SyncHook(["chunks"]),/** @type {SyncHook<[Iterable<Chunk>]>} */chunkIds: new SyncHook(["chunks"]),/** @type {SyncHook<[Iterable<Chunk>]>} */optimizeChunkIds: new SyncHook(["chunks"]),/** @type {SyncHook<[Iterable<Chunk>]>} */afterOptimizeChunkIds: new SyncHook(["chunks"]),/** @type {SyncHook<[Iterable<Module>, any]>} */recordModules: new SyncHook(["modules", "records"]),/** @type {SyncHook<[Iterable<Chunk>, any]>} */recordChunks: new SyncHook(["chunks", "records"]),/** @type {SyncHook<[Iterable<Module>]>} */optimizeCodeGeneration: new SyncHook(["modules"]),/** @type {SyncHook<[]>} */beforeModuleHash: new SyncHook([]),/** @type {SyncHook<[]>} */afterModuleHash: new SyncHook([]),/** @type {SyncHook<[]>} */beforeCodeGeneration: new SyncHook([]),/** @type {SyncHook<[]>} */afterCodeGeneration: new SyncHook([]),/** @type {SyncHook<[]>} */beforeRuntimeRequirements: new SyncHook([]),/** @type {SyncHook<[]>} */afterRuntimeRequirements: new SyncHook([]),/** @type {SyncHook<[]>} */beforeHash: new SyncHook([]),/** @type {SyncHook<[Chunk]>} */contentHash: new SyncHook(["chunk"]),/** @type {SyncHook<[]>} */afterHash: new SyncHook([]),/** @type {SyncHook<[any]>} */recordHash: new SyncHook(["records"]),/** @type {SyncHook<[Compilation, any]>} */record: new SyncHook(["compilation", "records"]),/** @type {SyncHook<[]>} */beforeModuleAssets: new SyncHook([]),/** @type {SyncBailHook<[], boolean>} */shouldGenerateChunkAssets: new SyncBailHook([]),/** @type {SyncHook<[]>} */beforeChunkAssets: new SyncHook([]),// TODO webpack 6 remove/** @deprecated */additionalChunkAssets: createProcessAssetsHook("additionalChunkAssets",Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,() => [this.chunks],"DEP_WEBPACK_COMPILATION_ADDITIONAL_CHUNK_ASSETS"),// TODO webpack 6 deprecate/** @deprecated */additionalAssets: createProcessAssetsHook("additionalAssets",Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,() => []),// TODO webpack 6 remove/** @deprecated */optimizeChunkAssets: createProcessAssetsHook("optimizeChunkAssets",Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE,() => [this.chunks],"DEP_WEBPACK_COMPILATION_OPTIMIZE_CHUNK_ASSETS"),// TODO webpack 6 remove/** @deprecated */afterOptimizeChunkAssets: createProcessAssetsHook("afterOptimizeChunkAssets",Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE + 1,() => [this.chunks],"DEP_WEBPACK_COMPILATION_AFTER_OPTIMIZE_CHUNK_ASSETS"),// TODO webpack 6 deprecate/** @deprecated */optimizeAssets: processAssetsHook,// TODO webpack 6 deprecate/** @deprecated */afterOptimizeAssets: afterProcessAssetsHook,processAssets: processAssetsHook,afterProcessAssets: afterProcessAssetsHook,/** @type {AsyncSeriesHook<[CompilationAssets]>} */processAdditionalAssets: new AsyncSeriesHook(["assets"]),/** @type {SyncBailHook<[], boolean>} */needAdditionalSeal: new SyncBailHook([]),/** @type {AsyncSeriesHook<[]>} */afterSeal: new AsyncSeriesHook([]),/** @type {SyncWaterfallHook<[RenderManifestEntry[], RenderManifestOptions]>} */renderManifest: new SyncWaterfallHook(["result", "options"]),/** @type {SyncHook<[Hash]>} */fullHash: new SyncHook(["hash"]),/** @type {SyncHook<[Chunk, Hash, ChunkHashContext]>} */chunkHash: new SyncHook(["chunk", "chunkHash", "ChunkHashContext"]),/** @type {SyncHook<[Module, string]>} */moduleAsset: new SyncHook(["module", "filename"]),/** @type {SyncHook<[Chunk, string]>} */chunkAsset: new SyncHook(["chunk", "filename"]),/** @type {SyncWaterfallHook<[string, object, AssetInfo]>} */assetPath: new SyncWaterfallHook(["path", "options", "assetInfo"]),/** @type {SyncBailHook<[], boolean>} */needAdditionalPass: new SyncBailHook([]),/** @type {SyncHook<[Compiler, string, number]>} */childCompiler: new SyncHook(["childCompiler","compilerName","compilerIndex"]),/** @type {SyncBailHook<[string, LogEntry], true>} */log: new SyncBailHook(["origin", "logEntry"]),/** @type {SyncWaterfallHook<[WebpackError[]]>} */processWarnings: new SyncWaterfallHook(["warnings"]),/** @type {SyncWaterfallHook<[WebpackError[]]>} */processErrors: new SyncWaterfallHook(["errors"]),/** @type {HookMap<SyncHook<[Partial<NormalizedStatsOptions>, CreateStatsOptionsContext]>>} */statsPreset: new HookMap(() => new SyncHook(["options", "context"])),/** @type {SyncHook<[Partial<NormalizedStatsOptions>, CreateStatsOptionsContext]>} */statsNormalize: new SyncHook(["options", "context"]),/** @type {SyncHook<[StatsFactory, NormalizedStatsOptions]>} */statsFactory: new SyncHook(["statsFactory", "options"]),/** @type {SyncHook<[StatsPrinter, NormalizedStatsOptions]>} */statsPrinter: new SyncHook(["statsPrinter", "options"]),get normalModuleLoader() {return getNormalModuleLoader();}});

如何编写wenpack插件相关推荐

  1. 使用Qt编写模块化插件式应用程序

    动态链接库技术使软件工程师们兽血沸腾,它使得应用系统(程序)可以以二进制模块的形式灵活地组建起来.比起源码级别的模块化,二进制级别的模块划分使得各模块更加独立,各模块可以分别编译和链接,模块的升级不会 ...

  2. skywalking原理_Skywalking系列博客6手把手教你编写 Skywalking 插件

    点击上方 IT牧场 ,选择 置顶或者星标技术干货每日送达! 前置知识 在正式进入编写环节之前,建议先花一点时间了解下javaagent(这是JDK 5引入的一个玩意儿,最好了解下其工作原理):另外,S ...

  3. 编写OD插件将IDA中分析出来的函数名导入到OD中

    逆向程序的时候,喜欢用IDA静态分析,用OD动态调试,如果把IDA分析出来的函数名称都导入到OD中,调试的时候就知道哪些函数不需要再看了.以前我一直用GODUP的map loader,但是有些时候感觉 ...

  4. 使用Lua编写whireshark插件

    whireshark支持Lua.C.C++编写的插件 在这里,我简单介绍如何使用Lua编写whireshark插件. 一.插件的存放位置 whireshark插件分为个人插件和全局插件,在window ...

  5. 自己编写jQuery插件之表单验证

    自己编写jQuery插件之表单验证 吐个嘈先:最近状态不咋滴,真是什么都不想干,不想上班,做什么都没动力,觉得没意思.不想这样,不想这样,快让这种情绪消失吧,忽忽.... 表单验证在项目中用的还是比较 ...

  6. 如何编写 Nagios 插件 (http://zener.blog.51cto.com/937811/727685)

    如何编写 Nagios 插件 Nagios 的最激动人心的方面是可以轻松地编写您自己的插件,只需要了解一些简单的指导原则即可.为了管理插件,Nagios 每次在查询一个服务的状态时,产生一个子进程,并 ...

  7. maven插件编写_编写Maven插件的提示

    maven插件编写 最近,我花了很多时间为Maven编写插件或在其中工作. 它们简单,有趣且有趣. 我以为我会分享一些技巧,使编写它们时的生活更轻松. 提示1:将任务与Mojo分开 最初,您将把moj ...

  8. 编写Maven插件的提示

    最近,我花了很多时间来编写或为Maven开发插件. 它们简单,有趣且有趣. 我以为我会分享一些技巧,使他们在编写时变得更轻松. 提示1:将任务与Mojo分开 最初,您将把mojo的所有代码放入mojo ...

  9. 编写Eclipse插件教程–第1部分

    Eclipse是三个最受欢迎的Java开发IDE之一. 其成功的原因之一是其可扩展性. 对于任何知道该怎么做并且已经做到的人来说,编写eclipse插件都可以非常轻松快捷. 不幸的是,第一次在Ecli ...

最新文章

  1. 最小二乘法、迭代优化、坐标轴下降法(Coordinate Descent, CD)、坐标下降和梯度下降对比、梯度下降法/最速下降法
  2. svn文件夹不显示绿色勾的解决方法
  3. pycharm git 超详细教程
  4. 初中计算机学情分析,初中信息技术教学计划
  5. 人工智能免费学习!想了解的进来看看
  6. c语言指针官方解释_C语言中的指针解释了–它们并不像您想象的那么难
  7. codevs——T1048 石子归并
  8. 解决串口数据接收,实际值FF,接收却是FFFFFFFF
  9. uniapp仿照微信朋友圈图片布局
  10. redigo批量lpush/rpush、批量zrem
  11. 我的游记--九色甘南 扎尕那
  12. 【测试】优秀软件测试工程师必备的8个能力
  13. 明解c语言答案第八章,《明解C语言》第1章初识C语言练习题答案(最新整理)
  14. 小程序服务器图片的使用
  15. oracle表给用户授权
  16. 计算Grassmannian geodesic
  17. QT 之 编译错误总结(2)
  18. Linux Shell脚本语句执行失败,后续语句继续执行的问题
  19. 鸿蒙系统与nblot,华为鸿蒙操作系统,和想象中的不一样
  20. php搜索功能实现,PHP 搜索查询功能实现

热门文章

  1. 由浅入深,逐步了解 Java 并发编程中的 Synchronized!
  2. 甲骨文重磅发布:客户现可将自治数据库部署在自己的数据中心
  3. 任正非卸任上海华为董事;百度“云手机”今日线上发布;Inkscape 1.0 RC 版发布 | 极客头条...
  4. 程序员常用的泛型机制究竟怎么玩?
  5. 惊呆了,竟然可以用这种方式秒建 Redis 集群?
  6. 一行 Python 代码能干什么?有意思!
  7. VS Code 必知必会的 20 个快捷键!
  8. 刚在乌镇夺魁的飞桨,又将在“WAVE SUMMIT+”深度学习开发者峰会带来哪些惊喜?...
  9. 这个东西可以温暖你想打BUG的心......
  10. Google 为中国开发者都带来了什么?