Vitest在GitLab Runner因inotify.max_user_watches耗尽失败,非监听模式此行为正常吗?
问题背景
添加新的Node模块后,使用Vitest在非监听模式下运行测试时触发了ENOSPC错误,GitLab Runner日志如下:
yarn run v1.22.19 $ vitest --run --watch=false --reporter junit [ESLint] Found 0 error and 0 warning node:internal/event_target:1037 process.nextTick(() => { throw err; }); ^ Error: ENOSPC: System limit for number of file watchers reached, watch '/builds/project/src' at FSWatcher.<computed> (node:internal/fs/watchers:247:19) at Object.watch (node:fs:2399:36) at createFsWatchInstance (/builds/project/node_modules/chokidar/lib/nodefs-handler.js:119:15) at setFsWatchListener (/builds/project/node_modules/chokidar/lib/nodefs-handler.js:166:15) at NodeFsHandler._watchWithNodeFs (/builds/project/node_modules/chokidar/lib/nodefs-handler.js:331:14) at NodeFsHandler._handleDir (/builds/project/node_modules/chokidar/lib/nodefs-handler.js:567:19) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async NodeFsHandler._addToNodeFs (/builds/project/node_modules/chokidar/lib/nodefs-handler.js:617:16) at async /builds/project/node_modules/chokidar/index.js:451:21 at async Promise.all (index 0) Emitted 'error' event on Worker instance at: at [kOnErrorMessage] (node:internal/worker:323:10) at [kOnMessage] (node:internal/worker:334:37) at MessagePort.<anonymous> (node:internal/worker:229:57) at [nodejs.internal.kHybridDispatch] (node:internal/event_target:762:20) at exports.emitMessage (node:internal/per_context/messageport:23:28) { errno: -28, syscall: 'watch', code: 'ENOSPC', path: '/builds/project/src', filename: '/builds/project/src' } Node.js v20.1.0
经排查,问题根源是共享GitLab Runner的inotify.max_user_watches值设为8192,而项目node_modules中的文件及目录总数超过16k,导致监听资源耗尽触发异常,该问题已通过虚拟机设置相同inotify.max_user_watches值复现。
核心疑问:在非监听模式下运行Vitest时出现这种文件监听触发的错误,是否属于预期行为?
解答
这种行为不属于预期情况。
Vitest的--run(或--watch=false)模式设计初衷是一次性执行所有测试后立即退出,理论上不需要启动文件监听机制。实际出现该问题,通常是因为以下原因:
- Vitest内部依赖(如日志中出现的chokidar)在非监听模式下被意外初始化
- 项目配置的Vitest插件(如热更新类插件)未在非监听模式下正确禁用
- 特定版本的Vitest存在参数解析bug,导致
--watch=false未生效,仍启动了监听进程 - 第三方测试工具或ESLint插件集成时意外引入了文件监听逻辑
临时解决方案
可以在GitLab Runner的初始化脚本中临时调高inotify.max_user_watches值:
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
长期修复方向
- 排查项目配置,确保所有监听相关的插件/逻辑在
--run模式下被禁用 - 升级Vitest到最新稳定版本,修复可能存在的参数解析bug
内容的提问来源于stack exchange,提问作者Stefan A.Svellingen
相关产品推荐
相关产品推荐

