@@ -56,49 +56,52 @@ const getEntrypoints = async (files: BuildTempatesResult[]) => {
5656 return Array . from ( entrypoints ) . filter ( Boolean ) ;
5757} ;
5858
59- const getWatchPaths = async ( files : BuildTempatesResult [ ] ) => {
59+ const getWatchDirectories = async ( files : BuildTempatesResult [ ] , depPaths : string [ ] ) => {
6060 const entrypoints = await getEntrypoints ( files ) ;
61- const paths = entrypoints . map ( ( path ) => dirname ( path ) ) ;
61+ const paths = [
62+ ...entrypoints . map ( ( path ) => dirname ( path ) ) ,
63+ ...depPaths . map ( ( path ) => dirname ( path ) )
64+ ] ;
6265 const uniquePaths = Array . from ( new Set ( paths ) ) ;
6366 const watchPaths = removeChildPaths ( uniquePaths ) ;
6467
6568 log . debug ( { watchPaths } ) ;
6669
67- return watchPaths ;
70+ return { entrypoints , watchPaths } ;
6871} ;
6972
70- // const mapDeps = async (files: BuildTempatesResult[]) => {
71- // const depPaths: string[] = [];
72- // const metaReads = files.map(async ({ metaPath }) => {
73- // log.debug({ exists: await exists(metaPath ?? ''), metaPath });
74-
75- // if (!metaPath || !(await exists(metaPath))) return null;
76- // const contents = await readFile(metaPath, 'utf-8');
77- // const metafile = JSON.parse(contents) as Metafile;
78- // const { outputs } = metafile;
79- // const result = new Map<string, Set<string>>();
80-
81- // Object.entries(outputs).forEach(([_, meat]) => {
82- // const { entryPoint, inputs } = meat;
83- // const resolvedEntry = resolve(originalCwd, entryPoint!);
84- // depPaths.push(resolvedEntry);
85-
86- // for (const dep of Object.keys(inputs)) {
87- // const resolvedDepPath = resolve(originalCwd, dep);
88- // const set = result.get(resolvedDepPath) ?? new Set();
73+ const mapDeps = async ( files : BuildTempatesResult [ ] ) => {
74+ const depPaths : string [ ] = [ ] ;
75+ const metaReads = files . map ( async ( { metaPath } ) => {
76+ log . debug ( { exists : await exists ( metaPath ?? '' ) , metaPath } ) ;
8977
90- // depPaths.push(resolvedDepPath);
91- // set.add(resolvedEntry);
92- // result.set(resolvedDepPath, set);
93- // }
94- // });
78+ if ( ! metaPath || ! ( await exists ( metaPath ) ) ) return null ;
79+ const contents = await readFile ( metaPath , 'utf-8' ) ;
80+ const metafile = JSON . parse ( contents ) as Metafile ;
81+ const { outputs } = metafile ;
82+ const result = new Map < string , Set < string > > ( ) ;
83+
84+ Object . entries ( outputs ) . forEach ( ( [ _ , meat ] ) => {
85+ const { entryPoint, inputs } = meat ;
86+ const resolvedEntry = resolve ( originalCwd , entryPoint ! ) ;
87+ depPaths . push ( resolvedEntry ) ;
88+
89+ for ( const dep of Object . keys ( inputs ) ) {
90+ const resolvedDepPath = resolve ( originalCwd , dep ) ;
91+ const set = result . get ( resolvedDepPath ) ?? new Set ( ) ;
92+
93+ depPaths . push ( resolvedDepPath ) ;
94+ set . add ( resolvedEntry ) ;
95+ result . set ( resolvedDepPath , set ) ;
96+ }
97+ } ) ;
9598
96- // return result;
97- // });
98- // const deps = (await Promise.all(metaReads)).filter(Boolean);
99+ return result ;
100+ } ) ;
101+ const deps = ( await Promise . all ( metaReads ) ) . filter ( Boolean ) ;
99102
100- // return { depPaths, deps };
101- // };
103+ return { depPaths, deps } ;
104+ } ;
102105
103106export const watch = async ( args : WatchArgs ) => {
104107 newline ( ) ;
@@ -107,22 +110,40 @@ export const watch = async (args: WatchArgs) => {
107110 const { common, files, server } = args ;
108111 const { argv } = common ;
109112 const extensions = [ '.css' , '.js' , '.jsx' , '.ts' , '.tsx' ] ;
110- const watchPaths = await getWatchPaths ( files ) ;
111-
112- // const { depPaths, deps: metaDeps } = await mapDeps(files);
113- // const templateDeps = new Map<string, Set<string>>();
114-
115- // for (const map of metaDeps) {
116- // map!.forEach((value, key) => templateDeps.set(key, value));
117- // }
113+ const { depPaths, deps : metaDeps } = await mapDeps ( files ) ;
114+ const dependencyPaths = depPaths . filter ( ( path ) => ! path . includes ( '/node_modules/' ) ) ;
115+ const { entrypoints, watchPaths : watchDirectories } = await getWatchDirectories (
116+ files ,
117+ dependencyPaths
118+ ) ;
119+ const templateDeps = new Map < string , Set < string > > ( ) ;
120+ const validFiles = Array . from ( new Set ( [ ...entrypoints , ...dependencyPaths ] ) ) ;
121+
122+ for ( const map of metaDeps ) {
123+ map ! . forEach ( ( value , key ) => templateDeps . set ( key , value ) ) ;
124+ }
125+
126+ log . info ( { validFiles } ) ;
127+
128+ const handler : watcher . SubscribeCallback = async ( _ , incoming ) => {
129+ // Note: We perform this filter in case someone has a dependency of a template,
130+ // or has templates, at a path that includes node_modules. We also don't any
131+ // non-template files having builds attempted on them, so check to make sure
132+ // the event path is in the set of files we want to watch, unless it's a create
133+ // event
134+ const events = incoming . filter ( ( event ) => {
135+ if ( event . path . includes ( '/node_modules/' ) ) return false ;
136+ if ( event . type !== 'create' ) return validFiles . includes ( event . path ) ;
137+ return true ;
138+ } ) ;
118139
119- const handler : watcher . SubscribeCallback = async ( _ , events ) => {
120140 const changedFiles = events
121141 . filter ( ( event ) => event . type !== 'create' && event . type !== 'delete' )
122142 . map ( ( e ) => e . path )
123143 . filter ( ( path ) => extensions . includes ( extname ( path ) ) ) ;
124- const templateFileNames = files . map ( ( file ) => file . fileName ) ;
125- const changedTemplates = changedFiles . filter ( ( file ) => templateFileNames . includes ( file ) ) ;
144+ const changedTemplates = changedFiles
145+ . flatMap ( ( file ) => [ ...( templateDeps . get ( file ) || [ ] ) ] )
146+ . filter ( Boolean ) ;
126147 const createdFiles = events
127148 . filter ( ( event ) => event . type === 'create' )
128149 . map ( ( e ) => e . path )
@@ -149,13 +170,16 @@ export const watch = async (args: WatchArgs) => {
149170 ) ;
150171
151172 deletedFiles . forEach ( ( path ) => {
152- const index = files . findIndex ( ( { fileName } ) => path === fileName ) ;
173+ let index : any = files . findIndex ( ( { fileName } ) => path === fileName ) ;
153174 if ( index === - 1 ) return ;
154175 const file = files [ index ] ;
155176 files . splice ( index , 1 ) ;
156177 // Note: Don't await either, we don't need to
157178 unlink ( file . compiledPath ) ;
158179 unlink ( `${ file . writePathBase } .js` ) ;
180+
181+ index = validFiles . find ( ( fileName ) => path === fileName ) ;
182+ if ( index > - 1 ) validFiles . splice ( index , 1 ) ;
159183 } ) ;
160184 }
161185
@@ -177,7 +201,11 @@ export const watch = async (args: WatchArgs) => {
177201 targetPath : path
178202 } ) ;
179203
204+ const mappedDeps = await mapDeps ( results ) ;
180205 files . push ( ...results ) ;
206+ validFiles . push (
207+ ...[ path , ...mappedDeps . depPaths . filter ( ( p ) => ! p . includes ( '/node_modules/' ) ) ]
208+ ) ;
181209
182210 await writePreviewDataFiles ( results ) ;
183211 } )
@@ -200,14 +228,9 @@ export const watch = async (args: WatchArgs) => {
200228 } ) ;
201229 } ;
202230
203- // const watchPathSet = new Set([
204- // ...depPaths.filter((path) => !path.includes('/node_modules/')).map((path) => dirname(path))
205- // ]);
206- // const watchPaths = removeChildPaths([...watchPathSet]);
207-
208- log . debug ( 'Watching Paths:' , watchPaths . sort ( ) ) ;
231+ log . debug ( 'Watching Paths:' , watchDirectories . sort ( ) ) ;
209232
210- const subPromises = watchPaths . map ( ( path ) => watcher . subscribe ( path , handler ) ) ;
233+ const subPromises = watchDirectories . map ( ( path ) => watcher . subscribe ( path , handler ) ) ;
211234 const subscriptions = await Promise . all ( subPromises ) ;
212235
213236 server . httpServer ! . on ( 'close' , ( ) => {
0 commit comments