vitest 在 webstorm 中无法运行,首要排查 node ≥20.0.0 和 vite ≥6.0.0 环境;其次确认测试文件命名匹配 *.{test,spec}.{js,ts,jsx,tsx} 且含顶层 test();最后手动指定 vitest.config.js 路径并启用 --inspect-brk 调试。

WebStorm 里 Vitest 跑不起来?先确认这三件事
不是配置没写对,而是底层环境没搭稳——Vitest 依赖 Vite ≥6.0.0 和 Node ≥20.0.0,缺一不可。WebStorm 自动检测的 Node 解释器如果低于 v20(比如系统默认的 v18),哪怕 vitest 包装了也白搭,启动时会静默失败或报 ERR_UNSUPPORTED_ESM_URL_SCHEME 这类底层错误。
- 在 WebStorm 终端运行
node -v确认实际使用版本(不是which node看到的路径) - 进 Settings → Languages & Frameworks → JavaScript → Node.js,把
Node interpreter显式设为 v20+ 的可执行文件(别用Project别名赌自动识别) -
npm install -D vitest后,检查node_modules/.bin/vitest是否存在且可执行;若用 pnpm,确保没被pnpm store隔离导致 WebStorm 找不到二进制
点边栏图标没反应?检查测试文件命名和顶层 test 声明
WebStorm 依赖文件名模式和语法结构来注入运行图标。光有 vitest 包、有 .test.ts 后缀还不够——它必须能静态识别出这是“一个可运行的测试单元”。常见失效场景是用了 describe 套多层但漏了顶层 test 或 it,或者文件名不符合默认匹配规则。
- 默认只识别
**/*.{test,spec}.{js,ts,jsx,tsx},utils.test.mjs可以,utils.test.js.cjs不行 - 确保至少有一个顶层调用:
test('xxx', () => {...}),不能全包在describe('group', () => { test(...) })里还删了顶层 - 如果用了自定义
include模式(如加了type-test),需在vitest.config.js中显式配置,并让 WebStorm 读到该配置(见下一条)
WebStorm 没读到 vitest.config.js?手动指定配置路径很关键
WebStorm 不像命令行那样自动向上查找配置。它默认只认项目根目录下的 vitest.config.js 或 vitest.config.ts;如果放错位置(比如在 tests/ 子目录下),或用了非标准名(如 vitest.conf.mjs),就会退回到内置默认行为:不加载 environment、不识别 setupFiles、甚至忽略 include 规则——结果就是 DOM API 报错、mock 不生效、测试文件根本不出现在运行列表里。
- 创建运行配置时,在 Run → Edit Configurations → Vitest 页面,务必填上
Config file字段,指向你的真实配置路径 - 如果配置是
vitest.config.ts,确保项目已装ts-node或 WebStorm 的 TypeScript 服务已启用(否则解析失败无提示) - 改完配置后,别忘了点击右上角
Reload config按钮(小循环图标),否则 WebStorm 缓存旧配置
调试时断点不命中?检查 Node 选项和环境隔离设置
Vitest 在 WebStorm 里调试的本质,是用 --inspect-brk 启动子进程并连接 Chrome DevTools 协议。但如果你在配置里写了 environment: 'happy-dom',又没配好 setupFiles 中的定时器 mock,就可能出现断点“跳过”——因为 vi.useFakeTimers() 拦截了事件循环,而调试器还在等真实 tick。
- 在 Vitest 运行配置的
Node options字段中,必须包含--inspect-brk(不是--inspect),否则断点无法在首行挂起 - 若用
happy-dom或jsdom,确保setupFiles里调用了vi.useFakeTimers()且afterEach中调用vi.useRealTimers(),否则后续测试的异步流程会卡死调试器 - 避免在
beforeEach里做耗时操作(如重置 axios-mock-adapter),它会在每次断点暂停后重复执行,拖慢调试响应
最常被忽略的是:WebStorm 的 Vitest 配置和终端里 vitest --inspect 的行为并不完全一致——前者强依赖 UI 里填的每一个字段,后者靠命令行参数驱动。想稳定调试,宁可少用自动推导,多花十秒手填关键路径和参数。










