diff --git a/packages/next-swc/Cargo.lock b/packages/next-swc/Cargo.lock index c5118602db8ba..dc2609f5bac0c 100644 --- a/packages/next-swc/Cargo.lock +++ b/packages/next-swc/Cargo.lock @@ -2881,8 +2881,9 @@ dependencies = [ [[package]] name = "tracing-chrome" -version = "0.6.0" -source = "git+https://github.com/kwonoj/tracing-chrome?rev=0dd9d6c9e0f74f43993b58560f4ac0103e058df8#0dd9d6c9e0f74f43993b58560f4ac0103e058df8" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb13184244c7cd22758b79e7c993c515ad67a8e730edcb7e05fe7bcabb283c7" dependencies = [ "json", "tracing", diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 268c315debbb5..3400a2238da95 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -112,6 +112,7 @@ import { MiddlewareManifest } from './webpack/plugins/middleware-plugin' import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack' import { recursiveCopy } from '../lib/recursive-copy' import { shouldUseReactRoot } from '../server/config' +import { teardownTraceSubscriber } from './swc' export type SsgRoute = { initialRevalidateSeconds: number | false @@ -2158,6 +2159,7 @@ export default async function build( // Ensure all traces are flushed before finishing the command await flushAllTraces() + teardownTraceSubscriber() return buildResult } diff --git a/packages/next/build/output/store.ts b/packages/next/build/output/store.ts index 4c0af92680308..85998dbbd097c 100644 --- a/packages/next/build/output/store.ts +++ b/packages/next/build/output/store.ts @@ -2,7 +2,7 @@ import createStore from 'next/dist/compiled/unistore' import stripAnsi from 'next/dist/compiled/strip-ansi' import { flushAllTraces } from '../../trace' import { getUnresolvedModuleFromError } from '../utils' - +import { teardownTraceSubscriber } from '../swc' import * as Log from './log' export type OutputState = @@ -100,6 +100,7 @@ store.subscribe((state) => { // Ensure traces are flushed after each compile in development mode flushAllTraces() + teardownTraceSubscriber() return } @@ -126,6 +127,7 @@ store.subscribe((state) => { Log.warn(state.warnings.join('\n\n')) // Ensure traces are flushed after each compile in development mode flushAllTraces() + teardownTraceSubscriber() return } @@ -141,4 +143,5 @@ store.subscribe((state) => { ) // Ensure traces are flushed after each compile in development mode flushAllTraces() + teardownTraceSubscriber() }) diff --git a/packages/next/build/swc/index.d.ts b/packages/next/build/swc/index.d.ts index f291612476522..5dac4bf84d00c 100644 --- a/packages/next/build/swc/index.d.ts +++ b/packages/next/build/swc/index.d.ts @@ -6,3 +6,4 @@ export function minifySync(src: string, options: any): string export function bundle(options: any): Promise export function parse(src: string, options: any): any export function initCustomTraceSubscriber(traceFileName?: string): void +export function teardownTraceSubscriber(): void diff --git a/packages/next/build/swc/index.js b/packages/next/build/swc/index.js index bc15a25ef731c..9f9e041122978 100644 --- a/packages/next/build/swc/index.js +++ b/packages/next/build/swc/index.js @@ -9,6 +9,7 @@ const triples = platformArchTriples[PlatformName][ArchName] || [] let nativeBindings let wasmBindings +let swcTraceFlushGuard async function loadBindings() { let attempts = [] @@ -257,31 +258,39 @@ export function getBinaryMetadata() { /** * Initialize trace subscriber to emit traces. * - * Returns an internal object to guard async flush emission if subscriber is initialized, caller should manually - * tear it down via `teardownTraceSubscriber`. */ export const initCustomTraceSubscriber = (() => { - let guard - return (filename) => { - if (!guard) { + if (!swcTraceFlushGuard) { // Wasm binary doesn't support trace emission let bindings = loadNative() - guard = bindings.initCustomTraceSubscriber(filename) + swcTraceFlushGuard = bindings.initCustomTraceSubscriber(filename) } - - return guard } })() +/** + * Teardown swc's trace subscriber if there's an initialized flush guard exists. + * + * This is workaround to amend behavior with process.exit + * (https://github.com/vercel/next.js/blob/4db8c49cc31e4fc182391fae6903fb5ef4e8c66e/packages/next/bin/next.ts#L134=) + * seems preventing napi's cleanup hook execution (https://github.com/swc-project/swc/blob/main/crates/node/src/util.rs#L48-L51=), + * + * instead parent process manually drops guard when process gets signal to exit. + */ export const teardownTraceSubscriber = (() => { - let bindings - - return (guard) => { - if (!bindings && !!guard) { - // Wasm binary doesn't support trace emission - bindings = loadNative() - return bindings.teardownTraceSubscriber(guard) + let flushed = false + return () => { + if (!flushed) { + flushed = true + try { + let bindings = loadNative() + if (swcTraceFlushGuard) { + bindings.teardownTraceSubscriber(swcTraceFlushGuard) + } + } catch (e) { + // Suppress exceptions, this fn allows to fail to load native bindings + } } } })() diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 8d6699094fb14..f54b512e93236 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -88,22 +88,6 @@ const devtoolRevertWarning = execOnce( let loggedSwcDisabled = false let loggedIgnoredCompilerOptions = false -let swcTraceFlushGuard: unknown = null - -/** - * Teardown swc's trace subscriber if there's an initialized flush guard exists. - * - * This is workaround to amend behavior with process.exit - * (https://github.com/vercel/next.js/blob/4db8c49cc31e4fc182391fae6903fb5ef4e8c66e/packages/next/bin/next.ts#L134=) - * seems preventing napi's cleanup hook execution (https://github.com/swc-project/swc/blob/main/crates/node/src/util.rs#L48-L51=), - * - * instead parent process manually drops guard when process gets signal to exit. - */ -process.on('exit', () => { - if (swcTraceFlushGuard) { - require('./swc')?.teardownTraceSubscriber?.(swcTraceFlushGuard) - } -}) function getOptimizedAliases(): { [pkg: string]: string } { const stubWindowFetch = path.join(__dirname, 'polyfills', 'fetch', 'index.js') @@ -455,16 +439,12 @@ export default async function getBaseWebpackConfig( } const getBabelOrSwcLoader = (isMiddleware: boolean, buildDir: string) => { - if ( - useSWCLoader && - config?.experimental?.swcTraceProfiling && - !swcTraceFlushGuard - ) { + if (useSWCLoader && config?.experimental?.swcTraceProfiling) { // This will init subscribers once only in a single process lifecycle, // even though it can be called multiple times. // Subscriber need to be initialized _before_ any actual swc's call (transform, etcs) // to collect correct trace spans when they are called. - swcTraceFlushGuard = require('./swc')?.initCustomTraceSubscriber?.( + require('./swc')?.initCustomTraceSubscriber?.( path.join( buildDir, config.distDir,