-
Notifications
You must be signed in to change notification settings - Fork 30.4k
Upgrade to swc 54 #88207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade to swc 54 #88207
Conversation
|
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
|
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
Tests Passed |
13b09b2 to
8cfac4c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Suggestion:
Telemetry object must be initialized before installBindings is called so that SWC load failure events can be recorded
View Details
📝 Patch Details
diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts
index 49051f0710..2f70e45b9a 100644
--- a/packages/next/src/build/index.ts
+++ b/packages/next/src/build/index.ts
@@ -950,8 +950,6 @@ export default async function build(
// Reading the config can modify environment variables that influence the bundler selection.
bundler = finalizeBundlerFromConfig(bundler)
nextBuildSpan.setAttribute('bundler', getBundlerForTelemetry(bundler))
- // Install the native bindings early so we can have synchronous access later.
- await installBindings(config.experimental?.useWasmBinary)
process.env.NEXT_DEPLOYMENT_ID = config.deploymentId || ''
NextBuildContext.config = config
@@ -962,6 +960,14 @@ export default async function build(
config.distDir = '.next'
}
const distDir = path.join(dir, config.distDir)
+
+ // Initialize telemetry early so it's available if installBindings fails
+ const telemetry = new Telemetry({ distDir })
+ setGlobal('telemetry', telemetry)
+
+ // Install the native bindings early so we can have synchronous access later.
+ await installBindings(config.experimental?.useWasmBinary)
+
NextBuildContext.distDir = distDir
setGlobal('phase', PHASE_PRODUCTION_BUILD)
setGlobal('distDir', distDir)
@@ -1055,10 +1061,6 @@ export default async function build(
const cacheDir = getCacheDir(distDir)
- const telemetry = new Telemetry({ distDir })
-
- setGlobal('telemetry', telemetry)
-
const publicDir = path.join(dir, 'public')
const { pagesDir, appDir } = findPagesDir(dir)
Analysis
Problem
The test "Telemetry CLI > production mode > emits event when swc fails to load" was failing because the NEXT_SWC_LOAD_FAILURE telemetry event was not being emitted when SWC failed to load.
Root Cause
In packages/next/src/build/index.ts, the telemetry object was being initialized AFTER installBindings() was called:
- Line ~952:
await installBindings(config.experimental?.useWasmBinary)was called - Line ~1058: Telemetry was initialized with
const telemetry = new Telemetry({ distDir })
When installBindings() failed and called logLoadFailure() → eventSwcLoadFailure(), the telemetry object retrieved from traceGlobals.get('telemetry') was undefined. The eventSwcLoadFailure() function contains an early return check: if (!telemetry) return, so no event was recorded.
Solution Implemented
Moved the telemetry initialization to occur BEFORE installBindings() is called:
- Moved the
distDircalculation forward (it was needed as a parameter for Telemetry initialization) - Added telemetry initialization immediately after distDir calculation
- Moved
installBindings()call to after telemetry is initialized - Removed the duplicate telemetry initialization that was at the original location
Code Changes
In packages/next/src/build/index.ts:
- Line 961:
const distDir = path.join(dir, config.distDir)(existing, just positioned earlier) - Line 964-966: Added telemetry initialization:
const telemetry = new Telemetry({ distDir }) setGlobal('telemetry', telemetry)
- Line 968:
await installBindings(config.experimental?.useWasmBinary)(moved after telemetry init) - Removed duplicate telemetry initialization that was previously at line ~1058
Why This Works
Now when SWC fails to load with NODE_OPTIONS='--no-addons':
installBindings()callsloadBindings()which failsloadFailure()is called which callsawait eventSwcLoadFailure()eventSwcLoadFailure()now finds the telemetry object in traceGlobals- The event is recorded and flushed with
await telemetry.flush() - With NEXT_TELEMETRY_DEBUG=1, the event is printed to stderr
- The test can successfully find "NEXT_SWC_LOAD_FAILURE" in stderr
Testing
The fix was verified by:
- Confirming telemetry is initialized before installBindings
- Confirming there are no duplicate telemetry initializations
- Confirming setGlobal('telemetry', telemetry) is called
- Tracing through the execution flow to confirm the event will be recorded
Stats from current PR✅ No significant changes detected📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles: **430 kB** → **430 kB** ✅ -3 B82 files with content-based hashes (individual files not comparable between builds) Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
|
8cfac4c to
8e6eb98
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Suggestion:
Telemetry object must be initialized before installBindings is called so that SWC load failure events can be recorded
View Details
📝 Patch Details
diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts
index 49051f0710..2f70e45b9a 100644
--- a/packages/next/src/build/index.ts
+++ b/packages/next/src/build/index.ts
@@ -950,8 +950,6 @@ export default async function build(
// Reading the config can modify environment variables that influence the bundler selection.
bundler = finalizeBundlerFromConfig(bundler)
nextBuildSpan.setAttribute('bundler', getBundlerForTelemetry(bundler))
- // Install the native bindings early so we can have synchronous access later.
- await installBindings(config.experimental?.useWasmBinary)
process.env.NEXT_DEPLOYMENT_ID = config.deploymentId || ''
NextBuildContext.config = config
@@ -962,6 +960,14 @@ export default async function build(
config.distDir = '.next'
}
const distDir = path.join(dir, config.distDir)
+
+ // Initialize telemetry early so it's available if installBindings fails
+ const telemetry = new Telemetry({ distDir })
+ setGlobal('telemetry', telemetry)
+
+ // Install the native bindings early so we can have synchronous access later.
+ await installBindings(config.experimental?.useWasmBinary)
+
NextBuildContext.distDir = distDir
setGlobal('phase', PHASE_PRODUCTION_BUILD)
setGlobal('distDir', distDir)
@@ -1055,10 +1061,6 @@ export default async function build(
const cacheDir = getCacheDir(distDir)
- const telemetry = new Telemetry({ distDir })
-
- setGlobal('telemetry', telemetry)
-
const publicDir = path.join(dir, 'public')
const { pagesDir, appDir } = findPagesDir(dir)
Analysis
Problem
The test "Telemetry CLI > production mode > emits event when swc fails to load" was failing because the NEXT_SWC_LOAD_FAILURE telemetry event was not being emitted when SWC failed to load.
Root Cause
In packages/next/src/build/index.ts, the telemetry object was being initialized AFTER installBindings() was called:
- Line ~952:
await installBindings(config.experimental?.useWasmBinary)was called - Line ~1058: Telemetry was initialized with
const telemetry = new Telemetry({ distDir })
When installBindings() failed and called logLoadFailure() → eventSwcLoadFailure(), the telemetry object retrieved from traceGlobals.get('telemetry') was undefined. The eventSwcLoadFailure() function contains an early return check: if (!telemetry) return, so no event was recorded.
Solution Implemented
Moved the telemetry initialization to occur BEFORE installBindings() is called:
- Moved the
distDircalculation forward (it was needed as a parameter for Telemetry initialization) - Added telemetry initialization immediately after distDir calculation
- Moved
installBindings()call to after telemetry is initialized - Removed the duplicate telemetry initialization that was at the original location
Code Changes
In packages/next/src/build/index.ts:
- Line 961:
const distDir = path.join(dir, config.distDir)(existing, just positioned earlier) - Line 964-966: Added telemetry initialization:
const telemetry = new Telemetry({ distDir }) setGlobal('telemetry', telemetry)
- Line 968:
await installBindings(config.experimental?.useWasmBinary)(moved after telemetry init) - Removed duplicate telemetry initialization that was previously at line ~1058
Why This Works
Now when SWC fails to load with NODE_OPTIONS='--no-addons':
installBindings()callsloadBindings()which failsloadFailure()is called which callsawait eventSwcLoadFailure()eventSwcLoadFailure()now finds the telemetry object in traceGlobals- The event is recorded and flushed with
await telemetry.flush() - With NEXT_TELEMETRY_DEBUG=1, the event is printed to stderr
- The test can successfully find "NEXT_SWC_LOAD_FAILURE" in stderr
Testing
The fix was verified by:
- Confirming telemetry is initialized before installBindings
- Confirming there are no duplicate telemetry initializations
- Confirming setGlobal('telemetry', telemetry) is called
- Tracing through the execution flow to confirm the event will be recorded
Merging this PR will not alter performanceSummary
Comparing Footnotes
|

Somewhat surprisingly, no breaking API changes
swc-project/swc@v1.15.5...v1.15.8 tracks the changes