Nx Monorepo中React+Vite项目Jest测试遇import.meta TS1343错误求助
Nx Monorepo + React + Jest 中 import.meta.env 编译错误解决
报错信息
error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.
const chatApiUrl = import.meta.env.VITE_CHAT_API_URL || "";
场景说明
在Nx Monorepo的React工作区中配置了Jest测试环境,项目使用vite.config.ts,.env.test中已定义VITE_CHAT_API_URL,但单元测试因上述import.meta相关语法问题失败。
被测代码
const BACKEND_URI = ""; const chatApiUrl = import.meta.env.VITE_CHAT_API_URL || ""; const connection = new signalR.HubConnectionBuilder() .withUrl(chatApiUrl, { withCredentials: false }) .build(); connection.start() .then(() => console.log("Connected to SignalR hub")) .catch(err => console.error("Error connecting to SignalR hub: ", err));
测试文件
import { getHeaders } from './api'; describe('getHeaders', () => { it('should return the Authorization header if useLogin is true, isUsingAppServicesLogin is false, and idToken is provided', async () => { const headers = await getHeaders('some-id-token'); expect(headers).toEqual({ Authorization: 'Bearer some-id-token' }); }); });
已尝试修改的配置文件
tsconfig.spec.json
{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": ["jest", "node"], "module": "esnext", "target": "esnext", "allowJs": true, "noEmit": true, "isolatedModules": true, "esModuleInterop": true, "skipLibCheck": true }, "include": [ "src/**/*.spec.ts", "src/**/*.spec.tsx", "src/**/*.d.ts" ] }
tsconfig.json
{ "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "lib": [ "dom", "dom.iterable", "esnext", "es2020" ], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "sourceMap": true, "forceConsistentCasingInFileNames": true, "module": "esnext", "preserveConstEnums": true, "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "types": ["vite/client", "jest", "node"], "outDir": "dist" }, "include": ["src/**/*.ts", "src/**/*.tsx", "tests/**/*.ts", "tests/**/*.tsx"], "exclude": ["node_modules"], "extends": "../../tsconfig.base.json" }
tsconfig.base.json
{ "compileOnSave": false, "compilerOptions": { "rootDir": ".", "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2020", "module": "esnext", "lib": ["es2020", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", "paths": {} }, "include": ["**/*.ts", "**/*.tsx"], "exclude": ["node_modules", "dist", "tmp"] }
jest.preset.ts
const nxPreset = require('@nx/jest/preset').default; module.exports = { ...nxPreset, testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], transform: { '^.+\.(ts|js|html)$': 'ts-jest', }, resolver: '@nx/jest/plugins/resolver', moduleFileExtensions: ['ts', 'js', 'html'], coverageReporters: ['html'], };
jest.config.ts
import { getJestProjects } from '@nx/jest'; export default { projects: getJestProjects(), setupFiles: ['./jest.setup.ts'], };
解决方法
1. 让ts-jest支持ESM及import.meta
修改jest.preset.ts,启用ts-jest的ESM支持,同时添加环境变量模拟:
const nxPreset = require('@nx/jest/preset').default; module.exports = { ...nxPreset, testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], transform: { '^.+\.(ts|js|html)$': ['ts-jest', { useESM: true }], }, resolver: '@nx/jest/plugins/resolver', moduleFileExtensions: ['ts', 'js', 'html'], coverageReporters: ['html'], globals: { 'ts-jest': { tsconfig: 'tsconfig.spec.json', } }, moduleNameMapper: { // 直接模拟环境变量值 'import.meta.env.VITE_CHAT_API_URL': '"http://localhost:5000/chat-hub"' } };
2. 通过dotenv加载.env.test变量
安装dotenv依赖:
npm install dotenv --save-dev
在jest.setup.ts中添加加载逻辑并全局模拟import.meta:
import dotenv from 'dotenv'; dotenv.config({ path: '.env.test' }); // 全局挂载import.meta global.import.meta = { env: process.env };
3. 调整tsconfig.spec.json配置
将tsconfig.spec.json中的isolatedModules设为false,避免与ts-jest的ESM模式冲突:
"isolatedModules": false
4. 确保import.meta的类型支持
在src目录下创建/更新vite-env.d.ts:
/// <reference types="vite/client" /> interface ImportMetaEnv { readonly VITE_CHAT_API_URL: string; } interface ImportMeta { readonly env: ImportMetaEnv; }
内容的提问来源于stack exchange,提问作者so-user
相关产品推荐
相关产品推荐

