1import chalk from 'chalk'; 2import { watchFile } from 'fs'; 3import path from 'path'; 4import resolveFrom from 'resolve-from'; 5 6import * as Log from '../log'; 7import { memoize } from './fn'; 8 9/** Observes and reports file changes. */ 10export class FileNotifier { 11 constructor( 12 /** Project root to resolve the module IDs relative to. */ 13 private projectRoot: string, 14 /** List of module IDs sorted by priority. Only the first file that exists will be observed. */ 15 private moduleIds: string[] 16 ) {} 17 18 /** Get the file in the project. */ 19 private resolveFilePath(): string | undefined { 20 for (const moduleId of this.moduleIds) { 21 const filePath = resolveFrom.silent(this.projectRoot, moduleId); 22 if (filePath) { 23 return filePath; 24 } 25 } 26 return null; 27 } 28 29 public startObserving() { 30 const configPath = this.resolveFilePath(); 31 if (configPath) { 32 return this.watchFile(configPath); 33 } 34 return configPath; 35 } 36 37 /** Watch the file and warn to reload the CLI if it changes. */ 38 public watchFile = memoize(this.startWatchingFile.bind(this)); 39 40 private startWatchingFile(filePath: string): string { 41 const configName = path.relative(this.projectRoot, filePath); 42 watchFile(filePath, (cur: any, prev: any) => { 43 if (prev.size || cur.size) { 44 Log.log( 45 `\u203A Detected a change in ${chalk.bold( 46 configName 47 )}. Restart the server to see the new results.` 48 ); 49 } 50 }); 51 return filePath; 52 } 53} 54