Fix anonymous class expression names for serialization classes#991
Conversation
🦋 Changeset detectedLatest commit: 8d57648 The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (41 failed)turso (41 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
✅ 📋 Other
|
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 25 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 50 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.all with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Promise.race with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
|
When upstream bundlers like tsup/esbuild transform class declarations into anonymous class expressions (e.g. `var Foo = class { ... }`), the SWC plugin now re-inserts the binding name into the class expression (e.g. `var Foo = class Foo { ... }`). This preserves the class `.name` property through subsequent bundling passes, preventing runtime failures in downstream bundlers like Nitro's Rollup bundler that rely on the class expression name for serialization class registration.
bf954f2 to
ae4f598
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the @workflow/swc-plugin transform to preserve class names for serializable classes when upstream bundlers convert named class declarations into anonymous class expressions, preventing downstream bundlers from losing the class identifier during subsequent bundling passes.
Changes:
- Update the SWC transform to re-insert the variable binding name into anonymous
classexpressions when custom serialization methods are present. - Update transform fixture outputs to reflect the newly named class expressions.
- Document the behavior in
spec.mdand publish a patch changeset.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/swc-plugin-workflow/transform/src/lib.rs | Implements binding-name re-insertion for anonymous serializable class expressions. |
| packages/swc-plugin-workflow/transform/tests/fixture/class-expression-binding-name/output-workflow.js | Updates expected workflow-mode fixture output to include class Shell. |
| packages/swc-plugin-workflow/transform/tests/fixture/class-expression-binding-name/output-step.js | Updates expected step-mode fixture output to include class Shell. |
| packages/swc-plugin-workflow/transform/tests/fixture/class-expression-binding-name/output-client.js | Updates expected client-mode fixture output to include class Shell. |
| packages/swc-plugin-workflow/spec.md | Documents the anonymous class expression name re-insertion behavior. |
| .changeset/happy-doodles-return.md | Adds a patch changeset for the plugin release. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pranaygp
left a comment
There was a problem hiding this comment.
Looks good. Clean, well-scoped fix.
The guard conditions (has_serde && class_expr.ident.is_none()) correctly ensure this only fires for anonymous serialization classes, leaving named class expressions (like class _Bash) untouched. Test fixtures and spec updated appropriately.
…recompute internal_class_name after ident insertion

When upstream bundlers like tsup/esbuild transform class declarations into anonymous class expressions (e.g.
var Foo = class { ... }), the SWC plugin now re-inserts the binding name into the class expression (e.g.var Foo = class Foo { ... }). This preserves the class.nameproperty through subsequent bundling passes, preventing runtime failures in downstream bundlers like Nitro's Rollup bundler that rely on the class expression name for serialization class registration.