diff --git a/integrations/vite/svelte.test.ts b/integrations/vite/svelte.test.ts new file mode 100644 index 000000000000..5e3336b70792 --- /dev/null +++ b/integrations/vite/svelte.test.ts @@ -0,0 +1,76 @@ +import { expect } from 'vitest' +import { candidate, html, json, test, ts } from '../utils' + +test( + 'production build', + { + fs: { + 'package.json': json` + { + "type": "module", + "dependencies": { + "svelte": "^4.2.18", + "tailwindcss": "workspace:^" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.1.1", + "@tailwindcss/vite": "workspace:^", + "vite": "^5.3.5" + } + } + `, + 'vite.config.ts': ts` + import { defineConfig } from 'vite' + import { svelte, vitePreprocess } from '@sveltejs/vite-plugin-svelte' + import tailwindcss from '@tailwindcss/vite' + + export default defineConfig({ + plugins: [ + svelte({ + preprocess: [vitePreprocess()], + }), + tailwindcss(), + ], + }) + `, + 'index.html': html` + + + +
+ + + + `, + 'src/main.ts': ts` + import App from './App.svelte' + const app = new App({ + target: document.body, + }) + `, + 'src/App.svelte': html` + + +

Hello {name}!

+ + + `, + }, + }, + async ({ fs, exec }) => { + await exec('pnpm vite build') + + let files = await fs.glob('dist/**/*.css') + expect(files).toHaveLength(1) + + await fs.expectFileToContain(files[0][0], [candidate`underline`, candidate`foo`]) + }, +) diff --git a/packages/@tailwindcss-vite/package.json b/packages/@tailwindcss-vite/package.json index acbf1a1525d1..4914638d759b 100644 --- a/packages/@tailwindcss-vite/package.json +++ b/packages/@tailwindcss-vite/package.json @@ -31,12 +31,13 @@ "@tailwindcss/oxide": "workspace:^", "lightningcss": "^1.25.1", "postcss-load-config": "^6.0.1", + "svelte-preprocess": "^6.0.2", "tailwindcss": "workspace:^" }, "devDependencies": { "@types/node": "catalog:", - "vite": "catalog:", - "internal-postcss-fix-relative-paths": "workspace:^" + "internal-postcss-fix-relative-paths": "workspace:^", + "vite": "catalog:" }, "peerDependencies": { "vite": "^5.2.0" diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts index e0bd810c08ef..f3504f95e169 100644 --- a/packages/@tailwindcss-vite/src/index.ts +++ b/packages/@tailwindcss-vite/src/index.ts @@ -3,6 +3,7 @@ import fixRelativePathsPlugin, { normalizePath } from 'internal-postcss-fix-rela import { Features, transform } from 'lightningcss' import path from 'path' import postcssrc from 'postcss-load-config' +import { sveltePreprocess } from 'svelte-preprocess' import { compile } from 'tailwindcss' import type { Plugin, ResolvedConfig, Rollup, Update, ViteDevServer } from 'vite' @@ -173,6 +174,7 @@ export default function tailwindcss(): Plugin[] { } return [ + svelteProcessor(), { // Step 1: Scan source files for candidates name: '@tailwindcss/vite:scan', @@ -347,7 +349,11 @@ function getExtension(id: string) { function isTailwindCssFile(id: string, src: string) { if (id.includes('/.vite/')) return - return getExtension(id) === 'css' && src.includes('@tailwind') + const extension = getExtension(id) + const isTailwind = + (extension === 'css' && src.includes('@tailwind')) || + (extension === 'svelte' && id.endsWith('&lang.css')) + return isTailwind } function optimizeCss( @@ -373,3 +379,43 @@ function optimizeCss( errorRecovery: true, }).code.toString() } + +// Register a plugin that can hook into the Svelte preprocessor if svelte is +// enabled. This allows us to transform CSS in `