diff --git a/lib/internal/fs/recursive_watch.js b/lib/internal/fs/recursive_watch.js index ed146fa28bed8d..1bddfaa85ebf18 100644 --- a/lib/internal/fs/recursive_watch.js +++ b/lib/internal/fs/recursive_watch.js @@ -202,6 +202,9 @@ class FSWatcher extends EventEmitter { this.emit('change', 'rename', pathRelative(this.#rootPath, file)); } else if (currentStats.isDirectory()) { this.#watchFolder(file); + } else if(!this.#watchingFile) { + // Watching a dircetory will trigger a change event for child files + this.emit('change', 'change', pathRelative(this.#rootPath, file)); } }); } diff --git a/test/parallel/test-fs-watch-recursive.js b/test/parallel/test-fs-watch-recursive.js index a4c22bfbd2ce11..e3612862d310fb 100644 --- a/test/parallel/test-fs-watch-recursive.js +++ b/test/parallel/test-fs-watch-recursive.js @@ -22,6 +22,37 @@ const tmpdir = require('../common/tmpdir'); const testDir = tmpdir.path; tmpdir.refresh(); +(async () => { + // Watch a folder and update an already existing file in it. + + const rootDirectory = fs.mkdtempSync(testDir + path.sep); + const testDirectory = path.join(rootDirectory, 'test-0'); + fs.mkdirSync(testDirectory); + + const testFile = path.join(testDirectory, 'file-1.txt'); + fs.writeFileSync(testFile, 'hello'); + + const watcher = fs.watch(testDirectory, { recursive: true }); + let watcherClosed = false; + watcher.on('change', common.mustCallAtLeast(function(event, filename) { + // libuv inconsistenly emits a rename event for the file we are watching + assert.ok(event === 'change' || event === 'rename'); + + if (filename === path.basename(testFile)) { + watcher.close(); + watcherClosed = true; + } + })); + + await setTimeout(common.platformTimeout(100)); + fs.writeFileSync(testFile, 'hello'); + + process.once('exit', function() { + assert(watcherClosed, 'watcher Object was not closed'); + }); +})().then(common.mustCall()); + + (async () => { // Add a file to already watching folder