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,24 +92,42 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
9992 args [ '--input' ] ?? base ,
10093 )
10194
102- // Compile the input
103- let result = compile ( input , candidates ) . css
104-
105- // Optimize the output
106- if ( args [ '--minify' ] || args [ '--optimize' ] ) {
107- result = optimizeCss ( result , {
108- file : args [ '--input' ] ?? 'input.css' ,
109- minify : args [ '--minify' ] ?? false ,
110- } )
95+ let previous = {
96+ css : '' ,
97+ optimizedCss : '' ,
11198 }
11299
113- // Write the output
114- if ( args [ '--output' ] ) {
115- await outputFile ( args [ '--output' ] , result )
116- } else {
117- 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+ }
118124 }
119125
126+ // Compile the input
127+ let result = compile ( input , candidates )
128+
129+ await write ( result . css , args )
130+
120131 let end = process . hrtime . bigint ( )
121132 eprintln ( header ( ) )
122133 eprintln ( )
@@ -161,26 +172,14 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
161172 // Re-compile the input
162173 let start = process . hrtime . bigint ( )
163174
175+ // Track the compiled CSS
176+ let compiledCss = ''
177+
164178 // Scan the entire `base` directory for full rebuilds.
165179 if ( rebuildStrategy === 'full' ) {
166- // Clear the cache because we need to re-scan the entire directory.
167- clearCache ( )
168-
169180 // Re-scan the directory to get the new `candidates`.
170181 candidates = scanDir ( { base } ) . candidates
171- }
172-
173- // Scan changed files only for incremental rebuilds.
174- else if ( rebuildStrategy === 'incremental' ) {
175- let uniqueCandidates = new Set ( candidates )
176- for ( let candidate of scanFiles ( changedFiles , IO . Sequential | Parsing . Sequential ) ) {
177- uniqueCandidates . add ( candidate )
178- }
179- candidates = Array . from ( uniqueCandidates )
180- }
181182
182- // Resolve the input
183- if ( rebuildStrategy === 'full' ) {
184183 // Collect the new `input` and `cssImportPaths`.
185184 ; [ input , cssImportPaths ] = await handleImports (
186185 args [ '--input' ]
@@ -190,25 +189,19 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
190189 ` ,
191190 args [ '--input' ] ?? base ,
192191 )
192+
193+ result = compile ( input , candidates )
194+ compiledCss = result . css
193195 }
194196
195- // Compile the input
196- let result = compile ( input , candidates ) . css
197+ // Scan changed files only for incremental rebuilds.
198+ else if ( rebuildStrategy === 'incremental' ) {
199+ let newCandidates = scanFiles ( changedFiles , IO . Sequential | Parsing . Sequential )
197200
198- // Optimize the output
199- if ( args [ '--minify' ] || args [ '--optimize' ] ) {
200- result = optimizeCss ( result , {
201- file : args [ '--input' ] ?? 'input.css' ,
202- minify : args [ '--minify' ] ?? false ,
203- } )
201+ compiledCss = result . rebuild ( newCandidates )
204202 }
205203
206- // Write the output
207- if ( args [ '--output' ] ) {
208- await outputFile ( args [ '--output' ] , result )
209- } else {
210- println ( result )
211- }
204+ await write ( compiledCss , args )
212205
213206 let end = process . hrtime . bigint ( )
214207 eprintln ( `Done in ${ formatDuration ( end - start ) } ` )
@@ -243,7 +236,9 @@ function handleImports(
243236 // Relevant specification:
244237 // - CSS Import Resolve: https://csstools.github.io/css-import-resolve/
245238
246- if ( ! input . includes ( '@import' ) ) return [ input , [ ] ]
239+ if ( ! input . includes ( '@import' ) ) {
240+ return [ input , [ file ] ]
241+ }
247242
248243 return postcss ( )
249244 . use ( atImport ( ) )
@@ -253,6 +248,8 @@ function handleImports(
253248
254249 // Use `result.messages` to get the imported files. This also includes the
255250 // current file itself.
256- 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+ ) ,
257254 ] )
258255}
0 commit comments