profiling-plugin.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.webpackInvalidSpans = exports.spans = void 0;
  6. var _webpack = require("next/dist/compiled/webpack/webpack");
  7. const pluginName = "ProfilingPlugin";
  8. const spans = new WeakMap();
  9. exports.spans = spans;
  10. const moduleSpansByCompilation = new WeakMap();
  11. const webpackInvalidSpans = new WeakMap();
  12. exports.webpackInvalidSpans = webpackInvalidSpans;
  13. class ProfilingPlugin {
  14. constructor({ runWebpackSpan }){
  15. this.runWebpackSpan = runWebpackSpan;
  16. }
  17. apply(compiler) {
  18. this.traceTopLevelHooks(compiler);
  19. this.traceCompilationHooks(compiler);
  20. this.compiler = compiler;
  21. }
  22. traceHookPair(spanName, startHook, stopHook, { parentSpan , attrs , onStart , onStop } = {}) {
  23. let span;
  24. startHook.tap({
  25. name: pluginName,
  26. stage: -Infinity
  27. }, (...params)=>{
  28. const name = typeof spanName === "function" ? spanName() : spanName;
  29. const attributes = attrs ? attrs(...params) : attrs;
  30. span = parentSpan ? parentSpan().traceChild(name, attributes) : this.runWebpackSpan.traceChild(name, attributes);
  31. if (onStart) onStart(span, ...params);
  32. });
  33. stopHook.tap({
  34. name: pluginName,
  35. stage: Infinity
  36. }, ()=>{
  37. // `stopHook` may be triggered when `startHook` has not in cases
  38. // where `stopHook` is used as the terminating event for more
  39. // than one pair of hooks.
  40. if (!span) {
  41. return;
  42. }
  43. if (onStop) onStop();
  44. span.stop();
  45. });
  46. }
  47. traceTopLevelHooks(compiler) {
  48. this.traceHookPair("webpack-compilation", compiler.hooks.compilation, compiler.hooks.afterCompile, {
  49. parentSpan: ()=>webpackInvalidSpans.get(compiler) || this.runWebpackSpan,
  50. attrs: ()=>({
  51. name: compiler.name
  52. }),
  53. onStart: (span, compilation)=>{
  54. spans.set(compilation, span);
  55. spans.set(compiler, span);
  56. moduleSpansByCompilation.set(compilation, new WeakMap());
  57. }
  58. });
  59. if (compiler.options.mode === "development") {
  60. this.traceHookPair(()=>`webpack-invalidated-${compiler.name}`, compiler.hooks.invalid, compiler.hooks.done, {
  61. onStart: (span)=>webpackInvalidSpans.set(compiler, span),
  62. onStop: ()=>webpackInvalidSpans.delete(compiler),
  63. attrs: (fileName)=>({
  64. trigger: fileName || "manual"
  65. })
  66. });
  67. }
  68. }
  69. traceCompilationHooks(compiler) {
  70. this.traceHookPair("emit", compiler.hooks.emit, compiler.hooks.afterEmit, {
  71. parentSpan: ()=>webpackInvalidSpans.get(compiler) || this.runWebpackSpan
  72. });
  73. this.traceHookPair("make", compiler.hooks.make, compiler.hooks.finishMake, {
  74. parentSpan: ()=>webpackInvalidSpans.get(compiler) || this.runWebpackSpan
  75. });
  76. compiler.hooks.compilation.tap(pluginName, (compilation)=>{
  77. compilation.hooks.buildModule.tap(pluginName, (module)=>{
  78. var ref;
  79. const compilationSpan = spans.get(compilation);
  80. if (!compilationSpan) {
  81. return;
  82. }
  83. const moduleType = (()=>{
  84. if (!module.userRequest) {
  85. return "";
  86. }
  87. return module.userRequest.split(".").pop();
  88. })();
  89. const issuerModule = compilation == null ? void 0 : (ref = compilation.moduleGraph) == null ? void 0 : ref.getIssuer(module);
  90. let span;
  91. const moduleSpans = moduleSpansByCompilation.get(compilation);
  92. const spanName = `build-module${moduleType ? `-${moduleType}` : ""}`;
  93. const issuerSpan = issuerModule && (moduleSpans == null ? void 0 : moduleSpans.get(issuerModule));
  94. if (issuerSpan) {
  95. span = issuerSpan.traceChild(spanName);
  96. } else {
  97. span = compilationSpan.traceChild(spanName);
  98. }
  99. span.setAttribute("name", module.userRequest);
  100. moduleSpans.set(module, span);
  101. });
  102. const moduleHooks = _webpack.NormalModule.getCompilationHooks(compilation);
  103. // @ts-ignore TODO: remove ignore when using webpack 5 types
  104. moduleHooks.readResource.for(undefined).intercept({
  105. register (tapInfo) {
  106. const fn = tapInfo.fn;
  107. tapInfo.fn = (loaderContext, callback)=>{
  108. const moduleSpan = loaderContext.currentTraceSpan.traceChild(`read-resource`);
  109. fn(loaderContext, (err, result)=>{
  110. moduleSpan.stop();
  111. callback(err, result);
  112. });
  113. };
  114. return tapInfo;
  115. }
  116. });
  117. moduleHooks.loader.tap(pluginName, (loaderContext, module)=>{
  118. var ref;
  119. const moduleSpan = (ref = moduleSpansByCompilation.get(compilation)) == null ? void 0 : ref.get(module);
  120. loaderContext.currentTraceSpan = moduleSpan;
  121. });
  122. compilation.hooks.succeedModule.tap(pluginName, (module)=>{
  123. var ref, ref1;
  124. (ref1 = (ref = moduleSpansByCompilation == null ? void 0 : moduleSpansByCompilation.get(compilation)) == null ? void 0 : ref.get(module)) == null ? void 0 : ref1.stop();
  125. });
  126. this.traceHookPair("webpack-compilation-seal", compilation.hooks.seal, compilation.hooks.afterSeal, {
  127. parentSpan: ()=>spans.get(compilation)
  128. });
  129. compilation.hooks.addEntry.tap(pluginName, (entry)=>{
  130. const compilationSpan = spans.get(compilation);
  131. if (!compilationSpan) {
  132. return;
  133. }
  134. const addEntrySpan = compilationSpan.traceChild("add-entry");
  135. addEntrySpan.setAttribute("request", entry.request);
  136. spans.set(entry, addEntrySpan);
  137. });
  138. compilation.hooks.succeedEntry.tap(pluginName, (entry)=>{
  139. var ref;
  140. (ref = spans.get(entry)) == null ? void 0 : ref.stop();
  141. });
  142. this.traceHookPair("webpack-compilation-chunk-graph", compilation.hooks.beforeChunks, compilation.hooks.afterChunks, {
  143. parentSpan: ()=>spans.get(compilation) || spans.get(compiler)
  144. });
  145. this.traceHookPair("webpack-compilation-optimize", compilation.hooks.optimize, compilation.hooks.reviveModules, {
  146. parentSpan: ()=>spans.get(compilation) || spans.get(compiler)
  147. });
  148. this.traceHookPair("webpack-compilation-optimize-modules", compilation.hooks.optimizeModules, compilation.hooks.afterOptimizeModules, {
  149. parentSpan: ()=>spans.get(compilation) || spans.get(compiler)
  150. });
  151. this.traceHookPair("webpack-compilation-optimize-chunks", compilation.hooks.optimizeChunks, compilation.hooks.afterOptimizeChunks, {
  152. parentSpan: ()=>spans.get(compilation) || spans.get(compiler)
  153. });
  154. this.traceHookPair("webpack-compilation-optimize-tree", compilation.hooks.optimizeTree, compilation.hooks.afterOptimizeTree, {
  155. parentSpan: ()=>spans.get(compilation) || spans.get(compiler)
  156. });
  157. this.traceHookPair("webpack-compilation-hash", compilation.hooks.beforeHash, compilation.hooks.afterHash, {
  158. parentSpan: ()=>spans.get(compilation) || spans.get(compiler)
  159. });
  160. });
  161. }
  162. }
  163. exports.ProfilingPlugin = ProfilingPlugin;
  164. //# sourceMappingURL=profiling-plugin.js.map