Skip to content

fix(build): resolve non-hoisted SWC helpers#1994

Open
NathanDrake2406 wants to merge 1 commit into
cloudflare:mainfrom
NathanDrake2406:nathan/fix-non-hoisted-swc-helpers
Open

fix(build): resolve non-hoisted SWC helpers#1994
NathanDrake2406 wants to merge 1 commit into
cloudflare:mainfrom
NathanDrake2406:nathan/fix-non-hoisted-swc-helpers

Conversation

@NathanDrake2406

Copy link
Copy Markdown
Contributor

Overview

Field Details
goal Match Next.js when server-side page code requires @swc/helpers without an app-root helper install.
core change Add a Vite alias for @swc/helpers/_ to a concrete installed helper package, including pnpm virtual-store layouts.
boundary Pages Router production build and deploy-suite fixtures that do not hoist SWC helpers.
primary files packages/vinext/src/index.ts, tests/pages-router.test.ts, scripts/e2e-deploy.sh
expected impact Existing Next.js apps no longer need @swc/helpers visible from their root node_modules for server page builds.

Why

Next.js treats SWC helpers as framework-owned build/runtime helpers, not app-root dependencies. Its server externalization explicitly keeps @swc/helpers bundled, and its compiler aliases @swc/helpers/_ to an installed helper copy. Vinext already bundles server deps, but without the alias Vite/Rolldown resolved require('@swc/helpers/_/_object_spread') from the page file and failed when the helper was not hoisted.

Area Principle / invariant What this PR changes
Server module resolution Framework helpers should not require app-root hoisting. Resolves the helper package from direct app installs, nested Next installs, pnpm virtual-store installs, or vinext context.
Next.js parity Preserve upstream observable behaviour. Ports the upstream handle-non-hoisted-swc-helpers Pages Router fixture into vinext coverage.
Deploy-suite adapter The custom adapter owns throwaway fixture installation. Removes non-pnpm packageManager metadata in temp apps and calls the linked vinext binary directly after install.

What changed

Scenario Before After
getServerSideProps requires @swc/helpers/_/_object_spread and helpers are not app-hoisted Production build fails during module resolution. Build succeeds and the page renders hello world.
Upstream npm-specific deploy fixture under vinext deploy adapter pnpm refuses the fixture packageManager, or pnpm exec rechecks deps after init mutations. Adapter install proceeds and the upstream file reaches the original assertion.
Maintainer review path
  1. packages/vinext/src/index.ts: review resolveSwcHelpersUnderscoreDir() and the @swc/helpers/_ alias wiring.
  2. tests/pages-router.test.ts: review the ported fixture and assertion against the upstream Pages Router test.
  3. scripts/e2e-deploy.sh: review the temp manifest package-manager normalization and direct node_modules/.bin/vinext calls.
Validation
  • vp test run tests/pages-router.test.ts -t "non-hoisted SWC helpers"
  • vp env exec --node 24 ./scripts/run-nextjs-deploy-suite.sh /Users/nathan/Projects/vinext/.refs/nextjs-v16.2.6 --retries 0 -c 1 --debug test/e2e/handle-non-hoisted-swc-helpers/index.test.ts
  • vp fmt --check packages/vinext/src/index.ts tests/pages-router.test.ts
  • vp check packages/vinext/src/index.ts tests/pages-router.test.ts
  • bash -n scripts/e2e-deploy.sh
  • pre-commit hook: vp check --fix, full check, staged unit/integration tests, knip
Risk / compatibility
  • Public API: none.
  • Runtime: only affects resolving @swc/helpers/_... specifiers that would otherwise fail or depend on hoisting.
  • Package managers: supports npm-style direct/nested installs and pnpm virtual-store installs.
  • Deploy-suite: package-manager normalization is limited to throwaway Next.js test apps created by the custom adapter.

References

Reference Why it matters
Next.js upstream test Defines the expected observable behaviour.
Next.js server externalization Shows @swc/helpers should not be externalized because hoisting cannot be relied on.
Next.js compiler alias Shows the @swc/helpers/_ alias this PR mirrors for Vite.

@pkg-pr-new

pkg-pr-new Bot commented Jun 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@1994
npm i https://pkg.pr.new/vinext@1994

commit: f791f43

Pages Router builds failed when server-side page code required @swc/helpers and the package was not visible from the app root node_modules. Next.js does not rely on that hoisting; it aliases @swc/helpers/_ to an installed helper copy and bundles the helper.

Resolve the helper package from the app, nested Next install, pnpm virtual store, or vinext package context, then add the equivalent Vite alias. Adjust the deploy-suite adapter to run npm-declared throwaway fixtures through its pnpm-owned install path and direct vinext binary calls so the upstream fixture reaches the runtime assertion.

Regression coverage ports the upstream handle-non-hoisted-swc-helpers fixture and verifies the original upstream deploy-suite file.
@NathanDrake2406 NathanDrake2406 force-pushed the nathan/fix-non-hoisted-swc-helpers branch from 80acf77 to f791f43 Compare June 13, 2026 06:09
@NathanDrake2406 NathanDrake2406 marked this pull request as ready for review June 13, 2026 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant