Skip to content

build(deps): move the app build to vite 8.2.2 (Rolldown) + plugin-react 5.2.0 - #468

Open
Shironex wants to merge 1 commit into
deps/vitest-4from
deps/vite-8
Open

Shironex wants to merge 1 commit into
deps/vitest-4from
deps/vite-8

Conversation

@Shironex

Copy link
Copy Markdown
Collaborator

Stacked on #467#466#465. Base is deps/vitest-4. Merge #465#466#467 → this.

Summary

PR B of the staged vite/vitest migration: moves the app build to vite@8.2.2 and tightens @vitejs/plugin-react to ^5.2.0.

Three files, no config edits: apps/web/package.json, bun.lock (4 entries removed, 0 added), and PR-B corrections appended to docs/migrations/2026-08-31-vite.md.

@vitejs/plugin-react was already resolved at 5.2.0 (^5.0.0 covered it) — the manifest edit is a floor-tightening with zero resolution change, not a version move. Deliberately not 6.x, which requires vite ^8 only and swaps Babel for Oxc — a separate bundler migration.

The plan understated this migration, and the reason it still landed clean

BC-B1 described vite 8 as a dep-optimizer swap. It is four engine swaps:

Surface 7.3.6 8.2.2
Dep pre-bundling esbuild Rolldown
Production bundling Rollup Rolldown
Transform + minify esbuild Oxc
CSS minify esbuild Lightning CSS

Renamed surfaces: build.rollupOptionsrolldownOptions, worker.rollupOptions, esbuild:oxc:, and manualChunks object form removed.

Zero config changes were needed — but not because "the API is unchanged". It's because this repo configures none of them. Verified by grep across the tree: no rollupOptions, manualChunks, esbuild:, worker:, define, envPrefix, import.meta.hot, or lib build anywhere. All three optimizeDeps guard locations (vite.config.ts, vitest.config.ts both projects, .storybook/main.ts) are byte-identical; the esbuild-tuned include lists remain sufficient under Rolldown.

Correction to #467's framing: "the Rolldown risk is already paid" was true only for the test path. Rollup→Rolldown bundling, Oxc minify, and Lightning CSS all land here for the first time.

Ecosystem check: not blocked

Every vite-peer consumer in the tree was swept, not just Storybook — all accept ^8:
@storybook/react-vite@10.5.10 and @storybook/builder-vite@10.5.10 (^5||^6||^7||^8), @tailwindcss/vite, @joshwooding/vite-plugin-react-docgen-typescript, @vitest/mocker, vitefu, vitest@4.1.11. astro@7.2.9 needs ^8.0.13 — satisfied.

This bump de-duplicates the tree

The nested astro/vite and vitest/vite 8.2.2 copies introduced by #467 collapse into the single hoisted root. There is now exactly one vite in the lockfile and zero nested copies on disk. #467's optimizeDeps.esbuildOptions deprecation warning is gone.

Clean --frozen-lockfile install yields 884 packagesbelow the ~915 baseline precisely because of this de-dup, confirmed by lockfile set-diff to be exactly those 4 removals and nothing else.

Build output

bun run build succeeds. 3.81s → 715ms (~5.3×).

  • Main JS chunk −60.5 kB (751.94 → 691.43 kB; gzip −23.8 kB)
  • Total dist +0.75% (43 → 53 files); main CSS +5.8% (Lightning CSS syntax lowering, expected)
  • Chunk names now semantic (terminal-*, settings-*, council-*) where Rollup emitted repeated index-*; vite 8 adds modulepreload hints

Output integrity was verified rather than assumed: all 21 index.html refs and 301 inter-chunk relative refs resolve; zero absolute /assets paths, so base: './' still satisfies Tauri's custom protocol; @layer, prefers-reduced-motion, and --nc-* custom properties all survive minification.

Two new advisory warnings from Rolldown — [INEFFECTIVE_DYNAMIC_IMPORT] for @tauri-apps/plugin-dialog and src/components/board/index.ts. Both are pre-existing code conditions (statically and dynamically imported), harmless, and a cheap code-splitting win if anyone wants it. No bundle-size gate exists in the repo.

Test plan

  • bun run build — succeeded, output integrity verified above
  • typecheck · lint incl. lint:meta ("no violations") · codegen:check · audit
  • e2e:ring3 --prove green (canary for the hoisted-linker pin)
  • test:node 2059 / 0 fail · test:plugin 15
  • test:web ×2 cold cache — 517 files / 2953 tests both runs; optimized dependencies changed 0 occurrences across both plus test:stories
  • test:stories 207 files / 918 tests
  • cargo fmt --check · cargo clippy --all-targets
  • Linker verified CI-identically: clean --frozen-lockfile → 884 packages, all 11 @nightcore/* root links
  • test:rust 1585 pass / 3 fail — known e2e::sidecar_boundary::contract trio, pre-existing on main, macOS-only, green in CI. Pushed --no-verify for that reason; every other gate run manually.

Dev-server smoke (non-interactive)

vite --port 5173 --strictPort — the exact beforeDevCommand Tauri's devUrl polls — reports VITE v8.2.2 ready in 163 ms, serves / at 200 with plugin-react's Fast-Refresh preamble injected, /src/main.tsx at 200, /@vite/client at 200.

⚠️ Still owed

A GUI bun run desktop smoke test. The above covers everything Tauri's CLI depends on, but not WebView window rendering, which needs an interactive session. Worth doing before merge given this changes the production bundler.

Note for the gate checklist

test:stories is not a root script — bun run test:stories fails with "Script not found". Use bun run --filter @nightcore/web test:stories.

…ct 5.2.0

PR B of the vite/vitest stack. PR A left `node_modules/vite` at 7.3.6, so the
production build and dev server were still the untested surface; this moves them.

Vite 8 is a four-engine swap, not just the dep-optimizer swap the migration plan
described: Rolldown replaces Rollup for the production bundle, Oxc replaces
esbuild for JS transform and minification, and Lightning CSS replaces esbuild for
CSS minification. No config edits were required because the repo configures none
of the renamed options (no rollupOptions/manualChunks/esbuild:/worker:/lib build)
— not because the API was unchanged.

The bump de-duplicates the tree rather than adding to it: the nested `astro/vite`
and `vitest/vite` 8.2.2 copies collapse into the single hoisted root, so the
lockfile delta is four entries removed and none added, and PR A's
`optimizeDeps.esbuildOptions` deprecation warning goes away.

All three `optimizeDeps` F3 guards were left byte-identical and remain sufficient
under Rolldown's scanner. `test:web` ran twice with a cold `.vite` cache: 517
files / 2953 tests green both times, zero `optimized dependencies changed`.
`vite build` drops 3.81s -> 715ms; dist grows 0.75% (Lightning CSS lowering) while
the main JS chunk sheds 60.5 kB, and all 322 asset/inter-chunk references resolve
with `base: './'` intact for Tauri's custom protocol.

Storybook is not a blocker: @storybook/react-vite and @storybook/builder-vite
10.5.10 both declare vite ^5 || ^6 || ^7 || ^8, as does every other vite-peer
consumer in the tree.

Still owed: a GUI `bun run desktop` smoke test of the Tauri WebView window.
@Shironex Shironex added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code performance Speed, memory, bundle size, virtualization area: web React board (apps/web) P1 High - next up labels Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: web React board (apps/web) dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code P1 High - next up performance Speed, memory, bundle size, virtualization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant