Commit e0cad28
committed
fix: Windows path bugs across build/server/dev/native paths
Static audit of every `path.*` / `await import()` / `JSON.stringify(path)` /
chokidar / regex-anchored-on-`/` site surfaced a class of Windows-only bugs
where native-separator producers feed POSIX-expecting consumers. Same defect
class as #640 / commit 61302c5 (closed PR #695). Each fix is at the producer.
packages/one — seed bug + audit follow-ups:
- cli/build.ts mints serverJsPath via path.join (native sep). Downstream
oneServe.ts runs .includes('${outDir}/server') (forward-slash literal);
the check misses on Windows, the prefix is prepended a second time, and
`dist\server\dist\server\...` is passed to await import() — production
SSR returns 200 but loaderData is undefined. Fix at producer with
posix.join: build.ts:616 (builtMiddlewares), :1031 (serverJsPath),
oneServe.ts:320 (apiFile). The regex at build.ts:1366 and the literal
replace at vercel/build/generate/createSsrServerlessFunction.ts:130
start matching on Windows for free.
- utils/toServerOutputPath.ts (new): idempotent prefix-or-keep helper for
the symmetric oneServe.ts call sites (lines 168 and 334). posix.join +
startsWith with a trailing slash; backslash-input boundary conversion;
no false-positive on substrings. 7 unit tests.
- vite/plugins/virtualEntryPlugin.ts:97: pathToFileURL().href for the
setupFile import specifier. JSON.stringify of a Windows-backslash absolute
path is not a canonical ESM specifier shape. Mirrors the createNativeDevEngine
fix below. Direct repro is currently blocked by an unrelated rolldown
rust panic on Windows; this is preventive correctness.
- vite/plugins/fileSystemRouterPlugin.tsx:559: posix.join for
optimizeDeps.entries (tinyglobby needs forward-slash patterns). Also
dropped the hardcoded './app' for routerRoot — pre-existing bug for
users with router.root or ONE_ROUTER_ROOT overrides.
- metro-config/getViteMetroPluginOptions.ts:244,264: normalizePath on
path.relative results inlined by babel into metro-entry.js. ONE_SETUP_FILE_NATIVE
truly needs forward-slash on Windows (Metro's isRelativeImport regex
rejects `..\foo`); ONE_ROUTER_APP_ROOT_RELATIVE_TO_ENTRY is hygiene.
- cli/build.ts:559,566: posix.join in rolldown chunkFileNames/assetFileNames.
Latent for flat chunks; diverges for nested API routes.
- cli/build.ts:1480: normalizePath on wranglerInputConfig.main. Latent
today (relative() returns bare filename); preventive against future
source-layout changes.
- cli/buildPage.ts:67: clientJsPath was minted via join(clientDir, ...)
→ backslash on Windows. Currently only used by readFile (accepts both),
but stored in dist/buildInfo.json with backslashes — cross-platform
manifest hygiene fix matching serverJsPath. normalizePath wrap.
- vite/one.ts:255: SSR symlink-dedup compares Vite's POSIX resolved.id
against native realpathSync(nmPkgDir) on Windows; startsWith misses
and dedup never fires for pnpm symlinks (allows duplicate React copies
in SSR bundle). normalizePath both sides. Only active when
ssr.dedupeSymlinkedModules: true (opt-in).
packages/compiler:
- transformSWC.ts:14: ignoreId regex used native path.sep (`\\` on Windows)
but Vite plugin context hands the function a POSIX id on every platform,
so the regex never matched on Windows — Vite-internal `.vite/deps/...`
files got pushed through full SWC parse-and-transform instead of being
short-circuited. Performance regression, not functional break. The
function's other caller (vxrn/utils/patches.ts:274) hands native paths.
Fix: POSIX-only regex (`/node_modules\/(\.vite|vite)\//`) plus normalize
id once at the top of transformSWC so both callers agree on the format.
Also fixes an HMR cache-key inconsistency in the same line — `id.replace
(process.cwd(), '')` no longer no-ops on Windows when called from the
Vite plugin path.
packages/vxrn:
- utils/getVitePath.ts:81: normalizePath(id) before endsWith('/react/...')
sentinel. realpath returns native on Windows. Function has no in-tree
caller; preventive for external consumers.
- exports/dev.ts:148-157: normalize chokidar's native path and process.cwd()
before stripping; viteServer.transformRequest expects POSIX URLs. Also
collapsed the dual `'/dist/' || '\\dist\\'` check. Vite-native HMR codepath
(Metro HMR uses its own pipeline, unaffected).
- utils/createNativeDevEngine.ts:568,587: normalizePath() for the rolldown
module id; pathToFileURL().href for the JSON.stringify-embedded setupFile
import specifier.
packages/vite-plugin-metro:
- plugins/expoManifestRequestHandlerPlugin.ts:36: resolve(server.config.root)
for the Vite→Metro/Expo boundary. Commit 61302c5 applied the same fix at
metroPlugin.ts:88; this sibling boundary was missed.
Test-only fixes (cross-platform hygiene):
- vite/plugins/sourceInspectorPlugin.ts: normalizePath wrap on
resolveEditorFilePath output; mirrors sibling getSourceInspectorPath.
Production behavior unchanged.
- packages/resolve/src/index.test.ts: construct expected paths via
path.join (resolvePath returns native paths in production).
- packages/vxrn/src/utils/patches.test.ts: symlink type 'dir' → 'junction'.
Per Node fs docs the type arg is ignored on POSIX; on Windows junctions
don't require Administrator. Single codepath. 4 fail → 8/8 pass.
- packages/vxrn/src/plugins/serverExtensions.test.ts: source was refactored
from FSExtra.pathExists to node:fs.existsSync without updating mocks; two
config-extension tests also called plugin.config() with zero args while
source destructures { command } from arg 2. Switch to vi.mock('node:fs',
factory) (ESM module-namespace exports aren't spy-able) and pass the
required SERVE_HOOK_OPTS. 4 fail → 7/7 pass on every platform.
- packages/vxrn/package.json: add `"test": "vitest run --dir src"` script
so turbo picks vxrn up in `bun run test` and CI now runs the 33 vxrn
cases. Previously vxrn was typecheck-only on CI, which is how the
serverExtensions stale mocks and patches.test EPERM sat broken without
anyone noticing. Mirrors @vxrn/resolve.
End-to-end verified on Windows host: SSR loaders return real data; web HMR
fires; APK builds via Gradle; native HMR fires on Android emulator (Metro
bundler). Cross-platform tests identical on Windows and Linux Docker
(402 packages/one + 9 packages/resolve + 33 packages/vxrn/src + 20 helper/
posix tests, 0 fail).
Vite-native bundler (`native.bundler: 'vite'`) still crashes on Windows
with an unrelated rolldown rust panic (`crates/fft/src/hparser/convert.rs:120`);
the createNativeDevEngine + dev.ts fixes target that codepath but cannot
be directly exercised until rolldown ships a fix.1 parent a677174 commit e0cad28
23 files changed
Lines changed: 303 additions & 62 deletions
File tree
- packages
- compiler/src
- one
- src
- cli
- metro-config
- server
- utils
- vite
- plugins
- types/utils
- resolve/src
- vite-plugin-metro/src/plugins
- vxrn
- src
- exports
- plugins
- utils
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
15 | 18 | | |
16 | 19 | | |
17 | 20 | | |
18 | 21 | | |
19 | 22 | | |
20 | 23 | | |
21 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
22 | 28 | | |
23 | 29 | | |
24 | 30 | | |
25 | 31 | | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
282 | 282 | | |
283 | 283 | | |
284 | 284 | | |
285 | | - | |
| 285 | + | |
286 | 286 | | |
287 | 287 | | |
288 | 288 | | |
| |||
547 | 547 | | |
548 | 548 | | |
549 | 549 | | |
550 | | - | |
| 550 | + | |
| 551 | + | |
551 | 552 | | |
552 | 553 | | |
553 | 554 | | |
554 | 555 | | |
555 | 556 | | |
556 | 557 | | |
557 | | - | |
| 558 | + | |
558 | 559 | | |
559 | 560 | | |
560 | 561 | | |
| |||
601 | 602 | | |
602 | 603 | | |
603 | 604 | | |
604 | | - | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
605 | 611 | | |
606 | 612 | | |
607 | 613 | | |
| |||
1008 | 1014 | | |
1009 | 1015 | | |
1010 | 1016 | | |
1011 | | - | |
| 1017 | + | |
| 1018 | + | |
1012 | 1019 | | |
1013 | 1020 | | |
1014 | 1021 | | |
| |||
1452 | 1459 | | |
1453 | 1460 | | |
1454 | 1461 | | |
1455 | | - | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
1456 | 1466 | | |
1457 | 1467 | | |
1458 | 1468 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
64 | 65 | | |
65 | 66 | | |
66 | 67 | | |
| 68 | + | |
67 | 69 | | |
68 | | - | |
| 70 | + | |
69 | 71 | | |
70 | 72 | | |
71 | 73 | | |
| |||
Lines changed: 13 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
232 | 233 | | |
233 | 234 | | |
234 | 235 | | |
235 | | - | |
236 | | - | |
237 | | - | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
238 | 243 | | |
239 | 244 | | |
240 | 245 | | |
| |||
247 | 252 | | |
248 | 253 | | |
249 | 254 | | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
254 | 260 | | |
255 | 261 | | |
256 | 262 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
164 | 165 | | |
165 | 166 | | |
166 | 167 | | |
167 | | - | |
168 | | - | |
169 | | - | |
| 168 | + | |
170 | 169 | | |
171 | 170 | | |
172 | 171 | | |
| |||
314 | 313 | | |
315 | 314 | | |
316 | 315 | | |
317 | | - | |
| 316 | + | |
| 317 | + | |
318 | 318 | | |
319 | 319 | | |
320 | 320 | | |
| |||
328 | 328 | | |
329 | 329 | | |
330 | 330 | | |
331 | | - | |
332 | | - | |
333 | | - | |
| 331 | + | |
334 | 332 | | |
335 | 333 | | |
336 | 334 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
0 commit comments