Skip to content

fix(vite): support Vite 8 / Rolldown#11259

Open
JumpLink wants to merge 1 commit into
NativeScript:mainfrom
JumpLink:fix/vite-8-rolldown-compat
Open

fix(vite): support Vite 8 / Rolldown#11259
JumpLink wants to merge 1 commit into
NativeScript:mainfrom
JumpLink:fix/vite-8-rolldown-compat

Conversation

@JumpLink
Copy link
Copy Markdown

@JumpLink JumpLink commented Jun 4, 2026

What

Makes @nativescript/vite build under Vite 8, which swaps the bundler from Rollup to Rolldown. No behavior change on Vite ≤ 7 / webpack / rspack or the existing flavors.

Why it breaks on Vite 8 / Rolldown

Rolldown reimplements several Vite-internal plugins in Rust, changing two contracts:

  1. resolve.alias function replacements are rejected. Rolldown's native ViteAlias plugin only accepts string replacements and throws: Failed to convert builtin plugin 'ViteAlias' … function replacement into rust type String.
  2. The explicit @rollup/plugin-commonjs crashes. The bundled commonjs({...}) instance throws Cannot read properties of undefined (reading 'currentLoadingModule') under Rolldown. Rolldown transforms CommonJS natively, so the plugin is redundant there.

Fixes

1. Remove function-replacement resolve.alias entries (configuration/base.ts, helpers/ts-config-paths.ts):

  • @nativescript/core/(.+)/index becomes a plain string replacement (${NS_CORE_ROOT}/$1) — identical result.
  • The redundant packagePlatformAliases(...) alias is dropped: its package.json main + platform-variant lookup is already performed by the nativescriptPackageResolver resolveId plugin in the same config. The now-unused helper file is removed.
  • The tsconfig wildcard paths mapping moves out of a function-replacement alias into a new resolveId plugin, tsConfigPathsResolverPlugin. The fs-based platform-specific (.android/.ios) and directory-index resolution is preserved byte-for-byte in a shared helper. Exact (non-wildcard) tsconfig path aliases are unchanged.

2. Skip the explicit @rollup/plugin-commonjs on Vite 8 / Rolldown (configuration/base.ts):

  • Gated on Vite's reported major version (>= 8). Vite ≤ 7 keeps the plugin exactly as before; on Vite 8 / Rolldown it is omitted and Rolldown's native CJS handling takes over.

Verification

Validated empirically: a real @nativescript/canvas app (a three.js teapot) that fails to build on Vite 8.0.16 builds successfully (612 modules → working bundle, ns run android launches and renders on the emulator) once these fixes are applied. The change set was developed + proven via an independent implementation of the same two fixes before being applied here; the source changes are minimal and backward-compatible. Full-monorepo tsc/build is left to CI.

Backward compatibility

  • Only FIX 2 (the commonjs gate) is version-conditional, keyed on version from vite (also true for the rolldown-vite override). Vite ≤ 7 keeps the exact existing plugin pipeline.
  • FIX 1 is unconditional and behavior-equivalent on both Rollup and Rolldown.
  • build.commonjsOptions and @rollup/plugin-replace are untouched.

Note

helpers/prelink-angular.ts still contains a function-replacement alias, but createAngularPrelinkPlugin is currently dead code (not imported anywhere — configuration/angular.ts uses angularLinkerVitePlugin), so it does not affect a Vite 8 build today. Left untouched per minimal scope; flagging in case it is ever wired up.

Vite 8 swaps the bundler from Rollup to Rolldown, which changes two
contracts the NativeScript Vite config relies on:

1. Rolldown's native ViteAlias plugin rejects function `resolve.alias`
   replacements ("Failed to convert builtin plugin 'ViteAlias' ...
   function replacement into rust type String").
2. The explicit @rollup/plugin-commonjs instance crashes under Rolldown
   ("Cannot read properties of undefined (reading 'currentLoadingModule')").
   Rolldown transforms CommonJS natively, so it is redundant there.

Fixes:
- Convert the @nativescript/core/.../index alias to a string replacement
  (identical result) and drop the redundant packagePlatformAliases function
  alias (its package main + platform-variant lookup is already done by the
  nativescriptPackageResolver resolveId plugin); remove the now-unused helper.
- Move the tsconfig wildcard paths mapping out of a function-replacement alias
  into a new tsConfigPathsResolverPlugin resolveId hook, preserving the
  fs-based platform-specific and directory-index resolution byte-for-byte.
- Skip the explicit @rollup/plugin-commonjs only on Vite 8 / Rolldown
  (gated on the reported Vite major version); Vite <= 7 / webpack / rspack
  keep the exact existing pipeline.

No behavior change on Vite <= 7 / webpack / rspack or the existing flavors.
@NathanWalker
Copy link
Copy Markdown
Contributor

Excellent @JumpLink, I'll work on mapping this into https://github.com/NativeScript/NativeScript/tree/feat/vite-improvements-with-version-8-hmr which has some really nice hmr additions (with new runtime features upcoming with 9.1) so maybe this can release sooner while 9.1 is still being prepared.

@NathanWalker NathanWalker self-assigned this Jun 4, 2026
JumpLink added a commit to gjsify/gjsify that referenced this pull request Jun 5, 2026
* docs(nativescript): track upstream PRs #11259 + #6056

Add an "Upstream PRs in flight (NativeScript)" tracker to STATUS.md Open TODOs
listing both PRs we filed — NativeScript/NativeScript#11259 (Vite 8 / Rolldown
support) and NativeScript/nativescript-cli#6056 (copy the vite bundle to native
in non-watch builds) — with each PR's link, our interim workaround, and what to
drop once it merges + ships. Link the watch-mode-copy TODO to #6056.

* docs(nativescript): correct CLA note on upstream PRs

Neither NativeScript repo requires a CLA (verified: no CLA in CONTRIBUTING, no
CLA check on either PR). #11259's only extra gate is FOSSA license-compliance
(passing); both PRs are auto-reviewed by CodeRabbit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants