mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2026-02-01 17:26:34 +00:00
Add incremental rebuilds to @tailwindcss/cli (#13169)
* ensure the root CSS file part of the `cssImportPaths` * add incremental rebuilds to `@tailwindcss/cli` * update changelog
This commit is contained in:
parent
d230f2e13b
commit
a458e5ddda
@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Replace `--radius-none` and `--radius-full` theme values with static `rounded-none` and `rounded-full` utilities ([#13186](https://github.com/tailwindlabs/tailwindcss/pull/13186))
|
||||
|
||||
### Added
|
||||
|
||||
- Improve performance of incremental rebuilds for `@tailwindcss/cli` ([#13169](https://github.com/tailwindlabs/tailwindcss/pull/13169))
|
||||
|
||||
## [4.0.0-alpha.7] - 2024-03-08
|
||||
|
||||
### Added
|
||||
|
||||
@ -1,12 +1,5 @@
|
||||
import watcher from '@parcel/watcher'
|
||||
import {
|
||||
IO,
|
||||
Parsing,
|
||||
clearCache,
|
||||
scanDir,
|
||||
scanFiles,
|
||||
type ChangedContent,
|
||||
} from '@tailwindcss/oxide'
|
||||
import { IO, Parsing, scanDir, scanFiles, type ChangedContent } from '@tailwindcss/oxide'
|
||||
import { existsSync } from 'node:fs'
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
@ -99,24 +92,41 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
||||
args['--input'] ?? base,
|
||||
)
|
||||
|
||||
let previous = {
|
||||
css: '',
|
||||
optimizedCss: '',
|
||||
}
|
||||
|
||||
async function write(css: string, args: Result<ReturnType<typeof options>>) {
|
||||
let output = css
|
||||
|
||||
// Optimize the output
|
||||
if (args['--minify'] || args['--optimize']) {
|
||||
if (css !== previous.css) {
|
||||
let optimizedCss = optimizeCss(css, {
|
||||
file: args['--input'] ?? 'input.css',
|
||||
minify: args['--minify'] ?? false,
|
||||
})
|
||||
previous.css = css
|
||||
previous.optimizedCss = optimizedCss
|
||||
output = optimizedCss
|
||||
} else {
|
||||
output = previous.optimizedCss
|
||||
}
|
||||
}
|
||||
|
||||
// Write the output
|
||||
if (args['--output']) {
|
||||
await outputFile(args['--output'], output)
|
||||
} else {
|
||||
println(output)
|
||||
}
|
||||
}
|
||||
|
||||
// Compile the input
|
||||
let { build } = compile(input)
|
||||
let result = build(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']) {
|
||||
await outputFile(args['--output'], result)
|
||||
} else {
|
||||
println(result)
|
||||
}
|
||||
await write(build(candidates), args)
|
||||
|
||||
let end = process.hrtime.bigint()
|
||||
eprintln(header())
|
||||
@ -162,26 +172,14 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
||||
// Re-compile the input
|
||||
let start = process.hrtime.bigint()
|
||||
|
||||
// Track the compiled CSS
|
||||
let compiledCss = ''
|
||||
|
||||
// Scan the entire `base` directory for full rebuilds.
|
||||
if (rebuildStrategy === 'full') {
|
||||
// Clear the cache because we need to re-scan the entire directory.
|
||||
clearCache()
|
||||
|
||||
// Re-scan the directory to get the new `candidates`.
|
||||
candidates = scanDir({ base }).candidates
|
||||
}
|
||||
|
||||
// Scan changed files only for incremental rebuilds.
|
||||
else if (rebuildStrategy === 'incremental') {
|
||||
let uniqueCandidates = new Set(candidates)
|
||||
for (let candidate of scanFiles(changedFiles, IO.Sequential | Parsing.Sequential)) {
|
||||
uniqueCandidates.add(candidate)
|
||||
}
|
||||
candidates = Array.from(uniqueCandidates)
|
||||
}
|
||||
|
||||
// Resolve the input
|
||||
if (rebuildStrategy === 'full') {
|
||||
// Collect the new `input` and `cssImportPaths`.
|
||||
;[input, cssImportPaths] = await handleImports(
|
||||
args['--input']
|
||||
@ -191,25 +189,19 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
||||
`,
|
||||
args['--input'] ?? base,
|
||||
)
|
||||
|
||||
build = compile(input).build
|
||||
compiledCss = build(candidates)
|
||||
}
|
||||
|
||||
// Compile the input
|
||||
result = compile(input).build(candidates)
|
||||
// Scan changed files only for incremental rebuilds.
|
||||
else if (rebuildStrategy === 'incremental') {
|
||||
let newCandidates = scanFiles(changedFiles, IO.Sequential | Parsing.Sequential)
|
||||
|
||||
// Optimize the output
|
||||
if (args['--minify'] || args['--optimize']) {
|
||||
result = optimizeCss(result, {
|
||||
file: args['--input'] ?? 'input.css',
|
||||
minify: args['--minify'] ?? false,
|
||||
})
|
||||
compiledCss = build(newCandidates)
|
||||
}
|
||||
|
||||
// Write the output
|
||||
if (args['--output']) {
|
||||
await outputFile(args['--output'], result)
|
||||
} else {
|
||||
println(result)
|
||||
}
|
||||
await write(compiledCss, args)
|
||||
|
||||
let end = process.hrtime.bigint()
|
||||
eprintln(`Done in ${formatDuration(end - start)}`)
|
||||
@ -244,7 +236,9 @@ function handleImports(
|
||||
// Relevant specification:
|
||||
// - CSS Import Resolve: https://csstools.github.io/css-import-resolve/
|
||||
|
||||
if (!input.includes('@import')) return [input, []]
|
||||
if (!input.includes('@import')) {
|
||||
return [input, [file]]
|
||||
}
|
||||
|
||||
return postcss()
|
||||
.use(atImport())
|
||||
@ -254,6 +248,8 @@ function handleImports(
|
||||
|
||||
// Use `result.messages` to get the imported files. This also includes the
|
||||
// current file itself.
|
||||
result.messages.filter((msg) => msg.type === 'postcss-import').map((msg) => msg.file),
|
||||
[file].concat(
|
||||
result.messages.filter((msg) => msg.type === 'dependency').map((msg) => msg.file),
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user