1 | # Chokidar [![Weekly downloads](https://img.shields.io/npm/dw/chokidar.svg)](https://github.com/paulmillr/chokidar) [![Yearly downloads](https://img.shields.io/npm/dy/chokidar.svg)](https://github.com/paulmillr/chokidar)
|
2 |
|
3 | > Minimal and efficient cross-platform file watching library
|
4 |
|
5 | [![NPM](https://nodei.co/npm/chokidar.png)](https://www.npmjs.com/package/chokidar)
|
6 |
|
7 | ## Why?
|
8 |
|
9 | Node.js `fs.watch`:
|
10 |
|
11 | * Doesn't report filenames on MacOS.
|
12 | * Doesn't report events at all when using editors like Sublime on MacOS.
|
13 | * Often reports events twice.
|
14 | * Emits most changes as `rename`.
|
15 | * Does not provide an easy way to recursively watch file trees.
|
16 | * Does not support recursive watching on Linux.
|
17 |
|
18 | Node.js `fs.watchFile`:
|
19 |
|
20 | * Almost as bad at event handling.
|
21 | * Also does not provide any recursive watching.
|
22 | * Results in high CPU utilization.
|
23 |
|
24 | Chokidar resolves these problems.
|
25 |
|
26 | Initially made for **[Brunch](https://brunch.io/)** (an ultra-swift web app build tool), it is now used in
|
27 | [Microsoft's Visual Studio Code](https://github.com/microsoft/vscode),
|
28 | [gulp](https://github.com/gulpjs/gulp/),
|
29 | [karma](https://karma-runner.github.io/),
|
30 | [PM2](https://github.com/Unitech/PM2),
|
31 | [browserify](http://browserify.org/),
|
32 | [webpack](https://webpack.github.io/),
|
33 | [BrowserSync](https://www.browsersync.io/),
|
34 | and [many others](https://www.npmjs.com/browse/depended/chokidar).
|
35 | It has proven itself in production environments.
|
36 |
|
37 | Version 3 is out! Check out our blog post about it: [Chokidar 3: How to save 32TB of traffic every week](https://paulmillr.com/posts/chokidar-3-save-32tb-of-traffic/)
|
38 |
|
39 | ## How?
|
40 |
|
41 | Chokidar does still rely on the Node.js core `fs` module, but when using
|
42 | `fs.watch` and `fs.watchFile` for watching, it normalizes the events it
|
43 | receives, often checking for truth by getting file stats and/or dir contents.
|
44 |
|
45 | On MacOS, chokidar by default uses a native extension exposing the Darwin
|
46 | `FSEvents` API. This provides very efficient recursive watching compared with
|
47 | implementations like `kqueue` available on most \*nix platforms. Chokidar still
|
48 | does have to do some work to normalize the events received that way as well.
|
49 |
|
50 | On most other platforms, the `fs.watch`-based implementation is the default, which
|
51 | avoids polling and keeps CPU usage down. Be advised that chokidar will initiate
|
52 | watchers recursively for everything within scope of the paths that have been
|
53 | specified, so be judicious about not wasting system resources by watching much
|
54 | more than needed.
|
55 |
|
56 | ## Getting started
|
57 |
|
58 | Install with npm:
|
59 |
|
60 | ```sh
|
61 | npm install chokidar
|
62 | ```
|
63 |
|
64 | Then `require` and use it in your code:
|
65 |
|
66 | ```javascript
|
67 | const chokidar = require('chokidar');
|
68 |
|
69 | // One-liner for current directory
|
70 | chokidar.watch('.').on('all', (event, path) => {
|
71 | console.log(event, path);
|
72 | });
|
73 | ```
|
74 |
|
75 | ## API
|
76 |
|
77 | ```javascript
|
78 | // Example of a more typical implementation structure
|
79 |
|
80 | // Initialize watcher.
|
81 | const watcher = chokidar.watch('file, dir, glob, or array', {
|
82 | ignored: /(^|[\/\\])\../, // ignore dotfiles
|
83 | persistent: true
|
84 | });
|
85 |
|
86 | // Something to use when events are received.
|
87 | const log = console.log.bind(console);
|
88 | // Add event listeners.
|
89 | watcher
|
90 | .on('add', path => log(`File ${path} has been added`))
|
91 | .on('change', path => log(`File ${path} has been changed`))
|
92 | .on('unlink', path => log(`File ${path} has been removed`));
|
93 |
|
94 | // More possible events.
|
95 | watcher
|
96 | .on('addDir', path => log(`Directory ${path} has been added`))
|
97 | .on('unlinkDir', path => log(`Directory ${path} has been removed`))
|
98 | .on('error', error => log(`Watcher error: ${error}`))
|
99 | .on('ready', () => log('Initial scan complete. Ready for changes'))
|
100 | .on('raw', (event, path, details) => { // internal
|
101 | log('Raw event info:', event, path, details);
|
102 | });
|
103 |
|
104 | // 'add', 'addDir' and 'change' events also receive stat() results as second
|
105 | // argument when available: https://nodejs.org/api/fs.html#fs_class_fs_stats
|
106 | watcher.on('change', (path, stats) => {
|
107 | if (stats) console.log(`File ${path} changed size to ${stats.size}`);
|
108 | });
|
109 |
|
110 | // Watch new files.
|
111 | watcher.add('new-file');
|
112 | watcher.add(['new-file-2', 'new-file-3', '**/other-file*']);
|
113 |
|
114 | // Get list of actual paths being watched on the filesystem
|
115 | var watchedPaths = watcher.getWatched();
|
116 |
|
117 | // Un-watch some files.
|
118 | await watcher.unwatch('new-file*');
|
119 |
|
120 | // Stop watching.
|
121 | // The method is async!
|
122 | watcher.close().then(() => console.log('closed'));
|
123 |
|
124 | // Full list of options. See below for descriptions.
|
125 | // Do not use this example!
|
126 | chokidar.watch('file', {
|
127 | persistent: true,
|
128 |
|
129 | ignored: '*.txt',
|
130 | ignoreInitial: false,
|
131 | followSymlinks: true,
|
132 | cwd: '.',
|
133 | disableGlobbing: false,
|
134 |
|
135 | usePolling: false,
|
136 | interval: 100,
|
137 | binaryInterval: 300,
|
138 | alwaysStat: false,
|
139 | depth: 99,
|
140 | awaitWriteFinish: {
|
141 | stabilityThreshold: 2000,
|
142 | pollInterval: 100
|
143 | },
|
144 |
|
145 | ignorePermissionErrors: false,
|
146 | atomic: true // or a custom 'atomicity delay', in milliseconds (default 100)
|
147 | });
|
148 |
|
149 | ```
|
150 |
|
151 | `chokidar.watch(paths, [options])`
|
152 |
|
153 | * `paths` (string or array of strings). Paths to files, dirs to be watched
|
154 | recursively, or glob patterns.
|
155 | - Note: globs must not contain windows separators (`\`),
|
156 | because that's how they work by the standard —
|
157 | you'll need to replace them with forward slashes (`/`).
|
158 | - Note 2: for additional glob documentation, check out low-level
|
159 | library: [picomatch](https://github.com/micromatch/picomatch).
|
160 | * `options` (object) Options object as defined below:
|
161 |
|
162 | #### Persistence
|
163 |
|
164 | * `persistent` (default: `true`). Indicates whether the process
|
165 | should continue to run as long as files are being watched. If set to
|
166 | `false` when using `fsevents` to watch, no more events will be emitted
|
167 | after `ready`, even if the process continues to run.
|
168 |
|
169 | #### Path filtering
|
170 |
|
171 | * `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition)
|
172 | Defines files/paths to be ignored. The whole relative or absolute path is
|
173 | tested, not just filename. If a function with two arguments is provided, it
|
174 | gets called twice per path - once with a single argument (the path), second
|
175 | time with two arguments (the path and the
|
176 | [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
177 | object of that path).
|
178 | * `ignoreInitial` (default: `false`). If set to `false` then `add`/`addDir` events are also emitted for matching paths while
|
179 | instantiating the watching as chokidar discovers these file paths (before the `ready` event).
|
180 | * `followSymlinks` (default: `true`). When `false`, only the
|
181 | symlinks themselves will be watched for changes instead of following
|
182 | the link references and bubbling events through the link's path.
|
183 | * `cwd` (no default). The base directory from which watch `paths` are to be
|
184 | derived. Paths emitted with events will be relative to this.
|
185 | * `disableGlobbing` (default: `false`). If set to `true` then the strings passed to `.watch()` and `.add()` are treated as
|
186 | literal path names, even if they look like globs.
|
187 |
|
188 | #### Performance
|
189 |
|
190 | * `usePolling` (default: `false`).
|
191 | Whether to use fs.watchFile (backed by polling), or fs.watch. If polling
|
192 | leads to high CPU utilization, consider setting this to `false`. It is
|
193 | typically necessary to **set this to `true` to successfully watch files over
|
194 | a network**, and it may be necessary to successfully watch files in other
|
195 | non-standard situations. Setting to `true` explicitly on MacOS overrides the
|
196 | `useFsEvents` default. You may also set the CHOKIDAR_USEPOLLING env variable
|
197 | to true (1) or false (0) in order to override this option.
|
198 | * _Polling-specific settings_ (effective when `usePolling: true`)
|
199 | * `interval` (default: `100`). Interval of file system polling, in milliseconds. You may also
|
200 | set the CHOKIDAR_INTERVAL env variable to override this option.
|
201 | * `binaryInterval` (default: `300`). Interval of file system
|
202 | polling for binary files.
|
203 | ([see list of binary extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
|
204 | * `useFsEvents` (default: `true` on MacOS). Whether to use the
|
205 | `fsevents` watching interface if available. When set to `true` explicitly
|
206 | and `fsevents` is available this supercedes the `usePolling` setting. When
|
207 | set to `false` on MacOS, `usePolling: true` becomes the default.
|
208 | * `alwaysStat` (default: `false`). If relying upon the
|
209 | [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
210 | object that may get passed with `add`, `addDir`, and `change` events, set
|
211 | this to `true` to ensure it is provided even in cases where it wasn't
|
212 | already available from the underlying watch events.
|
213 | * `depth` (default: `undefined`). If set, limits how many levels of
|
214 | subdirectories will be traversed.
|
215 | * `awaitWriteFinish` (default: `false`).
|
216 | By default, the `add` event will fire when a file first appears on disk, before
|
217 | the entire file has been written. Furthermore, in some cases some `change`
|
218 | events will be emitted while the file is being written. In some cases,
|
219 | especially when watching for large files there will be a need to wait for the
|
220 | write operation to finish before responding to a file creation or modification.
|
221 | Setting `awaitWriteFinish` to `true` (or a truthy value) will poll file size,
|
222 | holding its `add` and `change` events until the size does not change for a
|
223 | configurable amount of time. The appropriate duration setting is heavily
|
224 | dependent on the OS and hardware. For accurate detection this parameter should
|
225 | be relatively high, making file watching much less responsive.
|
226 | Use with caution.
|
227 | * *`options.awaitWriteFinish` can be set to an object in order to adjust
|
228 | timing params:*
|
229 | * `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in
|
230 | milliseconds for a file size to remain constant before emitting its event.
|
231 | * `awaitWriteFinish.pollInterval` (default: 100). File size polling interval, in milliseconds.
|
232 |
|
233 | #### Errors
|
234 |
|
235 | * `ignorePermissionErrors` (default: `false`). Indicates whether to watch files
|
236 | that don't have read permissions if possible. If watching fails due to `EPERM`
|
237 | or `EACCES` with this set to `true`, the errors will be suppressed silently.
|
238 | * `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`).
|
239 | Automatically filters out artifacts that occur when using editors that use
|
240 | "atomic writes" instead of writing directly to the source file. If a file is
|
241 | re-added within 100 ms of being deleted, Chokidar emits a `change` event
|
242 | rather than `unlink` then `add`. If the default of 100 ms does not work well
|
243 | for you, you can override it by setting `atomic` to a custom value, in
|
244 | milliseconds.
|
245 |
|
246 | ### Methods & Events
|
247 |
|
248 | `chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`:
|
249 |
|
250 | * `.add(path / paths)`: Add files, directories, or glob patterns for tracking.
|
251 | Takes an array of strings or just one string.
|
252 | * `.on(event, callback)`: Listen for an FS event.
|
253 | Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`,
|
254 | `raw`, `error`.
|
255 | Additionally `all` is available which gets emitted with the underlying event
|
256 | name and path for every event other than `ready`, `raw`, and `error`. `raw` is internal, use it carefully.
|
257 | * `.unwatch(path / paths)`: Stop watching files, directories, or glob patterns.
|
258 | Takes an array of strings or just one string.
|
259 | * `.close()`: **async** Removes all listeners from watched files. Asynchronous, returns Promise. Use with `await` to ensure bugs don't happen.
|
260 | * `.getWatched()`: Returns an object representing all the paths on the file
|
261 | system being watched by this `FSWatcher` instance. The object's keys are all the
|
262 | directories (using absolute paths unless the `cwd` option was used), and the
|
263 | values are arrays of the names of the items contained in each directory.
|
264 |
|
265 | ## CLI
|
266 |
|
267 | If you need a CLI interface for your file watching, check out
|
268 | [chokidar-cli](https://github.com/open-cli-tools/chokidar-cli), allowing you to
|
269 | execute a command on each change, or get a stdio stream of change events.
|
270 |
|
271 | ## Install Troubleshooting
|
272 |
|
273 | * `npm WARN optional dep failed, continuing fsevents@n.n.n`
|
274 | * This message is normal part of how `npm` handles optional dependencies and is
|
275 | not indicative of a problem. Even if accompanied by other related error messages,
|
276 | Chokidar should function properly.
|
277 |
|
278 | * `TypeError: fsevents is not a constructor`
|
279 | * Update chokidar by doing `rm -rf node_modules package-lock.json yarn.lock && npm install`, or update your dependency that uses chokidar.
|
280 |
|
281 | * Chokidar is producing `ENOSP` error on Linux, like this:
|
282 | * `bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell`
|
283 | `Error: watch /home/ ENOSPC`
|
284 | * This means Chokidar ran out of file handles and you'll need to increase their count by executing the following command in Terminal:
|
285 | `echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p`
|
286 |
|
287 | ## Changelog
|
288 |
|
289 | For more detailed changelog, see [`full_changelog.md`](.github/full_changelog.md).
|
290 | - **v3.5 (Jan 6, 2021):** Support for ARM Macs with Apple Silicon. Fixes for deleted symlinks.
|
291 | - **v3.4 (Apr 26, 2020):** Support for directory-based symlinks. Fixes for macos file replacement.
|
292 | - **v3.3 (Nov 2, 2019):** `FSWatcher#close()` method became async. That fixes IO race conditions related to close method.
|
293 | - **v3.2 (Oct 1, 2019):** Improve Linux RAM usage by 50%. Race condition fixes. Windows glob fixes. Improve stability by using tight range of dependency versions.
|
294 | - **v3.1 (Sep 16, 2019):** dotfiles are no longer filtered out by default. Use `ignored` option if needed. Improve initial Linux scan time by 50%.
|
295 | - **v3 (Apr 30, 2019):** massive CPU & RAM consumption improvements; reduces deps / package size by a factor of 17x and bumps Node.js requirement to v8.16 and higher.
|
296 | - **v2 (Dec 29, 2017):** Globs are now posix-style-only; without windows support. Tons of bugfixes.
|
297 | - **v1 (Apr 7, 2015):** Glob support, symlink support, tons of bugfixes. Node 0.8+ is supported
|
298 | - **v0.1 (Apr 20, 2012):** Initial release, extracted from [Brunch](https://github.com/brunch/brunch/blob/9847a065aea300da99bd0753f90354cde9de1261/src/helpers.coffee#L66)
|
299 |
|
300 | ## Also
|
301 |
|
302 | Why was chokidar named this way? What's the meaning behind it?
|
303 |
|
304 | >Chowkidar is a transliteration of a Hindi word meaning 'watchman, gatekeeper', चौकीदार. This ultimately comes from Sanskrit _ चतुष्क_ (crossway, quadrangle, consisting-of-four). This word is also used in other languages like Urdu as (چوکیدار) which is widely used in Pakistan and India.
|
305 |
|
306 | ## License
|
307 |
|
308 | MIT (c) Paul Miller (<https://paulmillr.com>), see [LICENSE](LICENSE) file.
|