@@ -130,50 +130,53 @@ export class MemoryBuildCache<State> implements DevBuildCache<State> {
130130 }
131131 }
132132
133- let entry = pathname . startsWith ( "/" ) ? pathname . slice ( 1 ) : pathname ;
134- entry = path . join ( this . #config. staticDir , entry ) ;
135- const relative = path . relative ( this . #config. staticDir , entry ) ;
136- if ( relative . startsWith ( ".." ) ) {
137- throw new Error (
138- `Processed file resolved outside of static dir ${ entry } ` ,
133+ const stripped = pathname . startsWith ( "/" ) ? pathname . slice ( 1 ) : pathname ;
134+
135+ for ( const staticDir of this . #config. staticDir ) {
136+ const entry = path . join ( staticDir , stripped ) ;
137+ const relative = path . relative ( staticDir , entry ) ;
138+ if ( relative . startsWith ( ".." ) ) {
139+ throw new Error (
140+ `Processed file resolved outside of static dir ${ entry } ` ,
141+ ) ;
142+ }
143+
144+ // Might be a file that we still need to process
145+ const transformed = await this . #transformer. process (
146+ entry ,
147+ "development" ,
148+ this . #config. target ,
139149 ) ;
140- }
141150
142- // Might be a file that we still need to process
143- const transformed = await this . #transformer. process (
144- entry ,
145- "development" ,
146- this . #config. target ,
147- ) ;
151+ if ( transformed !== null ) {
152+ for ( let i = 0 ; i < transformed . length ; i ++ ) {
153+ const file = transformed [ i ] ;
154+ const rel = path . relative ( staticDir , file . path ) ;
155+ if ( rel . startsWith ( ".." ) ) {
156+ throw new Error (
157+ `Processed file resolved outside of static dir ${ file . path } ` ,
158+ ) ;
159+ }
160+ const filePn = new URL ( rel , "http://localhost" ) . pathname ;
148161
149- if ( transformed !== null ) {
150- for ( let i = 0 ; i < transformed . length ; i ++ ) {
151- const file = transformed [ i ] ;
152- const relative = path . relative ( this . #config. staticDir , file . path ) ;
153- if ( relative . startsWith ( ".." ) ) {
154- throw new Error (
155- `Processed file resolved outside of static dir ${ file . path } ` ,
156- ) ;
162+ this . addProcessedFile ( filePn , file . content , null ) ;
157163 }
158- const pathname = new URL ( relative , "http://localhost" ) . pathname ;
159-
160- this . addProcessedFile ( pathname , file . content , null ) ;
161- }
162- if ( this . #processedFiles. has ( pathname ) ) {
163- return this . readFile ( pathname ) ;
164- }
165- } else {
166- try {
167- const filePath = path . join ( this . #config. staticDir , pathname ) ;
168- const relative = path . relative ( this . #config. staticDir , filePath ) ;
169- if ( ! relative . startsWith ( ".." ) && ( await Deno . stat ( filePath ) ) . isFile ) {
170- const pathname = new URL ( relative , "http://localhost" ) . pathname ;
171- this . addUnprocessedFile ( pathname , this . #config. staticDir ) ;
164+ if ( this . #processedFiles. has ( pathname ) ) {
172165 return this . readFile ( pathname ) ;
173166 }
174- } catch ( err ) {
175- if ( ! ( err instanceof Deno . errors . NotFound ) ) {
176- throw err ;
167+ } else {
168+ try {
169+ const filePath = path . join ( staticDir , pathname ) ;
170+ const rel = path . relative ( staticDir , filePath ) ;
171+ if ( ! rel . startsWith ( ".." ) && ( await Deno . stat ( filePath ) ) . isFile ) {
172+ const filePn = new URL ( rel , "http://localhost" ) . pathname ;
173+ this . addUnprocessedFile ( filePn , staticDir ) ;
174+ return this . readFile ( filePn ) ;
175+ }
176+ } catch ( err ) {
177+ if ( ! ( err instanceof Deno . errors . NotFound ) ) {
178+ throw err ;
179+ }
177180 }
178181 }
179182 }
@@ -303,9 +306,13 @@ export class DiskBuildCache<State> implements DevBuildCache<State> {
303306 }
304307
305308 async flush ( ) : Promise < void > {
306- const { staticDir, outDir, target, root } = this . #config;
309+ const { staticDir : staticDirs , outDir, target, root } = this . #config;
310+
311+ const seen = new Set < string > ( ) ;
312+
313+ for ( const staticDir of staticDirs ) {
314+ if ( ! ( await fsAdapter . isDirectory ( staticDir ) ) ) continue ;
307315
308- if ( await fsAdapter . isDirectory ( staticDir ) ) {
309316 const entries = fsAdapter . walk ( staticDir , {
310317 includeDirs : false ,
311318 includeFiles : true ,
@@ -332,12 +339,18 @@ export class DiskBuildCache<State> implements DevBuildCache<State> {
332339 const file = result [ i ] ;
333340 assertInDir ( file . path , staticDir ) ;
334341 const pathname = `/${ path . relative ( staticDir , file . path ) } ` ;
335- await this . addProcessedFile ( pathname , file . content , null ) ;
342+ if ( ! seen . has ( pathname ) ) {
343+ seen . add ( pathname ) ;
344+ await this . addProcessedFile ( pathname , file . content , null ) ;
345+ }
336346 }
337347 } else {
338348 const relative = path . relative ( staticDir , entry . path ) ;
339349 const pathname = `/${ relative } ` ;
340- this . addUnprocessedFile ( pathname , staticDir ) ;
350+ if ( ! seen . has ( pathname ) ) {
351+ seen . add ( pathname ) ;
352+ this . addUnprocessedFile ( pathname , staticDir ) ;
353+ }
341354 }
342355 }
343356 }
0 commit comments