rsnext/packages/next/build/webpack/plugins/profiling-plugin.ts

57 lines
1.7 KiB
TypeScript
Raw Normal View History

import { tracer } from '../../tracer'
import { webpack, isWebpack5 } from 'next/dist/compiled/webpack/webpack'
const pluginName = 'ProfilingPlugin'
export const spans = new WeakMap()
function getNormalModuleLoaderHook(compilation: any) {
if (isWebpack5) {
// @ts-ignore TODO: Remove ignore when webpack 5 is stable
return webpack.NormalModule.getCompilationHooks(compilation).loader
}
return compilation.hooks.normalModuleLoader
}
export class ProfilingPlugin {
apply(compiler: any) {
// Only enabled when instrumentation is loaded
const currentSpan = tracer.getCurrentSpan()
if (!currentSpan || !currentSpan.isRecording()) {
return
}
compiler.hooks.compile.tap(pluginName, () => {
const span = tracer.startSpan('webpack-compile', {
attributes: { name: compiler.name },
})
spans.set(compiler, span)
})
compiler.hooks.done.tap(pluginName, () => {
spans.get(compiler).end()
})
compiler.hooks.compilation.tap(pluginName, (compilation: any) => {
compilation.hooks.buildModule.tap(pluginName, (module: any) => {
tracer.withSpan(spans.get(compiler), () => {
const span = tracer.startSpan('build-module')
span.setAttribute('name', module.userRequest)
spans.set(module, span)
})
})
getNormalModuleLoaderHook(compilation).tap(
pluginName,
(loaderContext: any, module: any) => {
const parentSpan = spans.get(module)
loaderContext.currentTraceSpan = parentSpan
}
)
compilation.hooks.succeedModule.tap(pluginName, (module: any) => {
spans.get(module).end()
})
})
}
}