refactor: migrate path handling from node:path to pathslash#2502
Open
shulaoda wants to merge 17 commits into
Open
refactor: migrate path handling from node:path to pathslash#2502shulaoda wants to merge 17 commits into
shulaoda wants to merge 17 commits into
Conversation
commit: |
Contributor
Performance benchmarksCompared 0 improved · 0 regressed · 6 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
6aa72cf to
b8670c7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Migrates all of
packages/vinext/src(~100 files) fromnode:pathtopathslash, in eight batch commits:refactor:CLI cluster (typegen, check, cli, init, init-cloudflare, utils/project) + thepathslashdependency via pnpm catalogrefactor(routing):app-route-graph, pages-router, file-matcher, app-router + thevi.mockrewriterefactor(plugins):13 plugin filesrefactor(server):11 server filesrefactor(build):15 build filesrefactor(core):entries, config, and shared utils (18 files)refactor(plugin):index.ts (the Vite plugin heart, ~25 normalization sites)refactor:endgame — test-suite sweep totoSlash, stragglers,no-restricted-importslint guardFollow-up commits address CI findings (bundled-dependency output layout, Windows-only fixture gating) and track
main: the prerender path-discovery feature (#2481) landed mid-review and is migrated inrefactor: migrate upstream prerender path discovery to pathslash.Why
The forward-slash invariant used to live in JSDoc prose ("
rootmust be forward-slash — callers normalize it at their entry…") and had to be restated and hand-maintained at every hop, which produced a five-week, 50+-commit whack-a-mole campaign — and stragglers still kept surfacing.pathslashturns that convention into an API guarantee: it delegates every operation to the realnode:path(drive letters, per-drive cwd, case-insensitiverelativekeep native semantics) and only converts Windows output separators to/. Once a module imports it, everyjoin/resolve/relative/dirnameresult is canonical forward-slash by construction, so the per-function contracts, thepath.posix.*rewrites, and thenormalizePathSeparators(...)wrappers all disappear from migrated code. Notably,pathslash.relativebakes in the rule #2308 learned the hard way: relativize natively, then normalize the output.How
pathslashis a devDependency, bundled intodistvia the samedeps.alwaysBundlemechanism asam-i-vibing— it is a ~90-line zero-dependency wrapper, so end users never download it (single shared module in the emitted graph, nothing added to the install footprint).dist/deps/...instead of the defaultdist/node_modules/...mirror (outputOptions.entryFileNames/chunkFileNamesrename).build/standalone.tsprunes every path containing anode_modulessegment when assembling standalone output, so an inlined dep that the server statically imports (pathslash viaprod-server) would otherwise go missing at standalone-server boot — a latent trapam-i-vibing/process-ancestryhad only dodged because nothing in the server graph imports them.import path from "node:path"→import path from "pathslash";path.posix.*→path.*;normalizePathSeparators(path.X(...))→ barepath.X(...).toSlashmarks the boundaries where external-origin strings enter the canonical space:process.cwd(),config.root,fileURLToPath,require.resolve,realpathSync.native, node's glob output, and Rolldown/Vite ids reported with native separators (resolveIdimporter-joined virtual ids,watchChange). Everything in between needs no normalization at all..replaceAll("\\", "/")fallbacks. Tests that feed Windows-shaped fixtures (chunk-classification ids, V8 stack frames) are gated withit.runIf(process.platform === "win32")with their assertions left unconditional; seetests/build-optimization.test.ts,tests/dev-stack-sourcemap.test.ts.normalizePathSeparatorsremoved fromutils/path.ts(kept:isWindows,stripViteModuleQuery,stripJsExtension); the test suite's 39 wrap sites moved totoSlashfrompathslash.no-restricted-importsbansnode:pathinpackages/vinext/src— the durable replacement for prose contracts. The convention (pathslash in source,node:pathinputs +toSlash-wrapped expectations in tests, when to usetoSlash, how to opt a file out) is documented inAGENTS.mdunder Code Style.build/standalone.ts(native-space tree copier, inline lint-disable),server/app-ssr-entry.ts(dynamicimport("node:path")in a runtime React fallback where a package dependency would change bundling), URL-space backslash defenses (prod-server,image-optimization,index.tsredirect sanitizing),init-cloudflare.tsgenerated-config literals, and the tsconfig-extendsclassifier that must accept user-authored backslash paths.tests/app-route-graph.test.ts's Windows-simulation mock now mockspathslashitself (substituting the cross-platformwin32flavor), so POSIX CI exercises the real conversion instead of a no-op helper.appDir(computeLayoutTreePositions), chokidar watcher add/unlink route invalidation never matching on Windows (index.ts), and the fonts cached-CSS rewrite that silently no-opped on Windows.Testing
vp check(format + lint + types) green throughout; every batch committed only after its verification gate.toSlashwraps — inputs deliberately stay nativenode:pathso Windows runs keep exercising the conversion.:/*), the pinned performance-benchmarks environment, and a handful of load-flaky dev-server tests (verified green in isolation).HEADbaseline worktree on the same machine before being treated as a regression.