diff --git a/integrations/vite/index.test.ts b/integrations/vite/index.test.ts
index 3afb057c5..ead71b472 100644
--- a/integrations/vite/index.test.ts
+++ b/integrations/vite/index.test.ts
@@ -914,3 +914,112 @@ test(
function firstLine(str: string) {
return str.split('\n')[0]
}
+
+test(
+ 'optimize option: disabled',
+ {
+ fs: {
+ 'package.json': json`
+ {
+ "type": "module",
+ "dependencies": {
+ "@tailwindcss/vite": "workspace:^",
+ "tailwindcss": "workspace:^"
+ },
+ "devDependencies": {
+ "vite": "^7"
+ }
+ }
+ `,
+ 'vite.config.ts': ts`
+ import tailwindcss from '@tailwindcss/vite'
+ import { defineConfig } from 'vite'
+
+ export default defineConfig({
+ build: { cssMinify: false },
+ plugins: [tailwindcss({ optimize: false })],
+ })
+ `,
+ 'index.html': html`
+
+
+
+
+ Hello, world!
+
+ `,
+ 'src/index.css': css`
+ @reference 'tailwindcss/theme';
+ @import 'tailwindcss/utilities';
+ `,
+ },
+ },
+ async ({ exec, expect, fs }) => {
+ await exec('pnpm vite build')
+
+ let files = await fs.glob('dist/**/*.css')
+ expect(files).toHaveLength(1)
+ let [filename] = files[0]
+
+ // Should not be minified when optimize is disabled
+ let content = await fs.read(filename)
+ expect(content).toContain('.hover\\:flex {')
+ expect(content).toContain('&:hover {')
+ expect(content).toContain('@media (hover: hover) {')
+ expect(content).toContain('display: flex;')
+ },
+)
+
+test(
+ 'optimize option: enabled with minify disabled',
+ {
+ fs: {
+ 'package.json': json`
+ {
+ "type": "module",
+ "dependencies": {
+ "@tailwindcss/vite": "workspace:^",
+ "tailwindcss": "workspace:^"
+ },
+ "devDependencies": {
+ "vite": "^7"
+ }
+ }
+ `,
+ 'vite.config.ts': ts`
+ import tailwindcss from '@tailwindcss/vite'
+ import { defineConfig } from 'vite'
+
+ export default defineConfig({
+ build: { cssMinify: false },
+ plugins: [tailwindcss({ optimize: { minify: false } })],
+ })
+ `,
+ 'index.html': html`
+
+
+
+
+ Hello, world!
+
+ `,
+ 'src/index.css': css`
+ @reference 'tailwindcss/theme';
+ @import 'tailwindcss/utilities';
+ `,
+ },
+ },
+ async ({ exec, expect, fs }) => {
+ await exec('pnpm vite build')
+
+ let files = await fs.glob('dist/**/*.css')
+ expect(files).toHaveLength(1)
+ let [filename] = files[0]
+
+ // Should be optimized but not minified
+ let content = await fs.read(filename)
+ expect(content).toContain('@media (hover: hover) {')
+ expect(content).toContain('.hover\\:flex:hover {')
+ expect(content).toContain('display: flex;')
+ },
+)
diff --git a/packages/@tailwindcss-vite/README.md b/packages/@tailwindcss-vite/README.md
index 7d21bd883..53e03ab47 100644
--- a/packages/@tailwindcss-vite/README.md
+++ b/packages/@tailwindcss-vite/README.md
@@ -34,3 +34,43 @@ For help, discussion about best practices, or feature ideas:
## Contributing
If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**.
+
+---
+
+## `@tailwindcss/vite` plugin API
+
+### Enabling or disabling Lightning CSS
+
+By default, this plugin detects whether or not the CSS is being built for production by checking the `NODE_ENV` environment variable. When building for production Lightning CSS will be enabled otherwise it is disabled.
+
+If you want to always enable or disable Lightning CSS the `optimize` option may be used:
+
+```js
+import tailwindcss from '@tailwindcss/vite'
+import { defineConfig } from 'vite'
+
+export default defineConfig({
+ plugins: [
+ tailwindcss({
+ // Disable Lightning CSS optimization
+ optimize: false,
+ }),
+ ],
+})
+```
+
+It's also possible to keep Lightning CSS enabled but disable minification:
+
+```js
+import tailwindcss from '@tailwindcss/vite'
+import { defineConfig } from 'vite'
+
+export default defineConfig({
+ plugins: [
+ tailwindcss({
+ // Enable Lightning CSS but disable minification
+ optimize: { minify: false },
+ }),
+ ],
+})
+```
diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts
index 00ba92db4..ab9635d10 100644
--- a/packages/@tailwindcss-vite/src/index.ts
+++ b/packages/@tailwindcss-vite/src/index.ts
@@ -18,12 +18,20 @@ const SPECIAL_QUERY_RE = /[?&](?:worker|sharedworker|raw|url)\b/
const COMMON_JS_PROXY_RE = /\?commonjs-proxy/
const INLINE_STYLE_ID_RE = /[?&]index\=\d+\.css$/
-export default function tailwindcss(): Plugin[] {
+export type PluginOptions = {
+ /**
+ * Optimize and minify the output CSS.
+ */
+ optimize?: boolean | { minify?: boolean }
+}
+
+export default function tailwindcss(opts: PluginOptions = {}): Plugin[] {
let servers: ViteDevServer[] = []
let config: ResolvedConfig | null = null
let isSSR = false
- let minify = false
+ let shouldOptimize = true
+ let minify = true
let roots: DefaultMap = new DefaultMap((id) => {
let cssResolver = config!.createResolver({
@@ -65,8 +73,22 @@ export default function tailwindcss(): Plugin[] {
async configResolved(_config) {
config = _config
- minify = config.build.cssMinify !== false
isSSR = config.build.ssr !== false && config.build.ssr !== undefined
+
+ // By default we optimize CSS during the build phase but if the user
+ // provides explicit options we'll use those instead
+ if (opts.optimize !== undefined) {
+ shouldOptimize = opts.optimize !== false
+ }
+
+ // Minification is also performed when optimizing as long as it's also
+ // enabled in Vite
+ minify = shouldOptimize && config.build.cssMinify !== false
+
+ // But again, the user can override that choice explicitly
+ if (typeof opts.optimize === 'object') {
+ minify = opts.optimize.minify !== false
+ }
},
},
@@ -116,12 +138,14 @@ export default function tailwindcss(): Plugin[] {
}
DEBUG && I.end('[@tailwindcss/vite] Generate CSS (build)')
- DEBUG && I.start('[@tailwindcss/vite] Optimize CSS')
- result = optimize(result.code, {
- minify,
- map: result.map,
- })
- DEBUG && I.end('[@tailwindcss/vite] Optimize CSS')
+ if (shouldOptimize) {
+ DEBUG && I.start('[@tailwindcss/vite] Optimize CSS')
+ result = optimize(result.code, {
+ minify,
+ map: result.map,
+ })
+ DEBUG && I.end('[@tailwindcss/vite] Optimize CSS')
+ }
return result
},