[v4] Make CSS optimization and minification configurable (#13130)
* only run Lightning CSS when passing `--minify` to the CLI
* only optimize the CSS when creating a production build
* add `optimize` option to PostCSS plugin
- The optimize option can be set to `true`, which will optimize
(unnesting, adding browser prefixes, lowering values) and minify
- The optimize option can also be set to `{ minify: false }`, which will
optimize but not minify.
* default `optimize` option to the true for `NODE_ENV=production`
* add `--optimize` flag to CLI
This will only optimize the CSS output without minification.
* update `--minify` description
* update changelog
This commit is contained in:
parent
7132875d02
commit
c550a62be4
5 changed files with 51 additions and 16 deletions
|
|
@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Added
|
||||
|
||||
- Add Android builds ([#13115](https://github.com/tailwindlabs/tailwindcss/pull/13115))
|
||||
- Make CSS optimization and minification configurable ([#13130](https://github.com/tailwindlabs/tailwindcss/pull/13130))
|
||||
|
||||
## [4.0.0-alpha.6] - 2024-03-07
|
||||
|
||||
|
|
|
|||
|
|
@ -46,9 +46,13 @@ export function options() {
|
|||
},
|
||||
'--minify': {
|
||||
type: 'boolean',
|
||||
description: 'Minify the output',
|
||||
description: 'Optimize and minify the output',
|
||||
alias: '-m',
|
||||
},
|
||||
'--optimize': {
|
||||
type: 'boolean',
|
||||
description: 'Optimize the output without minifying',
|
||||
},
|
||||
'--cwd': {
|
||||
type: 'string',
|
||||
description: 'The current working directory',
|
||||
|
|
@ -96,10 +100,15 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
)
|
||||
|
||||
// Compile the input
|
||||
let result = optimizeCss(compile(input, candidates), {
|
||||
file: args['--input'] ?? 'input.css',
|
||||
minify: args['--minify'],
|
||||
})
|
||||
let result = compile(input, candidates)
|
||||
|
||||
// Optimize the output
|
||||
if (args['--minify'] || args['--optimize']) {
|
||||
result = optimizeCss(result, {
|
||||
file: args['--input'] ?? 'input.css',
|
||||
minify: args['--minify'] ?? false,
|
||||
})
|
||||
}
|
||||
|
||||
// Write the output
|
||||
if (args['--output']) {
|
||||
|
|
@ -184,10 +193,15 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
}
|
||||
|
||||
// Compile the input
|
||||
let result = optimizeCss(compile(input, candidates), {
|
||||
file: args['--input'] ?? 'input.css',
|
||||
minify: args['--minify'],
|
||||
})
|
||||
let result = compile(input, candidates)
|
||||
|
||||
// Optimize the output
|
||||
if (args['--minify'] || args['--optimize']) {
|
||||
result = optimizeCss(result, {
|
||||
file: args['--input'] ?? 'input.css',
|
||||
minify: args['--minify'] ?? false,
|
||||
})
|
||||
}
|
||||
|
||||
// Write the output
|
||||
if (args['--output']) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ beforeEach(async () => {
|
|||
})
|
||||
|
||||
test("`@import 'tailwindcss'` is replaced with the generated CSS", async () => {
|
||||
let processor = postcss([tailwindcss({ base: `${__dirname}/fixtures/example-project` })])
|
||||
let processor = postcss([
|
||||
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
||||
])
|
||||
|
||||
let result = await processor.process(`@import 'tailwindcss'`, { from: INPUT_CSS_PATH })
|
||||
|
||||
|
|
@ -47,7 +49,9 @@ test("`@import 'tailwindcss'` is replaced with the generated CSS", async () => {
|
|||
})
|
||||
|
||||
test('output is optimized by Lightning CSS', async () => {
|
||||
let processor = postcss([tailwindcss({ base: `${__dirname}/fixtures/example-project` })])
|
||||
let processor = postcss([
|
||||
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
||||
])
|
||||
|
||||
// `@apply` is used because Lightning is skipped if neither `@tailwind` nor
|
||||
// `@apply` is used.
|
||||
|
|
@ -82,7 +86,9 @@ test('output is optimized by Lightning CSS', async () => {
|
|||
})
|
||||
|
||||
test('@apply can be used without emitting the theme in the CSS file', async () => {
|
||||
let processor = postcss([tailwindcss({ base: `${__dirname}/fixtures/example-project` })])
|
||||
let processor = postcss([
|
||||
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
||||
])
|
||||
|
||||
// `@apply` is used because Lightning is skipped if neither `@tailwind` nor
|
||||
// `@apply` is used.
|
||||
|
|
@ -112,7 +118,7 @@ describe('processing without specifying a base path', () => {
|
|||
afterEach(() => unlink(filepath))
|
||||
|
||||
test('the current working directory is used by default', async () => {
|
||||
let processor = postcss([tailwindcss()])
|
||||
let processor = postcss([tailwindcss({ optimize: { minify: false } })])
|
||||
|
||||
let result = await processor.process(`@import "tailwindcss"`, { from: INPUT_CSS_PATH })
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,14 @@ import { compile, optimizeCss } from 'tailwindcss'
|
|||
type PluginOptions = {
|
||||
// The base directory to scan for class candidates.
|
||||
base?: string
|
||||
|
||||
// Optimize the output CSS.
|
||||
optimize?: boolean | { minify?: boolean }
|
||||
}
|
||||
|
||||
function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
|
||||
let base = opts.base ?? process.cwd()
|
||||
let optimize = opts.optimize ?? process.env.NODE_ENV === 'production'
|
||||
|
||||
return {
|
||||
postcssPlugin: 'tailwindcss-v4',
|
||||
|
|
@ -38,7 +42,13 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
|
|||
|
||||
function replaceCss(css: string) {
|
||||
root.removeAll()
|
||||
root.append(postcss.parse(optimizeCss(css), result.opts))
|
||||
let output = css
|
||||
if (optimize) {
|
||||
output = optimizeCss(output, {
|
||||
minify: typeof optimize === 'object' ? optimize.minify : false,
|
||||
})
|
||||
}
|
||||
root.append(postcss.parse(output, result.opts))
|
||||
}
|
||||
|
||||
// No `@tailwind` means we don't have to look for candidates
|
||||
|
|
|
|||
|
|
@ -61,7 +61,11 @@ export default function tailwindcss(): Plugin[] {
|
|||
}
|
||||
|
||||
function generateCss(css: string) {
|
||||
return optimizeCss(compile(css, Array.from(candidates)), { minify })
|
||||
return compile(css, Array.from(candidates))
|
||||
}
|
||||
|
||||
function generateOptimizedCss(css: string) {
|
||||
return optimizeCss(generateCss(css), { minify })
|
||||
}
|
||||
|
||||
// In dev mode, there isn't a hook to signal that we've seen all files. We use
|
||||
|
|
@ -168,7 +172,7 @@ export default function tailwindcss(): Plugin[] {
|
|||
rawSource instanceof Uint8Array ? new TextDecoder().decode(rawSource) : rawSource
|
||||
|
||||
if (source.includes('@tailwind')) {
|
||||
item.source = generateCss(source)
|
||||
item.source = generateOptimizedCss(source)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue