Repository navigation
fix(router-plugin): point split routes' source maps at the route file - #8860
Conversation
Real webpack and Rspack builds, and Vite's dev server: a throw in a split component, and in code it shares, maps to its line in the route file, and the map names the route file rather than its ?tsr-split / ?tsr-shared id. Fails on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Require unplugin ^3.5.0: its webpack/Rspack transform loader dropped a plugin's map when no earlier loader passed one (unjs/unplugin#626). - Name the route file, not the ?tsr-split / ?tsr-shared module id, as the source of split and shared modules' maps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 664878d The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
View your CI Pipeline Execution ↗ for commit 664878d
☁️ Nx Cloud last updated this comment at |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
🚀 Changeset Version Preview4 package(s) bumped directly, 6 bumped as dependents. 🟨 Minor bumps
🟩 Patch bumps
|
Bundle Size Benchmarks
The following scenarios have bundle-size changes compared with the baseline:
Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better. |
…he app runCompiler settled before compiler.close finished, so the test could remove the app while webpack or Rspack was still shutting down, and a close error went unreported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merging this PR will degrade performance by 4.42%2 warnings, 1 note
Performance Changes
Comparing Footnotes
|
#8817's side for the split-out PRs: - #8861 (Start router options): the PR's generator-config, Vite and Rsbuild wiring; main's start-router-wiring test and start-app helper dropped (start-build-options, start-dev-route-tree-footer and start-compose-project-path test the same four behaviours). Main's changeset kept; the duplicated bullets leave start-compiler-yuku.md. - #8860 (split route source maps): the PR's own loader; compilers.ts stays deleted; main's source-maps test dropped (build-source-maps and dev-source-maps test webpack, Rspack and Vite dev). unplugin ^3.5.0 kept from main (no downgrade). Main's changeset kept; the PR's source map clause leaves router-plugin-yuku.md. - #8653 (visible() hooks): merged to the PR's file, test and changeset unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… map-name checks The slice has no test for two behaviours main guards: a webpack or Rspack production build whose configuration has no `mode` ships no splitter warning (#8269), and on webpack and Rspack the maps of a split component and of shared code name the route file, not the `?tsr-split` id (#8860). Keep those cases of main's tests, cut to what the slice does not cover: the `mode: 'production'` rows, the line mapping and Vite's dev server are asserted in the integration tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Source maps of split routes now point at the route file you wrote.
The fix
webpack, Rspack and Rsbuild: the router plugin's map was dropped. unplugin 3.3.0's webpack/Rspack transform loader returns
map == null ? map : res.map || map. The router plugin's loader runs first (enforce: 'pre'), so no earlier loader passes a map in, and our map is thrown away. Later loaders (SWC in Rsbuild) then map against the splitter's output, so a split component maps to the wrong line. Upstream fixed this in unjs/unplugin#626, released in v3.5.0.unpluginnow requires^3.5.0; the lockfile resolves 3.7.0.All bundlers: split and shared modules named their virtual id. The code splitter passed the module id,
index.tsx?tsr-split=component/?tsr-shared=1, as the map'ssourceFileName. It now passes the route file. In Vite dev, devtools used to listindex.tsx?tsr-split=componentbesideindex.tsx. With only the unplugin bump, webpack and Rspack get the right line but list the split chunk's source as a separate./routes/index.js?<hash>entry, so a breakpoint set in the route file doesn't bind there either. Both changes are needed.After the fix, in the tested setups, each map names one source (the route file) and holds its text as written.
Issues
autoCodeSplittingoff, the plugin doesn't transform the file, so no map is lost; that matches the report. Nothing about it is Windows-specific.autoCodeSplittingis enabled #6667 (VS Code breakpoints withautoCodeSplittingon Vite). This fixes the split module's map namingabout.tsx?tsr-split=componentinstead of the route file. VS Code itself wasn't run, so whether breakpoints now bind there, and the reporter'senableContentValidationworkaround, aren't verified.Tests
packages/router-plugin/tests/source-maps.test.tsuses public entry points only (@tanstack/router-plugin/{webpack,rspack,vite}):builtin:swc-loaderafter it, as in Rsbuild): the throw in the split component, and the throw in a function the loader and component share, each map through the emitted.mapto their line inroutes/index.*;/routes/index.tsx, not the?tsr-*id.All 3 fail on main, and each change alone leaves at least one failing (checked separately, including each of the 2
sourceFileNamesites).Validation
@tanstack/router-plugin:test:unit(21 files, 902 passed),test:types,test:eslint,test:buildpass.{react,solid,vue}-router/rspack-basic-file-basedand…-virtual-named-export-config-file-based, all withautoCodeSplitting) pass. The webpack examples ({react,solid}/quickstart-webpack-file-based) build.react-start.rsbuild.*scenarios have the same raw bytes and +7 to +14 B gzip. Only Rspack's numeric module and chunk IDs differ (and, in the IIFE build, the minified names derived from them), because those IDs hash each module's loader request, which contains unplugin's versioned install path. No code changes.@rolldown/pluginutilsdependency and optional@rsbuild/corepeer. pnpm's re-resolution also moved one existing@typescript-eslint/eslint-pluginsnapshot fromignore7.0.5 to 7.0.12; both versions were already in the lockfile, and a no-oppnpm install --no-frozen-lockfileon main doesn't produce it.With #8817
This is one of the small PRs split out of #8817. Merging #8817's head on top conflicts in:
packages/router-plugin/package.json: adjacent lines. Take refactor(compiler)!: replace Babel with a Yuku-based compiler core for Router and Start #8817's side (nochokidar, addyuku) and keep"unplugin": "^3.5.0".packages/router-plugin/src/core/code-splitter/compilers.ts: refactor(compiler)!: replace Babel with a Yuku-based compiler core for Router and Start #8817 deletes it. Delete.pnpm-lock.yaml: take refactor(compiler)!: replace Babel with a Yuku-based compiler core for Router and Start #8817's and runpnpm install --no-frozen-lockfile. Only unplugin moves (3.3.0 → 3.7.0).The new test passes on #8817's head unchanged (webpack, Rspack and Vite). #8817 uses its own webpack/Rspack loader for route modules, so the bump isn't needed for its maps but does no harm.
🤖 Generated with Claude Code
Summary by CodeRabbit