Skip to content

refactor(styles): replace internal styles plugin with @vuetify/unplugin-styles#359

Open
AndreyYolkin wants to merge 22 commits intomainfrom
feat/unplugin-styles-integration
Open

refactor(styles): replace internal styles plugin with @vuetify/unplugin-styles#359
AndreyYolkin wants to merge 22 commits intomainfrom
feat/unplugin-styles-integration

Conversation

@AndreyYolkin
Copy link
Copy Markdown
Contributor

@AndreyYolkin AndreyYolkin commented Apr 19, 2026

Summary

  • Replace the hand-rolled vuetifyStylesPlugin with @vuetify/unplugin-styles/vite, registered from configure-vite.ts with options mapped from moduleOptions.styles.
  • Remove src/vite/vuetify-styles-plugin.ts, src/utils/styles-compiler.ts, and the experimental SASS pre-compile cache (including stylesCachePath on the context and the cache helpers in utils/styles.ts).
  • Public moduleOptions.styles API unchanged ('sass' / 'none' / { configFile }). Nuxt-layer configFile resolution stays in vuetify-nuxt-module via the existing resolveVuetifyConfigFile helper.
  • New test coverage for the integration (see Test plan).

Test plan

  • pnpm -C packages/vuetify-nuxt-module test — 11 suites / 25 tests pass (adds unplugin-styles.test.ts, a 6-case unit matrix over the configureVite styles branches).
  • pnpm -C packages/vuetify-nuxt-module test:e2e — Playwright-driven SSR matrix on a dedicated test/fixtures/styles-ssr/ fixture. 20 cases across { 'none', { configFile } } × { dev, build }, covering FOUC, hydration, SSR client hints (prefers-color-scheme), custom SCSS variables, CSS layers, and 404-free asset loading.
  • pnpm -C packages/vuetify-nuxt-module dev — playground (styles: { configFile }) renders Vuetify components with dark theme, date picker, locale switch; no SASS compile errors in console.
  • Manual SSR check with ssr: true — covered by the fixture + Playwright spec.
  • Manual check with styles: 'none' — covered by the none/* matrix entries.

Notes

SSR-specific id prefix — partially valid concern

The previous vuetifyStylesPlugin defined two virtual prefixes: vuetify-styles/ (client) and /@vuetify-styles/ (SSR). The single-prefix approach in @vuetify/unplugin-styles is correct for prod builds — Vite's per-environment module graphs remove the need for a second prefix. However, the e2e suite caught a real regression in Vite dev mode:

  • SSR-rendered HTML references /_nuxt/vuetify-styles/lib/components/V*/V*.css (and /_nuxt/vuetify-styles-empty.css for styles: 'none').
  • Vite's transformMiddleware strips the /_nuxt/ base before plugin resolution, leaving an id like /vuetify-styles/lib/... (with leading /).
  • @vuetify/unplugin-styles' resolveId.filter.id and load.filter.id both anchor to bare ^vuetify-styles — the leading / causes the filter to miss, Vite falls through to the static-file resolver, and the browser gets a 404.
  • Prod builds are unaffected because the virtual CSS is materialised into real static files.

Scope of failures in dev mode: 1 URL for styles: 'none', 11 URLs for styles: { configFile }.

Captured in tests: styles-ssr.spec.ts scenario 6 (no 404 responses during page load) runs in all four matrix combos. The two */dev combos are marked it.fails so CI stays green while preserving the regression signal — when the upstream fix lands, those cases flip and vitest reports "expected to fail but passed", prompting removal of the marker.

Fix location (upstream, @vuetify/unplugin-styles): strip a leading / in both the resolveId and load filters (or their handlers) to accept ids that arrive via the Vite dev server's base-stripped path. Minimal change, does not require reintroducing a separate SSR prefix.

Other notes

  • The experimental cache was removed — cold-start SASS compilation may be slightly slower for projects with a custom settings file.
  • moduleOptions.styles.experimental.cache is now silently ignored; should be noted in the release changelog.

@userquin
Copy link
Copy Markdown
Member

userquin commented Apr 21, 2026

The previous SSR-only id prefix (/@vuetify-styles/) was not carried over. Modern Vite separates SSR and client module graphs per environment, and vite-plugin-vuetify (which this module mirrored) does not use such a prefix. If an SSR regression surfaces it can be addressed upstream in @vuetify/unplugin-styles (now in a private repo).

Tried a few times, any pr ignored, check my pr there. Maybe with the vite environment api... but will required support there and nuxt v5 (may or may not work with nuxt v4 with or without env. Api experimental flag, I havent checked it yet)

@userquin
Copy link
Copy Markdown
Member

Where is @vuetify/unplugin-styles?

…nts, layers

Adds a 16-test Playwright-driven SSR matrix across styles-mode (none,
configFile) x run-type (dev, build) for the @vuetify/unplugin-styles
integration. Uses createTest + manual vitest hook wiring so four
@nuxt/test-utils setups coexist in one file without clobbering each
other's module-level TestContext.

Also fixes the styles-ssr fixture's settings.scss: the single-quoted
"Comic Sans MS, sans-serif" collapsed into one invalid font name,
making the custom-font assertion unverifiable; a proper sass list
restores the cascade.
Picks up the dev-mode virtual-id fix (leading-slash + query-string
normalisation) that the e2e suite was capturing via it.fails markers.
Those markers were already dropped in the prior commit; this bump makes
the passing run reproducible against the published package.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants