Chokidar chokes on options that are explicitely set to "undefined" #1394
Description
Describe the bug
Chokidar v4 doesnt clean up the passed options. Setting an option to explicit undefined
will make node throw.
Versions (please complete the following information):
- Chokidar version: 4.0.1
- Node version: 22
- OS version: Ubuntu
To Reproduce:
Steps to reproduce the behavior. Include filename and chokidar config.
Ideally prove a problem by isolating and making it reproducible with a very short sample program, which you could paste here:
const chokidar = require('chokidar');
const fs = require('fs');
// Passing undefined will crash node
chokidar.watch('test*', { interval: undefined }).on('all', (event, path) => {
console.log(event, path);
});
fs.writeFileSync('test.txt', 'testing 1');
Expected behavior
It should filter out undefined values so that chokidars defaulst are used instead (which doesnt happen because the explicit undefined overwrites the default when spreading):
Lines 361 to 377 in 5e6daaa
Additional context
I was in the process of testing the feasability to update to v4 in webpack/webpack-dev-server#5368.
However, all watch-tests fail with the error TypeError: The "interval" argument must be of type number. Received undefined
.
So either chokidar was cleaning up options in v3 or something else than Nodes native watcher was used.
In any case it is an unexpected breaking change.
I am aware that v4 was a major version bump but this seems to be a minor thing that could be adapted easily to make upgrading to v4 even easier.
Changing the above code to this would solve the problem:
const opts = {
..._opts,
// Defaults
persistent: _opts.persistent ?? true,
ignoreInitial: _opts.ignoreInitial ?? false,
ignorePermissionErrors: _opts.ignorePermissionErrors ?? false,
interval: _opts.interval ?? 100,
binaryInterval: _opts.binaryInterval ?? 300,
followSymlinks: _opts.followSymlinks ?? true,
usePolling: _opts.usePolling ?? false,
// useAsync: _opts.useAsync ?? false,
atomic: _opts.atomic ?? true, // NOTE: overwritten later (depends on usePolling)
// Change format
ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]),
awaitWriteFinish: _opts.awaitWriteFinish ?? (awf === true ? DEF_AWF : typeof awf === 'object' ? { ...DEF_AWF, ...awf } : false),
};