Skip to content

limit dev watcher to avoid overhead from third party processes writing to root #8341

@dominikg

Description

@dominikg

Clear and concise description of the problem

By default, vite devuses a chokidar watcher on root, ignoring only .git and node_modules.

https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/index.ts#L291-L302

This causes overhead when processes write files to root that are not needed to be watched. eg. @playwright/test writes to test-results - a lot - if tracing is enabled. (see details below)

Suggested solution

Limit watching to directories matching the fs.allow pattern inside root. This gives frameworks and users more control over what is watched and improves performance.

example code, not perfect but to illustrate whats suggested.

  const { ignored = [], ...watchOptions } = serverConfig.watch || {}
-  const watcher = chokidar.watch(path.resolve(root), {
+  const scope = path.resolve(root) + path.sep;
+  const watch = serverConfig.fs?.allow?.length ? serverConfig.fs.allow.filter(dir => dir.startsWith(scope)) : [];
+  if(watch.length === 0) {
+    watch.push(path.resolve(root))
+  }  
+  const watcher = chokidar.watch(watch, {    
    ignored: [
      '**/node_modules/**',
      '**/.git/**',
      ...(Array.isArray(ignored) ? ignored : [ignored])
    ],
    ignoreInitial: true,
    ignorePermissionErrors: true,
    disableGlobbing: true,
    ...watchOptions
  }) as FSWatcher

Considerations:

  1. fs.allow can contain items outside root. simply watching all fs.allow entries could cause even more problems (what if someone put / in fs.allow?) so keep the root boundary in place.
  2. keep the current behavior if fs.allow contains root or only contains directories outside root (it has to watch something).
  3. could use some logging too what gets watched and maybe a warning on excessive flooding

Alternative

manually add ignore entries to known patterns.

watch: {
	// perf, do not watch playwright output dir
	ignored: ['**/test-results/**']
}

This would still incur some cost inside chokidar but at least it would not reach the downstream handlers

Additional context

example of a sveltekit testsuite run with enabled logging inside a watcher demonstrating the current behavior.
https://github.com/sveltejs/kit/runs/6599185996?check_suite_focus=true

...
@sveltejs/kit:test: [WebServer] config.kit.files.routes: D:\a\kit\kit\packages\kit\test\apps\basics\src\routes
@sveltejs/kit:test: [WebServer] add D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-0\41adcbc97f1df5cc5fc3997a22928727.zip
@sveltejs/kit:test: [WebServer] add D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-0\f845da79f5fc1bf257a216cc3e2eb100.png
@sveltejs/kit:test: [WebServer] unlink D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-0\41adcbc97f1df5cc5fc3997a22928727.zip
@sveltejs/kit:test: [WebServer] unlink D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-0\f845da79f5fc1bf257a216cc3e2eb100.png
@sveltejs/kit:test: [WebServer] add D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-1\ec2416cbd7c50f61810b6fac2a86d166.zip
@sveltejs/kit:test: [WebServer] add D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-1\639ae30030d1658af3b1a90aae33d8fc.png
@sveltejs/kit:test: [WebServer] unlink D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-1\ec2416cbd7c50f61810b6fac2a86d166.zip
@sveltejs/kit:test: unlink D:\a\kit\kit\packages\kit\test\apps\basics\test-results\.playwright-artifacts-1\639ae30030d1658af3b1a90aae33d8fc.png
...

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestperformancePerformance related enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions