mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Add optimize option to @tailwindcss/vite plugin (#19131)
Adds an `optimize` option to the Vite plugin that matches the API and
behavior of the PostCSS plugin.
Supports three formats:
- `optimize: false` - disable optimization
- `optimize: true` - enable optimization with minification
- `optimize: { minify: false }` - enable optimization without
minification
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This commit is contained in:
parent
acb27ef9e9
commit
89cbfc7b2d
@ -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`
|
||||
<head>
|
||||
<link rel="stylesheet" href="./src/index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="hover:flex">Hello, world!</div>
|
||||
</body>
|
||||
`,
|
||||
'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`
|
||||
<head>
|
||||
<link rel="stylesheet" href="./src/index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="hover:flex">Hello, world!</div>
|
||||
</body>
|
||||
`,
|
||||
'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;')
|
||||
},
|
||||
)
|
||||
|
||||
@ -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 },
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
@ -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<string, Root> = 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
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user