From 0db226a222510ccbf13e09039c6d27d82f8bc460 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 14 May 2026 15:38:51 +0200 Subject: [PATCH] Add Vue integration test with 1000 components (#20055) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds an integration test with Vue where we use a 1000 components and where each component references a CSS file via `@reference`. Each component has a unique class that uses `@apply`. There are some discussions in https://github.com/tailwindlabs/tailwindcss/discussions/16429 that mention that this causes OOM issues. Right now I can't reproduce that, and even with a 1000 components, it produces CSS in a reasonable time: ``` vite v7.3.3 building client environment for production... ✓ 2011 modules transformed. dist/index.html 0.23 kB │ gzip: 0.18 kB dist/assets/index-DNVNFkYQ.css 106.65 kB │ gzip: 10.79 kB dist/assets/index-B8v7EbAN.js 223.84 kB │ gzip: 49.81 kB ✓ built in 3.17s ``` I also started a Vite server and triggered file changes to see if the memory would grow forever, which it didn't. After a 1000 changes, everything still behaves smoothly: image Making changes manually to a single component, result in proper HMR request that update the browser: https://github.com/user-attachments/assets/5c79ffc6-2329-4341-9d25-82b000093e31 This test is here to make sure that it keeps working in the future. --- If I remove all `@reference` references, and usages of `@apply`, then the build time is indeed faster: ``` vite v7.3.3 building client environment for production... ✓ 2011 modules transformed. dist/index.html 0.23 kB │ gzip: 0.18 kB dist/assets/index-CcxXccJ1.css 106.61 kB │ gzip: 10.76 kB dist/assets/index-M92YFF0G.js 223.84 kB │ gzip: 49.81 kB ✓ built in 1.97s ``` So we go from `1.97s` → `3.17s`, which is a `1.2s` increase when you use `@reference` with `@apply` in 1000 files for a fresh build. I also saw some comments about the CSS growing whenever `@reference` was used, but as you can see in the snippets above they are at a stable size. ## Test plan 1. All tests still pass [ci-all] For testing on Windows / macOS --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- integrations/vite/vue.test.ts | 108 +++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/integrations/vite/vue.test.ts b/integrations/vite/vue.test.ts index 3fea0db9a..6bcd3f799 100644 --- a/integrations/vite/vue.test.ts +++ b/integrations/vite/vue.test.ts @@ -1,5 +1,5 @@ import { stripVTControlCharacters } from 'node:util' -import { candidate, html, json, test, ts } from '../utils' +import { candidate, css, html, json, test, ts } from '../utils' test( 'production build', @@ -73,6 +73,110 @@ test( }, ) +{ + const VUE_COMPONENT_COUNT = 1_000 + + let vueComponentsWithReferences = Object.fromEntries( + Array.from({ length: VUE_COMPONENT_COUNT }, (_, idx) => [ + `src/components/Component${idx}.vue`, + html` + + + + `, + ]), + ) + + let vueComponentImports = Array.from( + { length: VUE_COMPONENT_COUNT }, + (_, idx) => `import Component${idx} from './components/Component${idx}.vue'`, + ).join('\n') + + let vueComponentUsages = Array.from( + { length: VUE_COMPONENT_COUNT }, + (_, idx) => ``, + ).join('\n') + + test( + 'production build with many Vue style blocks referencing the main stylesheet', + { + fs: { + 'package.json': json` + { + "type": "module", + "dependencies": { + "vue": "^3.4.37", + "tailwindcss": "workspace:^" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.1.2", + "@tailwindcss/vite": "workspace:^", + "vite": "^7" + } + } + `, + 'vite.config.ts': ts` + import { defineConfig } from 'vite' + import vue from '@vitejs/plugin-vue' + import tailwindcss from '@tailwindcss/vite' + + export default defineConfig({ + plugins: [vue(), tailwindcss()], + }) + `, + 'index.html': html` + + + +
+ + + + `, + 'src/main.css': css`@import 'tailwindcss';`, + 'src/main.ts': ts` + import { createApp } from 'vue' + import './main.css' + import App from './App.vue' + + createApp(App).mount('#app') + `, + 'src/App.vue': html` + + + + `, + ...vueComponentsWithReferences, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm vite build') + + let files = await fs.glob('dist/**/*.css') + expect(files).toHaveLength(1) + + await fs.expectFileToContain(files[0][0], [ + candidate`content-['component-0']`, + candidate`component-0`, + candidate`content-['component-99']`, + candidate`component-99`, + candidate`content-['component-999']`, + candidate`component-999`, + ]) + }, + ) +} + test( 'error when using `@apply` without `@reference`', { @@ -132,7 +236,7 @@ test( expect.assertions(1) try { - await exec('pnpm vite build') + await exec('pnpm vite build', {}, { ignoreStdErr: true }) } catch (error) { let [, message] = /error during build:([\s\S]*?)file:/g.exec(