Skip to content

vite: Vue flavor fails to build under rolldown and HMR breaks with a symlinked nativescript-vue #11429

Description

@rigor789

Two independent problems in @nativescript/vite 8.0.8 (Vite 8.3.0, rolldown) found while verifying nativescript-vue 3.1.1 with Vite. Repro project: nativescript-vue/nativescript-vue#1160 (demo-vite/, the blank Vue template scaffolded with ns create plus npx nativescript-vite init).

1. vue alias via @rollup/plugin-alias fails under rolldown

configuration/vue.ts aliases vue to nativescript-vue through @rollup/plugin-alias (enforce: 'pre'). With Vite 8 / rolldown the bare replacement resolves to the package directory and every build fails on the from "vue" import that @vitejs/plugin-vue injects into each SFC:

[UNLOADABLE_DEPENDENCY] Could not load node_modules/nativescript-vue
   src/components/Home.vue?vue&type=script&setup=true&lang.ts:1:53
 1 │ import { defineComponent as _defineComponent } from "vue";
   │                                                     ╰──── Is a directory (os error 21)

Ruled out: an exports map in nativescript-vue and the dedupe entry in base.ts change nothing. Setting the same alias through Vite's own resolve.alias works, whether the replacement is the bare name, the package directory or the entry file. The set-value entry in the same plugin is already covered by resolve.alias in base.ts.

2. HMR dev session: a symlinked nativescript-vue gets the /ns/rt bridge injected into itself

With "nativescript-vue": "file:../path" (a symlink under node_modules), ns debug ios boots into:

Dynamic import error: TypeError: _defineComponent is not a function
    at http://<host>:5173/ns/asm?mode=inline&path=%2Fsrc%2Fcomponents%2FDetails.vue:90:27
[ns-entry] deterministic dev session bootstrap failed

Cause, traced through the served modules:

  • /ns/m/node_modules/nativescript-vue is classified with classifyServedModule(resolvedCandidate || spec) (hmr/server/websocket-ns-m.ts). The resolved candidate of a symlinked package is its real path, which contains no node_modules/, so the module is treated as app source and processCodeForDevice runs the app-only passes on it. The served vendor module then starts with import { $navigateTo, $navigateBack } from "/ns/rt";.
  • /ns/rt binds every export at evaluation time through __ensure(), which reads nativescript-vue from the device-side vendor registry. Imported by nativescript-vue itself, the bridge evaluates before that registry entry exists, __ensure() caches {} (__cached_rt = rt runs even when vm is null) and never retries, so every binding, including defineComponent, is undefined.

Installing the same package as a packed tarball (a real directory under node_modules) makes the served module clean and the app boots. Verified by fetching /ns/m/node_modules/nativescript-vue from the dev server in both setups.

Suggested fixes, PRs incoming:

  • classify a served module as library code when either the request spec or the resolved candidate is under node_modules/;
  • do not cache a miss in __ensure(), and warn once when the vendor module is not registered yet, so the failure is diagnosable instead of surfacing as "X is not a function".

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions