Migrate to Vite 8 and improve the codebase by introducing roles#31
Merged
thetutlage merged 8 commits into5.xfrom May 9, 2026
Merged
Migrate to Vite 8 and improve the codebase by introducing roles#31thetutlage merged 8 commits into5.xfrom
thetutlage merged 8 commits into5.xfrom
Conversation
Bump peerDep + devDep to vite ^8.0.0. Rename build.rollupOptions to build.rolldownOptions in plugin config, with fallback chain that honors user-provided rolldownOptions.input then legacy rollupOptions.input for backwards compat. Add npm overrides to allow vite-plugin-restart 2.0.0 (peer pinned to ^7.0.0) to resolve against vite 8 — plugin internals only use stable Vite plugin API. Smoke tests added to cover Vite 8 touchpoints: config defaults, manifest shape, CSS chunk emission, dynamic imports, build error shape, createBuilder().buildApp(), plugin compat, outDir override. Existing CSS-collection tests updated to use rolldownOptions. BREAKING CHANGE: requires vite ^8.0.0 as peer dependency.
Drop the vite-plugin-restart dependency in favor of a local plugin
implementation at src/client/reload.ts. The upstream package is
unmaintained and pins its peer to vite ^7, blocking clean installs
on vite 8.
Only the browser-reload feature was used (server.restart was never
exposed via defineConfig), so the new plugin is reload-only: it
debounces watcher events that match the user-supplied glob patterns
and emits a full-reload WS message.
Implementation details:
- Uses picomatch for matching (Vite's bundled glob engine).
- Watches the longest non-glob prefix of each pattern so newly
created files inside watched dirs trigger reloads under chokidar 4
(which removed glob support entirely).
- 100ms default debounce, configurable via { delay }.
Plugin is internal — not exported from package.json. Test helpers
(bootDevServer, waitForReload) added to tests/backend/helpers.ts.
Replaces the import.meta.glob pattern that was used by app authors to
register static assets (images, fonts) into the build output. Vite 8
no longer emits non-JS modules through import.meta.glob, breaking
that pattern.
The new assets option on the AdonisJS plugin accepts:
- string[]: shorthand for { chunks }, glob-expanded and emitted via
emitFile({ type: 'chunk' }).
- { chunks?, assets? }: chunks behave as above; assets are exact file
paths (no glob — throws on glob chars) emitted as raw type: 'asset'.
The manifest is rewritten post-write so the manifest key matches
the original source path, letting templates resolve via
vite.assetPath('resources/images/logo.png').
Implemented as a pair of plugins (emit + manifest rewrite) in
src/client/resolve_assets.ts. tinyglobby is added as a direct dep
(was already transitive via @adonisjs/assembler).
Cover the runtime touchpoints between AdonisJS and Vite that were not exercised by the existing suite — surfaces that could silently regress on a future Vite upgrade. - dev_server.spec.ts: createDevServer middlewareMode contract, useDevServer flag, VITE_HMR_PORT env wiring, moduleGraph getModuleById/idToModuleMap after warmupRequest, environments.ssr and environments.client presence, middlewares Connect API, stopDevServer cleanup, adonisjs plugin integration. - module_runner.spec.ts: createModuleRunner returns ModuleRunner, runner.import loads a fixture module via the SSR environment, the vite/module-runner subpath export resolves. - middleware.spec.ts: extended with three proxy cases — /@vite/client, a .ts entrypoint (asserts type stripping), and a CSS file. - vite.spec.ts: re-skipped the recursive CSS collection test with an accurate reason (server-side warmupRequest does not transitively load nested imports the way a browser would).
Vite was a 519-line class mixing config, manifest reading, dev server lifecycle, tag generation, manifest chunk walking, dev module graph walking, and URL resolution — all branching on `useDevServer` at every mode-aware method. Split into a thin facade plus single-role collaborators: - TagBuilder HTML element factory (link/script/preload) - ManifestLoader lazy load + chunk lookup - AssetUrlBuilder (Dev|Build) URL resolution strategy - EntrypointWalker (DevCssGraph|ManifestChunk) traversal strategy - EntrypointTagRenderer shared walker + tagBuilder composition - ViteRuntime (Dev|Build) mode-specific behavior bundle Polymorphism point is the walker; renderer + tag builder are mode-free and shared. Every `if (this.useDevServer)` branch in Vite is gone. New seam: vite.useRuntime(runtime). Provider builds DevRuntime via DevRuntime.create() and installs it explicitly in ready(). The existing vite.createDevServer() is kept as a backward-compat wrapper. Public API unchanged. All 101 tests pass; lint + typecheck clean.
picomatch and tinyglobby expect POSIX paths, but Vite's config root and chokidar events use native separators. On Windows this caused the reload plugin to never match changed files and the resolve_assets glob to skip all chunk patterns, leaving asset manifest keys with backslashes.
`path.join` returns native separators, so on Windows the entrypoint inputs forwarded to rolldown carried backslashes. That diverged from the POSIX-style paths Vite uses everywhere else (manifest keys, module IDs), which broke asset lookups built around forward-slash keys.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.