# node-watch [![Status](https://travis-ci.org/yuanchuan/node-watch.svg?branch=master)](https://travis-ci.org/yuanchuan/node-watch "See test builds") A wrapper and enhancements for [fs.watch](http://nodejs.org/api/fs.html#fs_fs_watch_filename_options_listener). [![NPM](https://nodei.co/npm/node-watch.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/node-watch.png/) ## Installation ```bash npm install node-watch ``` ## Example ```js 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. ```js // 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](https://nodejs.org/dist/latest-v7.x/docs/api/fs.html#fs_fs_watch_filename_options_listener). * `persistent: Boolean` (default **true**) * `recursive: Boolean` (default **false**) * `encoding: String` (default **'utf8'**) **Extra options** * `filter: RegExp | Function` Return that matches the filter expression. ```js // filter with regular expression watch('./', { filter: /\.json$/ }); // filter with custom function watch('./', { filter: f => !/node_modules/.test(f) }); ``` * `delay: Number` (in ms, default **200**) Delay time of the callback function. ```js // 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`. ```js 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](https://nodejs.org/api/fs.html#fs_class_fs_fswatcher) like object as the same as `fs.watch` (>= v0.4.0). #### Watcher events ``` 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 ## Known issues **Windows** * Will output its parent directory when a new file/directory is created in a deep directory. **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 ```js watch(['file1', 'file2'], console.log); ``` #### 2. Customize watch command line tool ```js #!/usr/bin/env node // https://github.com/nodejs/node-v0.x-archive/issues/3211 require('epipebomb')(); var watcher = require('node-watch')( process.argv[2] || './', { recursive: true }, console.log ); process.on('SIGINT', watcher.close); ``` Monitoring chrome from disk: ```bash $ 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](https://confluence.jetbrains.com/display/IDEADEV/Inotify+Watches+Limit) ## Alternatives * [chokidar](https://github.com/paulmillr/chokidar) * [gaze](https://github.com/shama/gaze) * [mikeal/watch](https://github.com/mikeal/watch) ## Contributors Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)): | [
Yuan Chuan](http://yuanchuan.name)
[💻](https://github.com/yuanchuan/node-watch/commits?author=yuanchuan "Code") [📖](https://github.com/yuanchuan/node-watch/commits?author=yuanchuan "Documentation") [⚠️](https://github.com/yuanchuan/node-watch/commits?author=yuanchuan "Tests") | [
Greg Thornton](http://xdissent.com)
[💻](https://github.com/yuanchuan/node-watch/commits?author=xdissent "Code") [🤔](#ideas-xdissent "Ideas, Planning, & Feedback") | [
Amir Arad](https://github.com/amir-arad)
[💻](https://github.com/yuanchuan/node-watch/commits?author=amir-arad "Code") [📖](https://github.com/yuanchuan/node-watch/commits?author=amir-arad "Documentation") [⚠️](https://github.com/yuanchuan/node-watch/commits?author=amir-arad "Tests") | [
Gary Burgess](http://slipthrough.net)
[💻](https://github.com/yuanchuan/node-watch/commits?author=garyb "Code") | [
Peter deHaan](http://about.me/peterdehaan)
[💻](https://github.com/yuanchuan/node-watch/commits?author=pdehaan "Code") | [
kcliu](https://medium.com/@kcliu)
[💻](https://github.com/yuanchuan/node-watch/commits?author=kcliu "Code") | [
Hoovinator](https://github.com/crh3675)
[💬](#question-crh3675 "Answering Questions") | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | | [
Steve Shreeve](https://github.com/shreeve)
[💻](https://github.com/yuanchuan/node-watch/commits?author=shreeve "Code") | [
Blake Regalia](https://github.com/blake-regalia)
[💻](https://github.com/yuanchuan/node-watch/commits?author=blake-regalia "Code") | [
Mike Collins](https://github.com/intervalia)
[💻](https://github.com/yuanchuan/node-watch/commits?author=intervalia "Code") | [
Timo Tijhof](https://timotijhof.net)
[💻](https://github.com/yuanchuan/node-watch/commits?author=Krinkle "Code") | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! ## License MIT Copyright (c) 2012-2018 [yuanchuan](https://github.com/yuanchuan)