build(deps): upgrade Vite 7 → 8.0.2 (Rollup → Rolldown)#1347
build(deps): upgrade Vite 7 → 8.0.2 (Rollup → Rolldown)#1347iOvergaard wants to merge 10 commits intomainfrom
Conversation
- Bump vite 7.3.1 → ^8.0.1 - Bump vitest ^4.0.18 → ^4.1.0 - Rename `rollupOptions` → `rolldownOptions` in vite.config.ts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
There was a problem hiding this comment.
Pull request overview
Upgrades the repo’s build/test toolchain to Vite 8 (which switches bundling to Rolldown) and updates Vitest accordingly, aligning the Vite config with the new bundler option name.
Changes:
- Upgrade
viteto^8.0.1andvitest/@vitest/browser*to^4.1.0. - Update
vite.config.tsto userolldownOptionsinstead ofrollupOptions. - Refresh
package-lock.jsonto reflect the new dependency graph (Rolldown bindings, lightningcss, etc).
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
vite.config.ts |
Switches build bundler configuration to rolldownOptions for Vite 8. |
package.json |
Bumps Vite/Vitest-related devDependency versions to match the new toolchain. |
package-lock.json |
Locks updated dependency tree after upgrading Vite/Vitest (including Rolldown + new transitive deps). |
…istration
Rolldown (Vite 8) has two behavioral differences from Rollup that break
the registration file pattern (button.ts calling defineElement):
1. **Extglob not supported in sideEffects**: The existing
`!(*.element).ts` extglob patterns in package.json#sideEffects are
not parsed by Rolldown. With no files matching, Rolldown treats all
files as side-effect-free and omits the bare registration imports
(e.g. `import "./components/button/button.js"`) from dist/index.js.
Fix: replace extglob with negative-prefix glob patterns that Rolldown
understands (`!dist/components/**/*.element.js` + `dist/**/*.js`).
2. **Re-exports stripped from non-entry modules**: When only src/index.ts
is the entry, Rolldown resolves re-export chains and strips the
exports from intermediate modules like button.js (since UUIButtonElement
is already reachable via button.element.js). This breaks the cherry-pick
import pattern where consumers do:
import { UUIButtonElement } from '@umbraco-ui/uui/components/button/button.js'
Fix: add all component registration files as explicit Rolldown entry
points via a glob in vite.config.ts. This signals to Rolldown that
each registration file is a first-class output, preserving its exports.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
Moves the 81 component re-exports out of src/index.ts into a dedicated src/components/index.ts, keeping src/index.ts slim (3 lines + comment). Also adds src/components/index.ts as an explicit Rolldown entry in vite.config.ts (same reason as component registration files — prevents Rolldown from flattening its re-export chain) and updates the plop template to append new components to src/components/index.ts instead of src/index.ts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
…kage.json Replace src/ patterns in package.json#sideEffects with treeshake.moduleSideEffects: true in rolldownOptions. The sideEffects field is a public contract for consumer bundlers — it should only describe published dist/ files, not src/ files that are never shipped. Build-time side-effect behaviour belongs in the build config. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
Pure re-export barrel, same as dist/internal/index.js which was already excluded. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
|
Follow-up to watch: Rolldown rc.12 was released today with two potentially relevant changes:
When Vite ships with rc.12, worth re-testing whether either of those workarounds can be dropped. |
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |
- scripts/verify-build.js: post-build assertions that catch silent regressions (missing bare imports, broken registration/element separation, source/dist count mismatch). Runs in CI after build. - src/components/components.test.ts: vitest browser smoke test that verifies element-only import does NOT register, and barrel import registers all components. - .github/workflows/tests.yml: run verify-build after build step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://delightful-beach-055ecb503-1347.westeurope.azurestaticapps.net |



Summary
Upgrades Vite 7 → 8.0.2, which switches the bundler from Rollup to Rolldown. Rolldown has two behavioral differences from Rollup that broke UUI's custom element registration — both are fixed here.
What works end-to-end after this PR
Barrel import registers all components:
Cherry-pick import works as expected:
All 946 tests pass (including 2 new registration smoke tests). Build produces 282 modules.
Fix 1 — Rolldown ignores extglob in
sideEffects(package.json)Rolldown cannot parse the extglob syntax
!(*.element).tsused inpackage.json#sideEffects. When no patterns match, Rolldown treats every file as side-effect-free and drops the bare registration imports (e.g.import "./components/button/button.js") fromdist/index.js— sodefineElementis never called and no components are registered.Fix: replace extglob with negative-prefix globs, and move build-time side-effect configuration into
vite.config.tswhere it belongs.The
sideEffectsfield inpackage.jsonis a public contract for consumer bundlers — it should only reference files that are actually published (dist/). The old config also includedsrc/patterns which Rolldown reads during the build to decide whether to preserve bare side-effect imports in the output. Rather than encoding build behaviour in package metadata, the fix usestreeshake: { moduleSideEffects: true }inrolldownOptionsto tell Rolldown to preserve all module side effects during the build.Result:
package.json#sideEffectsis now 4 lines that only describe publisheddist/files.Fix 2 — Rolldown strips re-exports from non-entry modules (
vite.config.ts)When only
src/index.tsis an explicit entry, Rolldown resolves re-export chains and strips exports from intermediate registration files likebutton.js(sinceUUIButtonElementis reachable viabutton.element.js). This breaks the cherry-pick import pattern.Fix: add all component registration files as explicit Rolldown entry points via a
componentEntriesglob invite.config.ts. Rolldown then treats each registration file as a first-class output, preserving its exports.Build verification (
scripts/verify-build.js)A post-build verification script runs in CI after
npm run buildto catch silent regressions. The build can succeed while producing broken output (e.g. missing bare imports = components won't register). The script checks:dist/index.jshas exactly 3 bare side-effect importsdist/components/index.jshas 81 registration imports, 0 element importsdefineElement+ exports (cherry-pick pattern)defineElement(separation preserved)Registration smoke test (
src/components/components.test.ts)A vitest browser test that verifies:
.element.jsfile does NOT register the custom elementChanges in this PR
package.jsonsideEffects: extglob → negative-prefix globs,dist/-only. Vite 7→8.0.2, vitest 4.0→4.1. Addverify-buildscriptvite.config.tsrollupOptions→rolldownOptions, addcomponentEntriesglob as explicit entries, addtreeshake: { moduleSideEffects: true }scripts/verify-build.jssrc/components/components.test.ts.github/workflows/tests.ymlverify-buildafter build steppackage-lock.jsonNote: the
src/components/index.tsbarrel extraction and plop template fixes were cherry-picked tomainseparately.Test plan
npm run buildcompletes without errors (282 modules, Vite 8.0.2)npm run verify-build— 17/17 checks passnpm run test— 946/946 tests pass in Chromium (including 2 new registration tests)customElements.get('uui-button')returnsUUIButtonElementafter barrel import🤖 Generated with Claude Code