Skip to content

Commit afbb87d

Browse files
sapphi-redbluwy
andauthored
docs: update WSL2 watch limitation explanation (#8939)
Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
1 parent f4b4405 commit afbb87d

5 files changed

Lines changed: 58 additions & 27 deletions

File tree

docs/config/build-options.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,10 @@ Limit for chunk size warnings (in kbs).
193193
- **Default:** `null`
194194

195195
Set to `{}` to enable rollup watcher. This is mostly used in cases that involve build-only plugins or integrations processes.
196+
197+
::: warning Using Vite on Windows Subsystem for Linux (WSL) 2
198+
199+
There are cases that file system watching does not work with WSL2.
200+
See [`server.watch`](./server-options.md#server-watch) for more details.
201+
202+
:::

docs/config/server-options.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,6 @@ The error that appears in the Browser when the fallback happens can be ignored.
169169

170170
File system watcher options to pass on to [chokidar](https://github.com/paulmillr/chokidar#api).
171171

172-
When running Vite on Windows Subsystem for Linux (WSL) 2, if the project folder resides in a Windows filesystem, you'll need to set this option to `{ usePolling: true }`. This is due to [a WSL2 limitation](https://github.com/microsoft/WSL/issues/4739) with the Windows filesystem.
173-
174172
The Vite server watcher skips `.git/` and `node_modules/` directories by default. If you want to watch a package inside `node_modules/`, you can pass a negated glob pattern to `server.watch.ignored`. That is:
175173

176174
```js
@@ -188,6 +186,19 @@ export default defineConfig({
188186
})
189187
```
190188

189+
::: warning Using Vite on Windows Subsystem for Linux (WSL) 2
190+
191+
When running Vite on WSL2, file system watching does not work when a file is edited by Windows applications (non-WSL2 process). This is due to [a WSL2 limitation](https://github.com/microsoft/WSL/issues/4739). This also applies to running on Docker with a WSL2 backend.
192+
193+
To fix it, you could either:
194+
195+
- **Recommended**: Use WSL2 applications to edit your files.
196+
- It is also recommended to move the project folder outside of a Windows filesystem. Accessing Windows filesystem from WSL2 is slow. Removing that overhead will improve performance.
197+
- Set `{ usePolling: true }`.
198+
- Note that [`usePolling` leads to high CPU utilization](https://github.com/paulmillr/chokidar#performance).
199+
200+
:::
201+
191202
## server.middlewareMode
192203

193204
- **Type:** `boolean`

packages/vite/src/node/build.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import type { PackageData } from './packages'
4949
import { watchPackageDataPlugin } from './packages'
5050
import { ensureWatchPlugin } from './plugins/ensureWatch'
5151
import { ESBUILD_MODULES_TARGET, VERSION } from './constants'
52+
import { resolveChokidarOptions } from './watch'
5253

5354
export interface BuildOptions {
5455
/**
@@ -504,23 +505,17 @@ async function doBuild(
504505
output.push(buildOutputOptions(outputs))
505506
}
506507

507-
const watcherOptions = config.build.watch
508+
const resolvedChokidarOptions = resolveChokidarOptions(
509+
config.build.watch.chokidar
510+
)
511+
508512
const { watch } = await import('rollup')
509513
const watcher = watch({
510514
...rollupOptions,
511515
output,
512516
watch: {
513-
...watcherOptions,
514-
chokidar: {
515-
ignoreInitial: true,
516-
ignorePermissionErrors: true,
517-
...watcherOptions.chokidar,
518-
ignored: [
519-
'**/node_modules/**',
520-
'**/.git/**',
521-
...(watcherOptions?.chokidar?.ignored || [])
522-
]
523-
}
517+
...config.build.watch,
518+
chokidar: resolvedChokidarOptions
524519
}
525520
})
526521

packages/vite/src/node/server/index.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { CLIENT_DIR } from '../constants'
4343
import type { Logger } from '../logger'
4444
import { printServerUrls } from '../logger'
4545
import { invalidatePackageData } from '../packages'
46+
import { resolveChokidarOptions } from '../watch'
4647
import type { PluginContainer } from './pluginContainer'
4748
import { createPluginContainer } from './pluginContainer'
4849
import type { WebSocketServer } from './ws'
@@ -300,6 +301,11 @@ export async function createServer(
300301
)
301302
const { middlewareMode } = serverConfig
302303

304+
const resolvedWatchOptions = resolveChokidarOptions({
305+
disableGlobbing: true,
306+
...serverConfig.watch
307+
})
308+
303309
const middlewares = connect() as Connect.Server
304310
const httpServer = middlewareMode
305311
? null
@@ -310,19 +316,10 @@ export async function createServer(
310316
setClientErrorHandler(httpServer, config.logger)
311317
}
312318

313-
const { ignored = [], ...watchOptions } = serverConfig.watch || {}
314-
const watcher = chokidar.watch(path.resolve(root), {
315-
ignored: [
316-
'**/.git/**',
317-
'**/node_modules/**',
318-
'**/test-results/**', // Playwright
319-
...(Array.isArray(ignored) ? ignored : [ignored])
320-
],
321-
ignoreInitial: true,
322-
ignorePermissionErrors: true,
323-
disableGlobbing: true,
324-
...watchOptions
325-
}) as FSWatcher
319+
const watcher = chokidar.watch(
320+
path.resolve(root),
321+
resolvedWatchOptions
322+
) as FSWatcher
326323

327324
const moduleGraph: ModuleGraph = new ModuleGraph((url, ssr) =>
328325
container.resolveId(url, undefined, { ssr })

packages/vite/src/node/watch.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { WatchOptions } from 'types/chokidar'
2+
3+
export function resolveChokidarOptions(
4+
options: WatchOptions | undefined
5+
): WatchOptions {
6+
const { ignored = [], ...otherOptions } = options ?? {}
7+
8+
const resolvedWatchOptions: WatchOptions = {
9+
ignored: [
10+
'**/.git/**',
11+
'**/node_modules/**',
12+
'**/test-results/**', // Playwright
13+
...(Array.isArray(ignored) ? ignored : [ignored])
14+
],
15+
ignoreInitial: true,
16+
ignorePermissionErrors: true,
17+
...otherOptions
18+
}
19+
20+
return resolvedWatchOptions
21+
}

0 commit comments

Comments
 (0)