Skip to content

Commit b272880

Browse files
committed
chore: update chokidar to v4
1 parent d163488 commit b272880

9 files changed

Lines changed: 569 additions & 90 deletions

File tree

lib/Server.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const schema = require("./options.json");
1717
/** @typedef {import("webpack").Stats} Stats */
1818
/** @typedef {import("webpack").MultiStats} MultiStats */
1919
/** @typedef {import("os").NetworkInterfaceInfo} NetworkInterfaceInfo */
20-
/** @typedef {import("chokidar").WatchOptions} WatchOptions */
20+
/** @typedef {import("chokidar").ChokidarOptions} WatchOptions */
2121
/** @typedef {import("chokidar").FSWatcher} FSWatcher */
2222
/** @typedef {import("connect-history-api-fallback").Options} ConnectHistoryApiFallbackOptions */
2323
/** @typedef {import("bonjour-service").Bonjour} Bonjour */
@@ -306,6 +306,22 @@ function useFn(route, fn) {
306306

307307
const DEFAULT_ALLOWED_PROTOCOLS = /^(file|.+-extension):/i;
308308

309+
/**
310+
* Removes properties with undefined values from an object.
311+
* Needed because chokidar v4 crashes when options are explicitly set to undefined.
312+
* @see https://github.com/paulmillr/chokidar/issues/1394
313+
* @template {Record<string, unknown>} T
314+
* @param {T} obj the object to filter
315+
* @returns {T} a new object without undefined values
316+
*/
317+
function removeUndefinedValues(obj) {
318+
return /** @type {T} */ (
319+
Object.fromEntries(
320+
Object.entries(obj).filter(([, value]) => typeof value !== "undefined"),
321+
)
322+
);
323+
}
324+
309325
/**
310326
* @typedef {object} BasicApplication
311327
* @property {typeof useFn} use
@@ -833,7 +849,7 @@ class Server {
833849

834850
const usePolling = getPolling();
835851
const interval = getInterval();
836-
const { poll, ...rest } = watchOptions;
852+
const { poll: _poll, ...rest } = watchOptions;
837853

838854
return {
839855
ignoreInitial: true,
@@ -844,9 +860,7 @@ class Server {
844860
ignorePermissionErrors: true,
845861
// Respect options from compiler watchOptions
846862
usePolling,
847-
interval,
848-
ignored: watchOptions.ignored,
849-
// TODO: we respect these options for all watch options and allow developers to pass them to chokidar, but chokidar doesn't have these options maybe we need revisit that in future
863+
...(interval !== undefined ? { interval } : {}),
850864
...rest,
851865
};
852866
};
@@ -3188,10 +3202,14 @@ class Server {
31883202
* @param {string | string[]} watchPath watch path
31893203
* @param {WatchOptions=} watchOptions watch options
31903204
*/
3191-
watchFiles(watchPath, watchOptions) {
3205+
watchFiles(watchPath, watchOptions = {}) {
31923206
const chokidar = require("chokidar");
31933207

3194-
const watcher = chokidar.watch(watchPath, watchOptions);
3208+
// https://github.com/paulmillr/chokidar/issues/1394
3209+
const watcher = chokidar.watch(
3210+
watchPath,
3211+
removeUndefinedValues(watchOptions),
3212+
);
31953213

31963214
// disabling refreshing on changing the content
31973215
if (this.options.liveReload) {

lib/options.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@
850850
"$ref": "#/definitions/WatchFilesObject"
851851
}
852852
],
853-
"description": "Allows to configure list of globs/directories/files to watch for file changes.",
853+
"description": "Allows to configure list of directories/files to watch for file changes.",
854854
"link": "https://webpack.js.org/configuration/dev-server/#devserverwatchfiles"
855855
},
856856
"WatchFilesObject": {
@@ -873,7 +873,7 @@
873873
"minLength": 1
874874
}
875875
],
876-
"description": "Path(s) of globs/directories/files to watch for file changes."
876+
"description": "Path(s) of directories/files to watch for file changes."
877877
},
878878
"options": {
879879
"type": "object",

migration-v6.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,47 @@ This document serves as a migration guide for `webpack-dev-server@6.0.0`.
3737
};
3838
```
3939

40+
- Updated `chokidar` from v3 to v4. Glob patterns are no longer supported in `watchFiles`. If you previously used globs, you can watch a directory and filter with `ignored`:
41+
42+
v5:
43+
44+
```js
45+
module.exports = {
46+
devServer: {
47+
watchFiles: "src/**/*.js",
48+
},
49+
};
50+
```
51+
52+
v6:
53+
54+
```js
55+
module.exports = {
56+
devServer: {
57+
watchFiles: {
58+
paths: "src",
59+
options: {
60+
ignored: (path, stats) => stats?.isFile() && !path.endsWith(".js"),
61+
},
62+
},
63+
},
64+
};
65+
```
66+
67+
Or resolve the glob before passing it:
68+
69+
```js
70+
const { globSync } = require("node:fs");
71+
72+
module.exports = {
73+
devServer: {
74+
watchFiles: globSync("src/**/*.js"),
75+
},
76+
};
77+
```
78+
79+
> **Note:** `fs.globSync` requires Node.js 22+. For Node.js 20, use a package like `fast-glob` or `tinyglobby`.
80+
4081
- Now, webpack-dev-server adds WebSocket communication only when the `target` is set to a web-compatible environment. Previously, it also injected WebSocket communication if `resolve` contained a `conditionNames` entry with `browser` or if `externalsPresets.web` existed.
4182
4283
- When retrieving the configuration in a multi-compiler setup, it will look for one that has a target compatible with a web environment. If it doesn’t find one, it will fall back to the first compiler found by webpack.

package-lock.json

Lines changed: 94 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"@types/ws": "^8.18.1",
5454
"ansi-html-community": "^0.0.8",
5555
"bonjour-service": "^1.3.0",
56-
"chokidar": "^3.6.0",
56+
"chokidar": "^4.0.3",
5757
"compression": "^1.8.1",
5858
"connect-history-api-fallback": "^2.0.0",
5959
"express": "^5.2.1",

0 commit comments

Comments
 (0)