11import watcher from '@parcel/watcher'
2- import {
3- IO ,
4- Parsing ,
5- clearCache ,
6- scanDir ,
7- scanFiles ,
8- type ChangedContent ,
9- } from '@tailwindcss/oxide'
2+ import { IO , Parsing , scanDir , scanFiles , type ChangedContent } from '@tailwindcss/oxide'
103import { existsSync } from 'node:fs'
114import fs from 'node:fs/promises'
125import path from 'node:path'
@@ -99,25 +92,42 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
9992 args [ '--input' ] ?? base ,
10093 )
10194
102- // Compile the input
103- let { build } = compile ( input )
104- let result = build ( candidates )
105-
106- // Optimize the output
107- if ( args [ '--minify' ] || args [ '--optimize' ] ) {
108- result = optimizeCss ( result , {
109- file : args [ '--input' ] ?? 'input.css' ,
110- minify : args [ '--minify' ] ?? false ,
111- } )
95+ let previous = {
96+ css : '' ,
97+ optimizedCss : '' ,
11298 }
11399
114- // Write the output
115- if ( args [ '--output' ] ) {
116- await outputFile ( args [ '--output' ] , result )
117- } else {
118- println ( result )
100+ async function write ( css : string , args : Result < ReturnType < typeof options > > ) {
101+ let output = css
102+
103+ // Optimize the output
104+ if ( args [ '--minify' ] || args [ '--optimize' ] ) {
105+ if ( css !== previous . css ) {
106+ let optimizedCss = optimizeCss ( css , {
107+ file : args [ '--input' ] ?? 'input.css' ,
108+ minify : args [ '--minify' ] ?? false ,
109+ } )
110+ previous . css = css
111+ previous . optimizedCss = optimizedCss
112+ output = optimizedCss
113+ } else {
114+ output = previous . optimizedCss
115+ }
116+ }
117+
118+ // Write the output
119+ if ( args [ '--output' ] ) {
120+ await outputFile ( args [ '--output' ] , output )
121+ } else {
122+ println ( output )
123+ }
119124 }
120125
126+ // Compile the input
127+ let { build } = compile ( input )
128+
129+ await write ( build ( candidates ) , args )
130+
121131 let end = process . hrtime . bigint ( )
122132 eprintln ( header ( ) )
123133 eprintln ( )
@@ -162,26 +172,14 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
162172 // Re-compile the input
163173 let start = process . hrtime . bigint ( )
164174
175+ // Track the compiled CSS
176+ let compiledCss = ''
177+
165178 // Scan the entire `base` directory for full rebuilds.
166179 if ( rebuildStrategy === 'full' ) {
167- // Clear the cache because we need to re-scan the entire directory.
168- clearCache ( )
169-
170180 // Re-scan the directory to get the new `candidates`.
171181 candidates = scanDir ( { base } ) . candidates
172- }
173-
174- // Scan changed files only for incremental rebuilds.
175- else if ( rebuildStrategy === 'incremental' ) {
176- let uniqueCandidates = new Set ( candidates )
177- for ( let candidate of scanFiles ( changedFiles , IO . Sequential | Parsing . Sequential ) ) {
178- uniqueCandidates . add ( candidate )
179- }
180- candidates = Array . from ( uniqueCandidates )
181- }
182182
183- // Resolve the input
184- if ( rebuildStrategy === 'full' ) {
185183 // Collect the new `input` and `cssImportPaths`.
186184 ; [ input , cssImportPaths ] = await handleImports (
187185 args [ '--input' ]
@@ -191,25 +189,19 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
191189 ` ,
192190 args [ '--input' ] ?? base ,
193191 )
192+
193+ build = compile ( input ) . build
194+ compiledCss = build ( candidates )
194195 }
195196
196- // Compile the input
197- result = compile ( input ) . build ( candidates )
197+ // Scan changed files only for incremental rebuilds.
198+ else if ( rebuildStrategy === 'incremental' ) {
199+ let newCandidates = scanFiles ( changedFiles , IO . Sequential | Parsing . Sequential )
198200
199- // Optimize the output
200- if ( args [ '--minify' ] || args [ '--optimize' ] ) {
201- result = optimizeCss ( result , {
202- file : args [ '--input' ] ?? 'input.css' ,
203- minify : args [ '--minify' ] ?? false ,
204- } )
201+ compiledCss = build ( newCandidates )
205202 }
206203
207- // Write the output
208- if ( args [ '--output' ] ) {
209- await outputFile ( args [ '--output' ] , result )
210- } else {
211- println ( result )
212- }
204+ await write ( compiledCss , args )
213205
214206 let end = process . hrtime . bigint ( )
215207 eprintln ( `Done in ${ formatDuration ( end - start ) } ` )
@@ -244,7 +236,9 @@ function handleImports(
244236 // Relevant specification:
245237 // - CSS Import Resolve: https://csstools.github.io/css-import-resolve/
246238
247- if ( ! input . includes ( '@import' ) ) return [ input , [ ] ]
239+ if ( ! input . includes ( '@import' ) ) {
240+ return [ input , [ file ] ]
241+ }
248242
249243 return postcss ( )
250244 . use ( atImport ( ) )
@@ -254,6 +248,8 @@ function handleImports(
254248
255249 // Use `result.messages` to get the imported files. This also includes the
256250 // current file itself.
257- result . messages . filter ( ( msg ) => msg . type === 'postcss-import' ) . map ( ( msg ) => msg . file ) ,
251+ [ file ] . concat (
252+ result . messages . filter ( ( msg ) => msg . type === 'dependency' ) . map ( ( msg ) => msg . file ) ,
253+ ) ,
258254 ] )
259255}
0 commit comments