Repository navigation
fix(router-plugin): omit browser warnings from production bundles - #8269
Conversation
|
View your CI Pipeline Execution ↗ for commit 96d73b8
☁️ Nx Cloud last updated this comment at |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
🚀 Changeset Version Preview9 package(s) bumped directly, 2 bumped as dependents. 🟨 Minor bumps
🟩 Patch bumps
|
Bundle Size BenchmarksThis pull request does not affect bundle size in any measured scenario. |
Merging this PR will not alter performance1 warning
Comparing Footnotes
|
# Conflicts: # packages/router-plugin/tests/router-plugin-context.test.ts
🦋 Changeset detectedLatest commit: 96d73b8 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 |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the page The code splitter always passes isProduction, so the NODE_ENV fallback in the compiler was reachable only from direct test calls. The changeset now names the bug users see. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o splitter warning Builds an app whose route exports its component, with mode 'production' and with mode left out, and checks that no emitted JS names the app's absolute path. Fails on main. Replaces the fake-compiler matrix in router-plugin-context.test.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Through the compiler-test-utils harness, failing on #8817 (f90a6e5): - Rsbuild dev compresses responses when the app leaves server.compress unset (#8863). - A Vite root given relative or through a symbolic link misses a Start library hoisted above the app: its server fn runs uncompiled in SSR (#8866). - An Rsbuild root of '.' fails the build (#8868). - A webpack or Rspack configuration without mode builds the client with route HMR code ($$tsrRefreshId with absolute paths) (#8269). The Start build harness gains an app inside a temporary monorepo (workspace) and the bundler root as the app configures it (root). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main c156097: #8858, #8863, #8805, #8269, #8866, #8867, #8868, #8869, #8870, #8871, #8876, #8888, #8889, #8890, #8892, Version Packages (#8854, #8891) and docs. - #8817's side and deletions throughout (Babel compilers, start-compiler, add-hmr, start-app.ts, server-fn-id-check.ts, router-utils ast.ts). The lines main changed for #8863, #8866, #8868, #8269 and #8889/#8892 stay #8817's here: their fixes follow as separate commits after the tests that reproduce them. - @rsbuild/core 2.3.1 (#8890) in the catalog, the examples and benchmarks/compiler-perf; Start's peers keep #8817's ^2.2.13 floor. Lockfile and e2e/react-start/basic's route tree regenerated. - Tests: main's start-vite-root, start-rsbuild-root, rsbuild server-compress and router-plugin production-warnings tests are replaced by their ports in the harness (start-build-roots, dev-server-config, production-bundle); main's start-dev-restart test is ported to the dev-server harness and replaces resolve-entries.test.ts (internals). #8817's Rsbuild SPA dev case gives way to main's spa-shell e2e. The route HMR `hot` binding test gains main's unsplit case (#8870). - KNOWN-BUGS: main fixed decorators after `export` (#8867) and the Rsbuild sibling-route manifest (#8780, #8876). - Changesets: drop what main ships now (custom server-fn ids, the Rsbuild manifest and SPA/compress items, exsolve, Vue store pre-bundling, falsy `use` entries, `.ts` route HMR). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ilds for production The plugin reads `compiler.options.mode` when it is applied, before webpack and Rspack fill in their default (`production`): a configuration without `mode` compiled in dev mode, and the client bundle shipped route HMR code with the route files' absolute paths. Treat a missing mode as production, as main does (#8269). 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>
🎯 Changes
The bug
webpack buildwithNODE_ENVunset ships the code splitter's development warning in the client bundle. It's a top-levelconsole.warn("[tanstack-router] These exports from \"/abs/path/src/routes/x.tsx\" will not be code-split …"). It runs on every page load and leaks the absolute path of the route file on the build machine.It happens when a route exports a component that would otherwise be split, and another option of that route is still split. It happens with the repo's webpack example and with the config in
docs/router/installation/with-webpack.md.Cause: the compiler read
process.env.NODE_ENVat compile time to decide whether to inject the warning. webpack-cli setsNODE_ENVonly with--node-env, and webpack only defines it inside the bundle. The Rspack and webpack Node APIs don't set it either. Vite, Rsbuild and the Rspack CLI setNODE_ENV=productionbefore building, so their CLI builds were clean.Fix
isProduction), and it now passes it to the compiler. The compiler injects the warning only when it isn't production. TheNODE_ENVread is gone: the plugin always passes the flag, so aNODE_ENVfallback could only be reached by direct test calls.modecounts as production. Both bundlers apply the plugins before they fill in defaults, socompiler.options.modeis stillundefinedat that point. Then they build in production (mode || 'production', and webpack prints "webpack will fallback to 'production'"). Before this change, a config withoutmodealso got route HMR and the React Refresh transforms. In a production build those are dead code.Scope:
@tanstack/router-pluginonly. Vite builds already decide bycommand === 'build'. The one visible change there is thatNODE_ENV=development vite buildno longer injects the warning. esbuild has no mode and is unchanged.Tests
packages/router-plugin/tests/production-warnings.test.tsruns real webpack and Rspack builds through the publictanstackRouterplugin, followingsource-maps.test.ts. The app has a route that exports its component and splits itserrorComponent. It builds withmode: 'production'and withmodeleft out. The checks:Vitest sets
NODE_ENV=test, which behaves like an unsetNODE_ENVhere.main, all 4 cases fail.isProductionpass-through, the 2 "mode left out" cases fail.These replace the fake-compiler matrix that the first version added to
router-plugin-context.test.ts.Validation
pnpm format.Nx,
@tanstack/router-plugin:test:unit,test:types,test:eslint,test:buildpass. Nx,@tanstack/start-plugin-core:test:unitpasses.examples/react/quickstart-webpack-file-based, built with webpack 5.97.1 and webpack-cli 5.1.4,NODE_ENVunset (env -i), with an extra route that exports its component:webpack build(example config,mode: 'production')mode--mode production--mode development(control)Bundle size: all 18 scenarios are unchanged (gzip, raw and brotli all +0) against
mainat01fab5a6c8.Relation to #8817
#8817 deletes
compilers.tsandrouter-code-splitter-plugin.ts. Merging #8817 on top of this PR gives 2 new conflicts, both modify/delete on those files. The resolution is to take #8817's deletion. The changeset and the new test merge cleanly.On #8817's head, the new test passes for
mode: 'production'. It fails formodeleft out: #8817's webpack/Rspack host treats a missingmodeas dev, so its production bundle ships$$tsrRefreshIdstrings with absolute paths. A one-line change in #8817'ssrc/hosts/webpack.tsmakes all 4 cases pass:(compiler.options.mode ?? 'production') === 'production'. This was tried locally and not pushed.Credits
Original fix and analysis by LadyBluenotes (
a1014f5015). The follow-up commits mergemain, remove theNODE_ENVfallback, rewrite the changeset, and replace the test with real builds.✅ Checklist
🚀 Release Impact
🤖 Generated with Claude Code