常见错误
不能找到模块 './relative-path'
如果你收到一个 module cannot be found 的报错,则可能意味着几种不同情况:
- 你拼错了路径。确保路径正确。
- 你可能依赖于
tsconfig.json中的baseUrl。默认情况下,Vite 不考虑tsconfig.json,因此如果你依赖此行为,你可能需要自己安装vite-tsconfig-paths。
import tsconfigPaths from 'vite-tsconfig-paths'
import { defineConfig } from 'vitest/config'
export default defineConfig({
plugins: [tsconfigPaths()],
})或者重写你的路径,使它不是相对于 root。
- import helpers from 'src/helpers'
+ import helpers from '../src/helpers'- 确保你没有使用相对路径的 别名。Vite 将它们视为相对于导入所在的文件而不是根目录。
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
alias: {
'@/': './src/',
'@/': new URL('./src/', import.meta.url).pathname,
},
},
})Worker 无法终止
当 NodeJS 的 fetch 与 pool: 'threads' 一起使用时,可能会出现此错误。详情请参阅 #3077。
默认的 pool: 'forks' 不存在此问题。如果你已显式设置 pool: 'threads',切换回 'forks' 或使用 'vmForks' 即可解决。
自定义包条件无法解析
如果你在 package.json 的 exports 或 subpath imports 中使用了自定义条件,你可能会发现 Vitest 默认不遵循这些条件。
例如,如果你的 package.json 中包含以下内容:
{
"exports": {
".": {
"custom": "./lib/custom.js",
"import": "./lib/index.js"
}
},
"imports": {
"#internal": {
"custom": "./src/internal.js",
"default": "./lib/internal.js"
}
}
}默认情况下,Vitest 仅使用 import 和 default 条件。要让 Vitest 遵循自定义条件,须在 Vitest 配置中配置 ssr.resolve.conditions:
import { defineConfig } from 'vitest/config'
export default defineConfig({
ssr: {
resolve: {
conditions: ['custom', 'import', 'default'],
},
},
})为什么是 ssr.resolve.conditions 而不是 resolve.conditions?
Vitest 遵循 Vite 的配置约定:
resolve.conditions适用于 Vite 的client环境,对应 Vitest 的浏览器模式、jsdom、happy-dom,以及使用viteEnvironment: 'client'的自定义环境。ssr.resolve.conditions适用于 Vite 的ssr环境,对应 Vitest 的 node 环境或使用viteEnvironment: 'ssr'的自定义环境。
由于 Vitest 默认使用 node 环境(该环境使用 viteEnvironment: 'ssr'),模块解析将使用 ssr.resolve.conditions。这同时适用于包导出(package exports)和子路径导入(subpath imports)。
你可以在 environment 中了解更多关于 Vite 环境和 Vitest 环境的内容。
段错误与原生代码错误
运行 原生 NodeJS 模块 在 pool: 'threads' 中,可能会遇到来自原生代码的神秘错误。
Segmentation fault (core dumped)thread '<unnamed>' panicked at 'assertion failedAbort trap: 6internal error: entered unreachable code
在这些情况下,原生模块可能不是为多线程安全而构建的。在解决方案中,你可以切换到 pool: 'forks',它在多个 node:child_process 而不是多个 node:worker_threads 中运行测试用例。
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
pool: 'forks',
},
})vitest --pool=forksUnhandled Promise Rejection
This error happens when a Promise rejects but no .catch() handler or await is attached to it before the microtask queue flushes. This behavior comes from JavaScript itself and is not specific to Vitest. Learn more in the Node.js documentation.
A common cause is calling an async function without awaiting it:
async function fetchUser(id) {
const res = await fetch(`/api/users/${id}`)
if (!res.ok) {
throw new Error(`User ${id} not found`)
}
return res.json()
}
test('fetches user', async () => {
fetchUser(123)
})Because fetchUser() is not awaited, its rejection has no handler and Vitest reports:
Unhandled Rejection: Error: User 123 not foundFix
await the promise so Vitest can catch the error:
test('fetches user', async () => {
await fetchUser(123)
})If you expect the call to throw, use expect().rejects:
test('rejects for missing user', async () => {
await expect(fetchUser(123)).rejects.toThrow('User 123 not found')
})