如何在Vite+React项目的Playwright测试中正确解析环境变量?
解决Vite React项目中Playwright测试的环境变量兼容问题
问题根源
Playwright配置文件运行在Node.js环境中,而import.meta.env是Vite专为浏览器/前端构建环境注入的变量,Node环境中不存在import.meta对象,直接导入依赖该变量的前端代码(如src/constants.ts)会触发TypeError: Cannot read properties of undefined (reading 'MODE')错误。
可行解决方案
方案1:在Node环境模拟import.meta.env
在Playwright配置文件中,先加载环境变量,再模拟Vite的import.meta.env对象,确保导入前端代码时变量可用:
import { defineConfig, devices } from "@playwright/test"; import dotenv from 'dotenv'; // 加载.env文件中的环境变量 dotenv.config({ path: '.env' }); // 为Node环境模拟Vite注入的import.meta.env globalThis.import.meta = { env: { MODE: process.env.MODE || 'testing', // 若需其他Vite环境变量,可在此添加 } } as any; // 模拟完成后再导入前端的constants模块 import { BASE_URL as baseURL } from "./src/constants"; export default defineConfig({ testDir: "./e2e", fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: "html", use: { baseURL, trace: "on-first-retry", }, });
方案2:拆分环境变量逻辑,兼容双环境
将环境变量的获取逻辑封装为兼容Node和Vite环境的工具函数,避免直接依赖单一环境变量:
- 创建
src/env-utils.ts:
export function getEnvMode() { // 优先识别Vite环境 if (typeof import.meta !== 'undefined') { return import.meta.env.MODE; } // 其次识别Node环境 else if (typeof process !== 'undefined') { return process.env.MODE || 'testing'; } // 默认返回生产环境 return 'production'; }
- 修改
src/constants.ts使用工具函数:
import { getEnvMode } from './env-utils'; let BASE_URL: string; const testMode = getEnvMode(); if (testMode === "testing") { BASE_URL = "http://testing.com"; } else if (testMode === "dev") { BASE_URL = "http://dev.com"; } else { BASE_URL = "http://production.com"; } export { BASE_URL };
- Playwright配置文件无需额外修改,正常导入
BASE_URL即可:
import { defineConfig, devices } from "@playwright/test"; import { BASE_URL as baseURL } from "./src/constants"; import dotenv from 'dotenv'; dotenv.config({ path: '.env' }); export default defineConfig({ testDir: "./e2e", fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: "html", use: { baseURL, trace: "on-first-retry", }, });
方案3:独立处理Playwright的环境变量
如果不需要和前端共享BASE_URL的逻辑,可直接在Playwright配置中根据process.env.MODE计算baseURL,避免依赖前端代码:
import { defineConfig, devices } from "@playwright/test"; import dotenv from 'dotenv'; dotenv.config({ path: '.env' }); let baseURL: string; const testMode = process.env.MODE || 'testing'; if (testMode === "testing") { baseURL = "http://testing.com"; } else if (testMode === "dev") { baseURL = "http://dev.com"; } else { baseURL = "http://production.com"; } export default defineConfig({ testDir: "./e2e", fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: "html", use: { baseURL, trace: "on-first-retry", }, });
注意事项
- 确保
.env文件中已正确设置MODE变量(如MODE=testing)。 - 若使用方案1,需注意
globalThis.import.meta的类型断言(as any)是为了绕过TypeScript类型检查,若需更严谨的类型,可定义对应的接口。
内容的提问来源于stack exchange,提问作者omelnik
相关产品推荐
相关产品推荐

