diff --git a/lib/fs.js b/lib/fs.js index 4ffc55c8abbd70..bd9aed2b4e00f9 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -2299,7 +2299,7 @@ function watch(filename, options, listener) { let watcher; - // TODO(anonrig): Remove this when/if libuv supports it. + // TODO(anonrig): Remove non-native watcher when/if libuv supports recursive. // As of November 2022, libuv does not support recursive file watch on all platforms, // e.g. Linux due to the limitations of inotify. if (options.recursive && !isOSX && !isWindows) { diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 9f5adb62113215..1dbe81ae3aadd9 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -925,7 +925,7 @@ async function* _watch(filename, options = kEmptyObject) { if (options.recursive != null) { validateBoolean(options.recursive, 'options.recursive'); - // TODO(anonrig): Remove this when/if libuv supports it. + // TODO(anonrig): Remove non-native watcher when/if libuv supports recursive. // As of November 2022, libuv does not support recursive file watch on all platforms, // e.g. Linux due to the limitations of inotify. if (options.recursive && !isOSX && !isWindows) { diff --git a/lib/internal/fs/recursive_watch.js b/lib/internal/fs/recursive_watch.js index 197c4f1a461724..ed146fa28bed8d 100644 --- a/lib/internal/fs/recursive_watch.js +++ b/lib/internal/fs/recursive_watch.js @@ -23,7 +23,12 @@ const { getValidatedPath } = require('internal/fs/utils'); const { kFSWatchStart, StatWatcher } = require('internal/fs/watchers'); const { kEmptyObject } = require('internal/util'); const { validateBoolean, validateAbortSignal } = require('internal/validators'); -const path = require('path'); +const { + basename: pathBasename, + join: pathJoin, + relative: pathRelative, + resolve: pathResolve, +} = require('path'); let internalSync; let internalPromises; @@ -45,7 +50,7 @@ async function traverse(dir, files = new SafeMap(), symbolicLinks = new SafeSet( const subdirectories = []; for await (const file of filenames) { - const f = path.join(dir, file.name); + const f = pathJoin(dir, file.name); files.set(f, file); @@ -67,7 +72,7 @@ class FSWatcher extends EventEmitter { #closed = false; #files = new SafeMap(); #symbolicFiles = new SafeSet(); - #rootPath = path.resolve(); + #rootPath = pathResolve(); #watchingFile = false; constructor(options = kEmptyObject) { @@ -140,10 +145,10 @@ class FSWatcher extends EventEmitter { break; } - const f = path.join(folder, file.name); + const f = pathJoin(folder, file.name); if (!this.#files.has(f)) { - this.emit('change', 'rename', path.relative(this.#rootPath, f)); + this.emit('change', 'rename', pathRelative(this.#rootPath, f)); if (file.isSymbolicLink()) { this.#symbolicFiles.add(f); @@ -186,15 +191,15 @@ class FSWatcher extends EventEmitter { if (currentStats.birthtimeMs === 0 && previousStats.birthtimeMs !== 0) { // The file is now deleted this.#files.delete(file); - this.emit('change', 'rename', path.relative(this.#rootPath, file)); + this.emit('change', 'rename', pathRelative(this.#rootPath, file)); this.#unwatchFiles(file); } else if (file === this.#rootPath && this.#watchingFile) { // This case will only be triggered when watching a file with fs.watch - this.emit('change', 'change', path.basename(file)); + this.emit('change', 'change', pathBasename(file)); } else if (this.#symbolicFiles.has(file)) { // Stats from watchFile does not return correct value for currentStats.isSymbolicLink() // Since it is only valid when using fs.lstat(). Therefore, check the existing symbolic files. - this.emit('change', 'rename', path.relative(this.#rootPath, file)); + this.emit('change', 'rename', pathRelative(this.#rootPath, file)); } else if (currentStats.isDirectory()) { this.#watchFolder(file); } @@ -202,7 +207,7 @@ class FSWatcher extends EventEmitter { } [kFSWatchStart](filename) { - filename = path.resolve(getValidatedPath(filename)); + filename = pathResolve(getValidatedPath(filename)); try { const file = lazyLoadFsSync().statSync(filename);