injectCjsGlobals
- 类型:
boolean - 默认值:
true - CLI:
--no-inject-cjs-globals、--injectCjsGlobals=false
将 CommonJS 模块变量(module、exports、require、__filename、__dirname)注入 Vitest 处理的每个模块中。
默认情况下,Vitest 转换的每个文件都可以访问这些变量,即使该文件使用 ESM 语法编写。这并不能反映实际环境中的模块工作方式:浏览器不支持 CommonJS 变量,而 Node.js 不会在 ES 模块中暴露这些变量。
要使模块环境更加严格,并更接近目标运行时,可以禁用此行为:
js
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
injectCjsGlobals: false,
},
})禁用此选项后,只有被检测为 CommonJS 的模块才会接收这些变量。CommonJS 模块始终保留这些变量,因为它们属于模块作用域;没有这些变量,模块根本无法完成求值。模块类型的检测方式与 Node.js 相同:
- 文件扩展名:
.cjs和.cts文件始终是 CommonJS,.mjs和.mts文件始终是 ES 模块。 - 最近的
package.json中的type字段:"module"表示 ES 模块,"commonjs"表示 CommonJS。与 Node.js 一样,查找会在遇到第一个package.json时停止,且不会跨越node_modules边界,因此依赖不会继承项目的type。 - 文件中是否存在 ESM 语法:如果文件没有静态的
import/export声明,也没有引用import.meta,则会被视为 CommonJS。注释和字符串中的语法不会影响检测。CommonJS 模块允许使用动态导入,因此动态导入不计为 ESM 语法;仅用于类型的 TypeScript 导入会在转换过程中被擦除,因此也不计为 ESM 语法。
语法检测始终启用:Vitest 不会遵循修改模块类型解析方式的 Node.js CLI 标志,例如 --no-experimental-detect-module、--input-type(在 Node.js 中它仅适用于字符串输入),或在 Node.js 23 中移除的 --experimental-default-type 标志。
在 ES 模块中引用 CommonJS 变量会抛出 ReferenceError,与 Vitest 外部的行为相同:
ReferenceError: __dirname is not defined
“__dirname” 是一个在 ES 模块中不可用的 CommonJS 变量,并且 “injectCjsGlobals” 已禁用。如果此模块应当是 ES 模块,请使用 “import.meta.dirname” 替代 “__dirname”。如果它应当是 CommonJS 模块,请使用 “.cjs” 文件扩展名,在最近的 package.json 中设置 “type”: “commonjs”,或通过 “server.deps.external” 将其外部化。WARNING
此选项不会影响外部化模块,因为这些模块始终由原生运行时执行。Node.js 会自行向外部化的 CommonJS 模块提供 CommonJS 变量。
请注意,即使启用了此选项,内联的 CommonJS 模块也不会经过 Vite 插件处理:require 调用始终会离开模块运行器,因此模拟等功能不会对其生效。
