Skip to content

fix(vite): serve pnpm-isolated transitive deps over /ns/m - #11475

Merged
NathanWalker merged 2 commits into
NativeScript:mainfrom
aleclarson:fix/vite-ns-m-pnpm-isolated-transitive-deps
Sep 29, 2026
Merged

NathanWalker merged 2 commits into
NativeScript:mainfrom
aleclarson:fix/vite-ns-m-pnpm-isolated-transitive-deps

Conversation

@aleclarson

Copy link
Copy Markdown
Contributor

PR Checklist

What is the current behavior?

Under pnpm's nodeLinker: isolated, a workspace package's own dependency lives in that package's private node_modules (e.g. packages/gif/node_modules/@nativescript-community/ui-image), not under the app root or the hoisted workspace root. Three compounding gaps make such deps unserveable over /ns/m:

  1. resolveCandidateFilePath only probes projectRoot and workspaceRoot, so the file lookup misses → 404.
  2. resolveVendorRouting sends plugin-patterned package entries (e.g. ui-image's index.ios.js main) down the vendor: route even when the package isn't in the vendor manifest — the sync require then resolves to the missing-module stub instead of falling back to HTTP serving.
  3. createNsMRequestContext's candidate list never probes platform-suffixed files (index.ios.js), so a plugin's main: './index' entry can't resolve at all in per-module serving.

On device: HTTP import failed / network error during dev-session boot. Repro with a real package set: any pnpm-isolated monorepo where an app imports a workspace package whose dependency is a NativeScript plugin.

What is the new behavior?

  • resolveCandidateFilePath gains a cached, best-effort fallback that probes every workspace package's node_modules for the <pkg>/<sub> tail of the URL (the importer is dropped by the URL form, so first-hit wins — pnpm guarantees the dep lives under exactly one package's private dir).
  • resolveVendorRouting only takes the vendor: route for plugin-patterned packages when the package actually exists in the active vendor manifest; otherwise it falls through to the per-module HTTP path. A null manifest (early boot) keeps the legacy behavior.
  • createNsMRequestContext expands candidates with the active platform's suffixes (ios/android/visionos/native) before the unsuffixed variants — existence-filtered downstream, so probing is safe.

Fixes #11470.

Testing note

Added resolveCandidateFilePath specs covering the pnpm-isolated hit, root priority, and the miss path. Verified end-to-end as a pnpm patch on 8.0.11: an app whose dev boot previously died on @nativescript-community/ui-image now serves the full module graph. Minimal standalone repro: https://github.com/aleclarson/repro/tree/nativescript-11470

@nx-cloud

nx-cloud Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit e2f49d3

Command Status Duration Result
nx test apps-automated -c=android ✅ Succeeded 3m 36s View ↗
nx run-many --target=test --configuration=ci --... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-09-29 21:31:12 UTC

@pkg-pr-new

pkg-pr-new Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@nativescript/core@11475
npm i https://pkg.pr.new/@nativescript/vite@11475
npm i https://pkg.pr.new/@nativescript/webpack@11475

commit: e2f49d3

- guard the workspace fallback against escaping its node_modules dir
- probe pnpm's hoisted virtual store for deps of published packages
- probe only the active platform suffix so iOS never picks .android.js
- fix the spec's unterminated string literals
- drop the resolveVendorRouting change duplicated from NativeScript#11459
@NathanWalker
NathanWalker merged commit 9c8d317 into NativeScript:main Sep 29, 2026
7 checks passed
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.

vite: /ns/m dev server 404s on pnpm-isolated transitive dependencies

2 participants