Skip to content

feat: support Vite 8 with the Rolldown bundler - #8909

Open
maiieul wants to merge 22 commits into
mainfrom
feat/vite8-rolldown
Open

feat: support Vite 8 with the Rolldown bundler#8909
maiieul wants to merge 22 commits into
mainfrom
feat/vite8-rolldown

Conversation

@maiieul

@maiieul maiieul commented Aug 3, 2026

Copy link
Copy Markdown
Member

What is it?

  • Feature / enhancement

Description

Qwik v2 now needs Vite 8 and bundles with rolldown. Vite 5-7 and Rollup are dropped, so this is a
breaking change. It's the minimal slice of #8785 — Brian is busy, so I'm carrying it. Stacked on
#8907 and #8908; those land first and the diff shrinks. The sensitive part is chunking:
manualChunks + onlyExplicitManualChunks become rolldown's codeSplitting groups +
includeDependenciesRecursively: false, which buys the same thing — a grouped module no longer
drags its deps into the chunk. Green: prod build, 3201 unit tests, 487/487 chromium e2e, SSG
html/state snapshot and size budgets unchanged, docs REPL still working.

Chunking, the part worth reviewing

  • Core and preloader are codeSplitting groups. The manifest finds them by group name.
  • The qwikloader is found by its emit reference, so a /qwikloader route can't shadow it.
  • Client only. The server bundle doesn't need Qwik chunking.
  • Qwik's groups go first. Users can outrank them with priority.
  • No strictExecutionOrder — it breaks preloading.

The dist build is untouched

  • Still rollup + terser. Vite 8 only changes the vite.build() option keys, so the shipped
    core.prod.mjs / core.min.mjs / preloader are byte-for-byte what main produces.
  • Size budgets stay where they were: app core chunk 34.5kb brotli against the same 35400 budget.

Three bugs found while verifying

  • The qwikloader filename never reached the manifest, so no loader script shipped and the page
    stayed dead. Unit tests missed it because they call the manifest directly. Only e2e caught it.
  • outputOptions is a sync hook, but ours returned a promise. The standalone qwikRolldown plugin
    was therefore applying no Qwik chunking at all. That is what broke the REPL. Now fixed, so
    standalone rolldown users get Qwik chunking for the first time.
  • Vite 8 leaves the compiled out-of-order executor ending in a line comment, which swallowed the
    closing brace of its wrapper and threw SyntaxError in the browser.

Where this differs from #8785

  • Vite 8.2 (rolldown >=1.2.1), not 8.1.5. 1.1.5 has an init-order bug with codeSplitting + CJS deps.
  • REPL fixed instead of test.fixme'd.
  • Chunking stays client-only.
  • The dist minifier stays terser.

@changeset-bot

changeset-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 240c3d5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@qwik.dev/core Minor
@qwik.dev/router Minor
@qwik.dev/react Minor
eslint-plugin-qwik Minor
@qwik.dev/utils Minor
create-qwik Minor

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

@maiieul maiieul self-assigned this Aug 3, 2026
@maiieul maiieul moved this to In progress in Qwik Development Aug 3, 2026
@pkg-pr-new

pkg-pr-new Bot commented Aug 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

@qwik.dev/core

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/core@8909

@qwik.dev/router

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/router@8909

eslint-plugin-qwik

npm i https://pkg.pr.new/QwikDev/qwik/eslint-plugin-qwik@8909

create-qwik

npm i https://pkg.pr.new/QwikDev/qwik/create-qwik@8909

@qwik.dev/optimizer

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/optimizer@8909

@qwik.dev/devtools

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/devtools@8909

commit: 240c3d5

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
qwik-docs ✅ Ready (View Log) Visit Preview 240c3d5

