diff --git a/packages/babel-cli/src/babel/dir.ts b/packages/babel-cli/src/babel/dir.ts index c65536a3e93f..2585951af31a 100644 --- a/packages/babel-cli/src/babel/dir.ts +++ b/packages/babel-cli/src/babel/dir.ts @@ -225,6 +225,8 @@ export default async function ({ watcher.watch(filenameOrDir); }); + watcher.startWatcher(); + watcher.onFilesChange(async filenames => { processing++; if (startTime === null) startTime = process.hrtime(); diff --git a/packages/babel-cli/src/babel/file.ts b/packages/babel-cli/src/babel/file.ts index a5d6aca79556..83f2912d44d3 100644 --- a/packages/babel-cli/src/babel/file.ts +++ b/packages/babel-cli/src/babel/file.ts @@ -201,6 +201,8 @@ export default async function ({ if (cliOptions.watch) { filenames.forEach(watcher.watch); + watcher.startWatcher(); + watcher.onFilesChange((changes, event, cause) => { const actionableChange = changes.some( filename => diff --git a/packages/babel-cli/src/babel/watcher.ts b/packages/babel-cli/src/babel/watcher.ts index 0c1d3756984e..be4ff00b921f 100644 --- a/packages/babel-cli/src/babel/watcher.ts +++ b/packages/babel-cli/src/babel/watcher.ts @@ -6,6 +6,8 @@ const depToFiles = new Map>(); let isWatchMode = false; let watcher; +const watchQueue = new Set(); +let hasStarted = false; export function enable({ enableGlobbing }: { enableGlobbing: boolean }) { isWatchMode = true; @@ -25,6 +27,19 @@ export function enable({ enableGlobbing }: { enableGlobbing: boolean }) { watcher.on("unlink", unwatchFile); } +export function startWatcher() { + hasStarted = true; + + for (const dep of watchQueue) { + watcher.add(dep); + } + watchQueue.clear(); + + watcher.on("ready", () => { + console.log("The watcher is ready."); + }); +} + export function watch(filename: string): void { if (!isWatchMode) { throw new Error( @@ -32,7 +47,11 @@ export function watch(filename: string): void { ); } - watcher.add(path.resolve(filename)); + if (!hasStarted) { + watchQueue.add(path.resolve(filename)); + } else { + watcher.add(path.resolve(filename)); + } } /** @@ -86,7 +105,11 @@ export function updateExternalDependencies( if (!depToFiles.has(dep)) { depToFiles.set(dep, new Set()); - watcher.add(dep); + if (!hasStarted) { + watchQueue.add(dep); + } else { + watcher.add(dep); + } } depToFiles.get(dep).add(absFilename); } @@ -100,7 +123,11 @@ function removeFileDependency(filename: string, dep: string) { if (depToFiles.get(dep).size === 0) { depToFiles.delete(dep); - watcher.unwatch(dep); + if (!hasStarted) { + watchQueue.delete(dep); + } else { + watcher.unwatch(dep); + } } } diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/executor.js b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/executor.js index bd72e2589b54..3a81f1a55c40 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/executor.js +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/executor.js @@ -11,10 +11,11 @@ const run = (async function* () { assert.match(files[1], /src[\\/]main.js -> lib[\\/]main.js/); assert.match(yield, /Successfully compiled 2 files with Babel \(\d+ms\)\./); + assert.equal(yield, "The watcher is ready."); + logFile("lib/index.js"); logFile("lib/main.js"); - // wait 2s for watcher setup - await new Promise(resolve => setTimeout(resolve, 2000)); + fs.writeFileSync("./file.txt", "Updated!"); files = [yield, yield].sort(); diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/stdout.txt b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/stdout.txt index 665259ace1e0..c41bfa2d44f1 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/stdout.txt +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch --verbose with external dependencies/stdout.txt @@ -1,6 +1,7 @@ BATCHED(0) src/index.js -> lib/index.js BATCHED(0) src/main.js -> lib/main.js Successfully compiled 2 files with Babel (123ms). +The watcher is ready. EXECUTOR lib/index.js "let str = /"Hi :)/";" EXECUTOR lib/main.js "console.log(/"Hi :)/");" BATCHED(1) src/index.js -> lib/index.js diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/executor.js b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/executor.js index c1ea9dc5a81c..db1c3be77eb6 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/executor.js +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/executor.js @@ -8,8 +8,8 @@ if (!assert.match) assert.match = (val, re) => assert(re.test(val)); const run = (async function* () { assert.match(yield, /Successfully compiled 4 files with Babel \(\d+ms\)\./); - // wait 2s for watcher setup - await new Promise(resolve => setTimeout(resolve, 2000)); + assert.equal(yield, "The watcher is ready."); + // update ./module1/src/index.js fs.writeFileSync( "./module1/src/index.js", diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/stdout.txt b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/stdout.txt index 8afbc224e55b..a35690cfc579 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/stdout.txt +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch multiple dir/stdout.txt @@ -1,2 +1,3 @@ Successfully compiled 4 files with Babel (123ms). +The watcher is ready. Successfully compiled 1 file with Babel (123ms). diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/executor.js b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/executor.js index 3f56c3749501..514b8a061bd3 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/executor.js +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/executor.js @@ -8,10 +8,11 @@ if (!assert.match) assert.match = (val, re) => assert(re.test(val)); const run = (async function* () { assert.match(yield, /Successfully compiled 2 files with Babel \(\d+ms\)\./); + assert.equal(yield, "The watcher is ready."); + logFile("lib/index.js"); logFile("lib/main.js"); - // wait 2s for watcher setup - await new Promise(resolve => setTimeout(resolve, 2000)); + fs.writeFileSync("./file.txt", "Updated!"); assert.match(yield, /Successfully compiled 2 files with Babel \(\d+ms\)\./); diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/stdout.txt b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/stdout.txt index eef2fd0d7c1c..db47d6dc9e77 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/stdout.txt +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --watch with external dependencies/stdout.txt @@ -1,4 +1,5 @@ Successfully compiled 2 files with Babel (123ms). +The watcher is ready. EXECUTOR lib/index.js "let str = /"Hi :)/";" EXECUTOR lib/main.js "console.log(/"Hi :)/");" Successfully compiled 2 files with Babel (123ms).