node-watch
A wrapper and enhancements for fs.watch.
Installation
npm install node-watch
Example
var watch = require('node-watch');
watch('file_or_dir', { recursive: true }, function(evt, name) {
console.log('%s changed.', name);
});
Now it's fast to watch deep directories on macOS and Windows, since the recursive
option is natively supported except on Linux.
// watch the whole disk
watch('/', { recursive: true }, console.log);
Why?
- Some editors will generate temporary files which will cause the callback function to be triggered multiple times.
- The callback function will only be triggered once on watching a single file.
Missing an option to watch a directory recursively.- Recursive watch is not supported on Linux or in older versions of nodejs.
- Keep it simple, stupid.
Options
The usage and options of node-watch
are compatible with fs.watch.
persistent: Boolean
(default true)recursive: Boolean
(default false)encoding: String
(default 'utf8')
Extra options
-
filter: RegExp | Function
Return that matches the filter expression.
// filter with regular expression watch('./', { filter: /\.json$/ }); // filter with custom function watch('./', { filter: f => !/node_modules/.test(f) });
Each file and directory will be passed to the filter to determine whether it will then be passed to the callback function. Like
Array.filter
does inJavaScript
. There are three kinds of return values for filter function:true
: Will be passed to callback.false
: Will not be passed to callback.skip
: Same withfalse
, and skip to watch all its subdirectories.
On Linux, where the
recursive
option is not natively supported, it is more efficient to skip ignored directories by returning theskip
flag:watch('./', { recursive: true, filter(f, skip) { // skip node_modules if (/\/node_modules/.test(f)) return skip; // skip .git folder if (/\.git/.test(f)) return skip; // only watch for js files return /\.js$/.test(f); } });
If you prefer glob patterns you can use minimatch or picomatch together with filter:
const pm = require('picomatch'); let isMatch = pm('*.js'); watch('./', { filter: f => isMatch(f) });
-
delay: Number
(in ms, default 200)Delay time of the callback function.
// log after 5 seconds watch('./', { delay: 5000 }, console.log);
Events
The events provided by the callback function is either update
or remove
, which is less confusing to fs.watch
's rename
or change
.
watch('./', function(evt, name) {
if (evt == 'update') {
// on create or modify
}
if (evt == 'remove') {
// on delete
}
});
Watcher object
The watch function returns a fs.FSWatcher like object as the same as fs.watch
(>= v0.4.0).
Watcher events
let watcher = watch('./', { recursive: true });
watcher.on('change', function(evt, name) {
// callback
});
watcher.on('error', function(err) {
// handle error
});
watcher.on('ready', function() {
// the watcher is ready to respond to changes
});
Close
// close
watcher.close();
// is closed?
watcher.isClosed()
List of methods
.on
.once
.emit
.close
.listeners
.setMaxListeners
.getMaxListeners
Extra methods
.isClosed
detect if the watcher is closed.getWatchedPaths
get all the watched paths
Known issues
Windows, node < v4.2.5
- Failed to detect
remove
event - Failed to get deleted filename or directory name
MacOS, node 0.10.x
- Will emit double event if the directory name is of one single character.
Misc
1. Watch multiple files or directories in one place
watch(['file1', 'file2'], console.log);
2. Customize watch command line tool
#!/usr/bin/env node
// https://github.com/nodejs/node-v0.x-archive/issues/3211
require('epipebomb')();
let watcher = require('node-watch')(
process.argv[2] || './', { recursive: true }, console.log
);
process.on('SIGINT', watcher.close);
Monitoring chrome from disk:
$ watch / | grep -i chrome
3. Got ENOSPC error?
If you get ENOSPC error, but you actually have free disk space - it means that your OS watcher limit is too low and you probably want to recursively watch a big tree of files.
Follow this description to increase the limit: https://confluence.jetbrains.com/display/IDEADEV/Inotify+Watches+Limit
Alternatives
Contributors
Thanks goes to all wonderful people who have helped this project.
License
MIT
Copyright (c) 2012-2021 yuanchuan