Skip to content

Commit ea268c3

Browse files
authored
feat(deps)!: update chokidar to v5 (#150)
1 parent f204f0c commit ea268c3

File tree

7 files changed

+97
-98
lines changed

7 files changed

+97
-98
lines changed

docs/migrate-v1-to-v2.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,48 @@ export default {
7777
};
7878
```
7979

80+
### Updated `chokidar` to v5
81+
82+
`@rspack/dev-server` v2 upgrades the underlying file watcher `chokidar` from v3 to v5.
83+
84+
One important breaking change in `chokidar` v4+ is that [glob patterns are no longer supported](https://github.com/paulmillr/chokidar#upgrading).
85+
86+
If you previously passed glob patterns such as `**/*.js` or `./directory/**/*` to `devServer.watchFiles`, you can watch a directory and filter with `ignored`:
87+
88+
```js
89+
// Before
90+
export default {
91+
devServer: {
92+
watchFiles: '**/*.js',
93+
},
94+
};
95+
96+
// After
97+
export default {
98+
devServer: {
99+
watchFiles: {
100+
paths: '.',
101+
options: {
102+
ignored: (path, stats) =>
103+
stats?.isFile() && !path.endsWith('.js'),
104+
},
105+
},
106+
},
107+
};
108+
```
109+
110+
Or use `node:fs/promises` to expand the glob first:
111+
112+
```js
113+
import { glob } from 'node:fs/promises';
114+
115+
export default async () => ({
116+
devServer: {
117+
watchFiles: await Array.fromAsync(glob('**/*.js')),
118+
},
119+
});
120+
```
121+
80122
### Removed `spdy` support
81123
82124
- `server.type: "spdy"` is no longer supported.
@@ -108,6 +150,8 @@ export default {
108150
};
109151
```
110152
153+
> `Array.fromAsync()` requires Node.js 22+.
154+
111155
### Optional `selfsigned` peer dependency
112156
113157
`selfsigned` is no longer bundled as a direct dependency of `@rspack/dev-server`.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"@types/serve-index": "^1.9.4",
5050
"@types/serve-static": "^2.2.0",
5151
"@types/ws": "^8.18.1",
52-
"chokidar": "^3.6.0",
52+
"chokidar": "^5.0.0",
5353
"connect-history-api-fallback": "^2.0.0",
5454
"connect-next": "^4.0.0",
5555
"http-proxy-middleware": "^3.0.5",

pnpm-lock.yaml

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

rslib.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export default defineConfig({
1515
'serve-static': 'commonjs serve-static',
1616
'serve-index': 'commonjs serve-index',
1717
selfsigned: 'commonjs selfsigned',
18-
chokidar: 'commonjs chokidar',
1918
},
2019
},
2120
},

src/server.ts

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ const getConnect = async () => {
148148
const { connect } = await import('connect-next');
149149
return connect;
150150
};
151+
const getChokidar = memoize(() => import('chokidar'));
151152
const getServeStatic = memoize(() => require('serve-static'));
152153

153154
const encodeOverlaySettings = (
@@ -602,11 +603,7 @@ class Server<
602603
const compilerOptions = this.#getCompilerOptions();
603604
const compilerWatchOptions = compilerOptions.watchOptions;
604605
const getWatchOptions = (
605-
watchOptions: WatchOptions & {
606-
aggregateTimeout?: number;
607-
ignored?: WatchOptions['ignored'];
608-
poll?: number | boolean;
609-
} = {},
606+
watchOptions: WatchFiles['options'] = {},
610607
): WatchOptions => {
611608
const getPolling = () => {
612609
if (typeof watchOptions.usePolling !== 'undefined') {
@@ -623,6 +620,7 @@ class Server<
623620

624621
return false;
625622
};
623+
626624
const getInterval = () => {
627625
if (typeof watchOptions.interval !== 'undefined') {
628626
return watchOptions.interval;
@@ -639,8 +637,7 @@ class Server<
639637

640638
const usePolling = getPolling();
641639
const interval = getInterval();
642-
const { poll, ...rest } = watchOptions;
643-
640+
const { poll: _poll, ...rest } = watchOptions;
644641
return {
645642
ignoreInitial: true,
646643
persistent: true,
@@ -650,9 +647,7 @@ class Server<
650647
ignorePermissionErrors: true,
651648
// Respect options from compiler watchOptions
652649
usePolling,
653-
interval,
654-
ignored: watchOptions.ignored,
655-
// 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
650+
...(interval !== undefined ? { interval } : {}),
656651
...rest,
657652
};
658653
};
@@ -1463,8 +1458,8 @@ class Server<
14631458
}
14641459
}
14651460

1466-
this.#setupWatchFiles();
1467-
this.#setupWatchStaticFiles();
1461+
await this.#setupWatchFiles();
1462+
await this.#setupWatchStaticFiles();
14681463
await this.#setupMiddlewares();
14691464

14701465
if (this.options.setupExitSignals) {
@@ -1563,24 +1558,24 @@ class Server<
15631558
);
15641559
}
15651560

1566-
#setupWatchStaticFiles(): void {
1561+
async #setupWatchStaticFiles(): Promise<void> {
15671562
const watchFiles = this.options.static as NormalizedStatic[];
15681563

15691564
if (watchFiles.length > 0) {
15701565
for (const item of watchFiles) {
15711566
if (item.watch) {
1572-
this.watchFiles(item.directory, item.watch as WatchOptions);
1567+
await this.watchFiles(item.directory, item.watch as WatchOptions);
15731568
}
15741569
}
15751570
}
15761571
}
15771572

1578-
#setupWatchFiles(): void {
1573+
async #setupWatchFiles(): Promise<void> {
15791574
const watchFiles = this.options.watchFiles as WatchFiles[];
15801575

15811576
if (watchFiles.length > 0) {
15821577
for (const item of watchFiles) {
1583-
this.watchFiles(item.paths, item.options);
1578+
await this.watchFiles(item.paths, item.options);
15841579
}
15851580
}
15861581
}
@@ -2577,10 +2572,12 @@ class Server<
25772572
}
25782573
}
25792574

2580-
watchFiles(watchPath: string | string[], watchOptions?: WatchOptions) {
2581-
const chokidar = require('chokidar');
2582-
2583-
const watcher = chokidar.watch(watchPath, watchOptions);
2575+
async watchFiles(
2576+
watchPath: string | string[],
2577+
watchOptions?: WatchOptions,
2578+
): Promise<void> {
2579+
const { watch } = await getChokidar();
2580+
const watcher = watch(watchPath, watchOptions);
25842581

25852582
// disabling refreshing on changing the content
25862583
if (this.options.liveReload) {

src/types.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type {
44
ServerResponse,
55
} from 'node:http';
66
import type { ServerOptions } from 'node:https';
7-
import type { FSWatcher, WatchOptions } from 'chokidar';
7+
import type { FSWatcher, ChokidarOptions as WatchOptions } from 'chokidar';
88
import type { Options as ConnectHistoryApiFallbackOptions } from 'connect-history-api-fallback';
99
import type {
1010
Server as ConnectApplication,
@@ -97,7 +97,6 @@ export interface WatchFiles {
9797
paths: string | string[];
9898
options?: WatchOptions & {
9999
aggregateTimeout?: number;
100-
ignored?: WatchOptions['ignored'];
101100
poll?: number | boolean;
102101
};
103102
}

0 commit comments

Comments
 (0)