尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Vitest environment 配置完全指南:node / jsdom / happy-dom / edge-runtime 与自定义环境

发布时间:2026/9/14 19:12:38

资讯中心
01
ARTICLE

Vitest environment 配置完全指南:node / jsdom / happy-dom / edge-runtime 与自定义环境

Vitest environment 配置完全指南:node / jsdom / happy-dom / edge-runtime 与自定义环境
Vitest environment 配置完全指南node / jsdom / happy-dom / edge-runtime 与自定义环境【免费下载链接】vitestNext generation testing framework powered by Vite.项目地址: https://gitcode.com/GitHub_Trending/vi/vitestenvironment是 Vitest 中决定测试代码运行环境的核心配置项它控制测试文件在 Node.js、浏览器模拟环境还是边缘运行时中执行。本文以 environment.md 为骨架结合 Vitest 源码实现packages/vitest/src/integrations/env/与真实测试用例系统讲解内置环境的选型、按文件切换环境、environmentOptions传参、自定义 Environment 的完整写法以及viteEnvironment、builtinEnvironments等进阶概念帮助你在单测、组件测试与边缘函数测试中精准选对运行环境。environment 配置项速览environment的完整定义如下见 environment.md类型node | jsdom | happy-dom | edge-runtime | string默认值nodeCLI 参数--environmentenvVitest 默认在 Node.js 环境中运行测试。如果你在构建 Web 应用可以通过jsdom或happy-dom获得浏览器风格的 DOM API如果你在开发边缘函数edge functions则可以使用edge-runtime环境。提示如果你希望在不模拟环境的情况下运行集成测试或单元测试可以考虑使用 Browser Mode它在真实浏览器中运行测试与环境模拟是两条不同的技术路线。在配置文件中按如下方式设置import { defineConfig } from vitest/config export default defineConfig({ test: { environment: jsdom, }, })对应命令行写法vitest --environmentjsdom在 Vitest 的 配置类型定义 中该选项会被解析并分发到各个 worker决定 worker 中loadEnvironment的调用结果见 loader.ts。四种内置环境的定位Vitest 内置环境定义在 packages/vitest/src/integrations/env/index.ts 中共四种环境名实现文件适用场景依赖nodenode.ts默认环境纯 Node.js 运行适合库、工具函数等不依赖 DOM 的测试无额外依赖jsdomjsdom.ts模拟完整浏览器 DOM API兼容性好jsdom包happy-domhappy-dom.ts同样提供浏览器 DOM API速度更快但部分 API 缺失happy-dom包edge-runtimeedge-runtime.ts模拟 Vercel 的 edge-runtime测试边缘函数edge-runtime/vm包其中node与jsdom、happy-dom、edge-runtime的具体差异可参考 Test Environment 指南jsdom通过jsdom包提供浏览器 API 模拟happy-dom也被认为比 jsdom 更快但缺少部分浏览器 APIedge-runtime使用edge-runtime/vm模拟 Vercel 的边缘运行时。注意环境Environments只在 Node.js 中运行测试时存在。browser在 Vitest 中并不被视为一种 environment若想用 Browser Mode 运行部分测试需要通过 projects 创建测试项目。按文件粒度切换环境docblock 与注释指令全局配置environment会作用于项目中所有测试文件。当需要在不同文件中使用不同环境时可以在文件顶部添加vitest-environmentdocblock 或注释指定该文件专属的环境。Docblock 风格/** * vitest-environment jsdom */ test(use jsdom in this test file, () { const element document.createElement(div) expect(element).not.toBeNull() })注释风格// vitest-environment happy-dom test(use happy-dom in this test file, () { const element document.createElement(div) expect(element).not.toBeNull() })Jest 兼容写法为兼容从 Jest 迁移过来的项目Vitest 同样支持jest-environment/** * jest-environment jsdom */ test(use jsdom in this test file, () { const element document.createElement(div) expect(element).not.toBeNull() })仓库中的 e2e 测试充分验证了这一机制。例如 test/e2e/fixtures/mixed-environments/project/test/jsdom.test.ts 通过 docblock 声明 jsdom 环境并断言各环境的全局变量互不泄漏/** * vitest-environment jsdom */ import { expect, test } from vitest test(Leaking globals not found, async () { (globalThis as any).__leaking_from_jsdom leaking expect((globalThis as any).__leaking_from_node).toBe(undefined) expect((globalThis as any).__leaking_from_happy_dom).toBe(undefined) })同一 fixtures 目录下还有happy-dom.test.ts与node.test.ts三者在同一个项目内通过文件级注释混用不同环境直接印证了按文件切换环境的能力。环境专属配置environmentOptions如果想为某个环境传入自定义选项使用environmentOptions配置项类型Recordjsdom | happyDOM | string, unknown默认值{}这些选项会被传入当前环境的setup方法。内置环境中默认只对jsdom和happyDOM开放可配置选项import { defineConfig } from vitest/config export default defineConfig({ test: { environmentOptions: { jsdom: { url: http://localhost:3000, }, happyDOM: { width: 300, height: 400, }, }, }, })重要约束选项按环境名作用域隔离。jsdom 的选项必须放在jsdom键下happy-dom 的选项必须放在happyDOM键下这样可以在同一个项目内混合使用多种环境而不互相干扰。从源码结构看这些选项最终会以options参数的形式传给自定义环境的setup(global, options)与setupVM(options)方法见 types/environment.ts。自定义环境加载规则与 Environment 形状当使用非内置环境时Vitest 会尝试加载对应的文件或包如果环境名是相对路径或绝对路径则直接加载该文件如果环境名是裸包名bare specifier则加载名为vitest-environment-${name}的包。这一规则在 packages/vitest/src/integrations/env/loader.ts 的loadNativeEnvironment与loadEnvironment中实现其中name[0] . || name[0] /判断路径形式否则走vitest-environment-${name}的包解析。环境加载失败时例如默认导出不是一个对象会抛出类型错误提示需要导出带setup或setupVM方法的默认对象。自定义环境文件需要导出一个符合Environment形状的对象import type { Environment } from vitest export default Environment{ name: custom, viteEnvironment: ssr, setup() { // custom setup return { teardown() { // called after all tests with this env have been run } } } }更完整的Environment类型定义见 packages/vitest/src/types/environment.ts包含以下字段name: string环境名称viteEnvironment?: client | ssr | ({} string)对应 Vite Environment API 定义的环境。默认情况下 Vite 暴露client浏览器与ssr服务端两种。该值决定用哪个环境处理文件缺省时回退为 Vitest 环境名prewarmModules?: boolean默认true。当setupVM较快时设为false可避免 vm 池在运行 setupVM 期间转换导入图setupVM?: (options) VmEnvironmentReturn仅在支持vmForks或vmThreads池时使用返回getVmContext()与teardown()setup: (global, options) EnvironmentReturn核心 setup 方法返回含teardown的对象。transformModeweb | ssr在 Vitest 4 中已被标记为废弃推荐改用viteEnvironment源码中保留了向后兼容的转换逻辑见 loader.ts 中的resolveEnvironmentFromModule。自定义环境完整示例含 setupVM以下示例来自 Test Environment 指南展示了同时实现setup与setupVM的完整形态import type { Environment } from vitest/runtime export default Environment{ name: custom, viteEnvironment: ssr, // optional - set to false when setupVM is fast, so vm pools // do not transform the import graph while it runs prewarmModules: true, // optional - only if you support vmForks or vmThreads pools async setupVM() { const vm await import(node:vm) const context vm.createContext() return { getVmContext() { return context }, teardown() { // called after all tests with this env have been run } } }, setup() { // custom setup return { teardown() { // called after all tests with this env have been run } } } }警告Vitest 要求环境对象提供viteEnvironment选项默认回退为 Vitest 环境名。它必须等于ssr、client或任意自定义 Vite 环境名该值决定了处理文件时使用的环境。扩展内置环境builtinEnvironments 与 populateGlobalVitest 通过vitest/environments入口暴露builtinEnvironments方便你在内置环境基础上扩展import { builtinEnvironments, populateGlobal } from vitest/runtime console.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime }builtinEnvironments的实际导出定义在 packages/vitest/src/public/runtime.tsexport { environments as builtinEnvironments }底层即 index.ts 中注册的四个内置环境对象。populateGlobal工具函数可以把对象上的属性迁移到全局命名空间interface PopulateOptions { // should non-class functions be bind to the global namespace bindFunctions?: boolean } interface PopulateResult { // a list of all keys that were copied, even if value doesnt exist on original object keys: Setstring // a map of property descriptors for keys that might have been overridden // you can restore them with Object.defineProperty inside teardown originals: Mapstring | symbol, PropertyDescriptor } export function populateGlobal(global: any, original: any, options: PopulateOptions): PopulateResult它的实现位于 packages/vitest/src/integrations/env/utils.tsoriginals记录被覆盖的属性描述符你可以在teardown中用Object.defineProperty恢复它们这是 jsdom / happy-dom 环境实现全局注入与清理的关键基础设施。关于 jsdom 环境的 TypeScript 类型支持jsdom 环境会暴露jsdom全局变量指向当前的 JSDOM 实例。如果使用 TypeScript需要在tsconfig.json中把vitest/jsdom加入 types让 TS 识别该全局变量{ compilerOptions: { types: [vitest/jsdom] } }混合环境实践与注意事项综合以上内容落地一个同一项目混合多环境的典型配置配置文件全局默认nodeUI 相关测试文件用vitest-environment注释切到jsdom并通过environmentOptions为每个环境传入独立参数。参考仓库中 mixed-environments 的 fixtures 结构即可验证该模式可行。常见问题CSS / 资源导入失败在jsdom或happy-dom环境下Vitest 遵循与 Vite 相同的规则处理 CSS 与静态资源导入。如果导入外部依赖时报unknown extension .css错误需要把整条导入链上的包手动加入server.deps.inline。例如导入链为source code - package-1 - package-2 - package-3且错误发生在package-3则需要把这三个包全部加入server.deps.inline。外部依赖中对 CSS 和资源的require会自动解析。小结environment默认node可通过配置或--environmentenvCLI 切换Web 项目选jsdom/happy-dom边缘函数选edge-runtime。用vitest-environment/jest-environment注释可精确到文件粒度切换环境仓库 e2e 用例mixed-environments)提供了可运行的参考。environmentOptions按环境名作用域传参是给 jsdom如url与 happy-dom如width/height注入选项的标准入口。自定义环境需导出含setup/setupVM与teardown的Environment对象裸包名会按vitest-environment-${name}解析viteEnvironment决定文件由哪个 Vite 环境处理。builtinEnvironments与populateGlobal从vitest/runtime导出是扩展内置环境、实现全局属性注入与清理的底层 API。【免费下载链接】vitestNext generation testing framework powered by Vite.项目地址: https://gitcode.com/GitHub_Trending/vi/vitest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。