Skip to content

Process Vue <style module> blocks in @tailwindcss/vite - #20597

Open
mkantautas wants to merge 2 commits into
tailwindlabs:mainfrom
mkantautas:fix/vite-vue-style-module
Open

mkantautas wants to merge 2 commits into
tailwindlabs:mainfrom
mkantautas:fix/vite-vue-style-module

Conversation

@mkantautas

Copy link
Copy Markdown

Summary

@vitejs/plugin-vue gives <style module> blocks ids that end in &lang.module.css (e.g. App.vue?vue&type=style&index=0&lang.module.css). isPotentialCssRootFile only accepts &lang.css, so these blocks are never handed to Tailwind and @reference / @apply end up in the built CSS unprocessed:

<template>
  <div :class="$style.foo">Hello Vue!</div>
</template>

<style module>
  @reference './main.css';

  .foo {
    @apply text-red-500;
  }
</style>

With Vite 8.3.4, @vitejs/plugin-vue 6.0.10 and @tailwindcss/vite 4.3.3 the bundle contains:

@reference './main.css';
._foo_rfnam_4 {
@apply text-red-500;
}

Plain <style> and <style scoped> blocks in the same component are processed.

This matches &lang.module.css in the transform filters and in isPotentialCssRootFile. The Tailwind transform runs with enforce: 'pre', so @apply is expanded before vite:css hashes the class names.

Test plan

  • Added production build with <style module> blocks to integrations/vite/vue.test.ts. On main it fails because the CSS still contains @apply text-red-500;; with this change it passes and the hashed .foo rule has color: var(--color-red-500, …).
  • pnpm vitest --root=./integrations run vite/vue.test.ts: 5 passed.
  • pnpm vitest --root=./integrations run vite/: all Vue and CSS modules tests pass. On my machine, dev-server tests that are unrelated to this change (external source file changes update the CSS, react-router build mode) timed out under load.
  • prettier --check on the changed files.

@mkantautas
mkantautas requested a review from a team as a code owner October 20, 2026 15:42
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The Vite integration now recognizes both standard CSS and CSS module language queries in its serve and build transform filters and CSS root detection. A production-build test covers Vue <style module> blocks with @reference and @apply. It checks that the generated CSS contains a hashed module selector and the expected red color output, without retaining those directives. The changelog records this support.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 990f6

No concrete issue identified here requires resolution before merging; complete the normal checks.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely identifies the main change: processing Vue <style module> blocks in @tailwindcss/vite.
Description check Passed The description directly explains the bug, the implementation change, the test coverage, and the validation results for Vue <style module> processing.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔇 Additional comments: 3
packages/@tailwindcss-vite/src/index.ts: 1

21-21: LGTM!

Also applies to: 214-214, 251-251, 303-303

CHANGELOG.md: 1

60-60: LGTM!

integrations/vite/vue.test.ts: 1

145-145: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Regex depends on the CSS output format and class-name template.

The test sets cssMinify: false and asserts a ._foo_<hash> { selector. This relies on the default @vitejs/plugin-vue CSS-module naming template. It also relies on Lightning CSS or esbuild keeping the color: var(--color-red-500 text unchanged.

The test passes in the reported run. Keep the assertion if the format is stable across the supported Vite versions. Otherwise, loosen the regex, for example to /\._foo_[\w-]+\s*\{\s*color:\s*var\(--color-red-500/.


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3a74a33e-fbf5-4b5d-ae46-6d563595e7cd
📥 Commits

Reviewing files that changed from the base of the PR and between 8cc0551 and 990f6f6.

📒 Files selected for processing: 3
  • CHANGELOG.md
  • integrations/vite/vue.test.ts
  • packages/@tailwindcss-vite/src/index.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Reviews (1) · Last reviewed commit: "Add changelog entry for #20597" · Reviewed by Greptile

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.

1 participant