@maiieul
maiieul changed the base branch from main to chore/dist-build-esbuild-minify August 4, 2026 04:19
@maiieul
maiieul force-pushed the feat/vite8-rolldown branch from 860e4fa to d45c410 Compare August 4, 2026 05:05
Base automatically changed from chore/dist-build-esbuild-minify to main August 5, 2026 13:26
@maiieul
maiieul force-pushed the feat/vite8-rolldown branch from d45c410 to 617b449 Compare August 5, 2026 13:26
Vite 8 bundles rolldown; pin 8.2.x so the lockfile resolves rolldown >=1.2.1, which
fixes an init-order bug with codeSplitting and CJS deps.
Renames the standalone plugin to qwikRolldown (qwikRollup stays as a deprecated
alias) and swaps manualChunks for rolldown's codeSplitting groups, which replace
Rollup 4.52's onlyExplicitManualChunks with includeDependenciesRecursively:false.

The manifest now finds core and preloader by group name, and the qwikloader by
its emit reference so a user route named /qwikloader can't shadow it.

outputOptions is a sync hook, so it no longer returns a promise — the standalone
plugin was silently dropping Qwik's chunking (the docs REPL built its own chunks).
handleHotUpdate becomes the per-environment hotUpdate hook, the watcher takes plain
directories now that chokidar 4 has no glob support, and the placeholder regexes
accept backticks because oxc re-emits string literals as template literals.
The raw-source load hook has to run first, otherwise Vite's wasm helper tries to
parse the raw .wasm source as a real module. The old manualChunks override for the
REPL is gone with manualChunks itself.
Covers the e2e fixtures, starters, scripts and the remaining package configs, plus
the two e2e assertions that track the new bundler's output (inline CSS minification
and the slightly larger core chunk).
Vite 8 leaves the compiled executor ending in a line comment, which swallowed the
closing brace of the wrapper and threw SyntaxError in the browser.
@maiieul
maiieul force-pushed the feat/vite8-rolldown branch from 617b449 to 6b5d8eb Compare August 17, 2026 09:46
Vite forces preserve_annotations for es lib builds, so terser kept a pure
annotation that rolldown then reports as invalid. Rolldown's own minifier drops
the comments and lets the terser config go.
Only the vite plugin was setting it, so rolldown warned that it had to infer it
from our codeSplitting options.
@maiieul
maiieul force-pushed the feat/vite8-rolldown branch from 44ba5c4 to b7de147 Compare August 17, 2026 12:32
Rolldown 1.2.4 may mangle the export names of group chunks and emit separate
facade chunks for the preloader and handlers entries, so the manifest pointed
symbols at chunks whose exports no longer carry their names. Prefer the emitted
facade when it exists in the output; fall back to the group chunk when the
bundler merged the entry into it.
Matches what users installing today resolve, so CI exercises rolldown's newer
chunk-export mangling.
…t own it

Nothing sets 'exports-only' — it is rolldown's default, invalid with the
codeSplitting the plugin configures. The vite plugin already sets
'allow-extension' where it builds the config; the repl now does the same at its
rolldown() call instead of the standalone plugin patching it in a hook.
Rolldown rejects the path-returning manualChunks compat on the ssr build:
chunk names may not be paths in the chunkFileNames pattern.
segment.entry has one consumer, so normalize it there instead of mutating the
transform output.
It only shaped debug-mode chunk names; sanitization is all the bundler needs.
Rolldown's default attachDebugInfo 'simple' writes provenance comments into
unminified output, which lib-mode builds publish.
Main added qwik-utils pinned to vite 7.3.5, so the merged lockfile referenced a vite
7 entry this branch had removed and --frozen-lockfile refused to install.
packages/docs does not depend on rolldown directly, so the docs tsc build could not
resolve the type.
The test kept its own copy of the sanitizer, which missed backslashes and failed on
windows.
@maiieul
maiieul marked this pull request as ready for review August 19, 2026 18:01
@maiieul
maiieul requested review from a team as code owners August 19, 2026 18:01
@maiieul maiieul moved this from In progress to Waiting For Review in Qwik Development Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Waiting For Review

Development

Successfully merging this pull request may close these issues.

2 participants