You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用import.meta导致Jest测试失败(React+TypeScript+Vite环境)

解决Jest中.ts文件import.meta.env未定义的问题

针对你的场景——ts-jest-mock-import-meta仅解决了.tsx文件的import.meta问题,但.ts文件仍报错,以下是几种可行的解决方案:

方案1:修复ts-jest-mock-import-meta的配置覆盖问题

你的transform规则^.+\\.tsx?$理论上覆盖.ts和.tsx文件,但项目启用ESM(package.json中type: "module")可能导致ts-jest对.ts文件的转换逻辑异常,可按以下方式调整:

调整为CommonJS风格配置(兼容性更好)

移除jest.config.ts中的type: 'module',改用CommonJS导出:

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jest-environment-jsdom',
  transform: {
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        diagnostics: {
          ignoreCodes: [1343],
        },
        astTransformers: {
          before: [
            {
              path: 'ts-jest-mock-import-meta',
              options: {
                metaObjectReplacement: {
                  API_ENDPOINT: 'https://www.url.com',
                  API_URL: 'https://www.url.com', // 补充代码中用到的API_URL
                  test2: 'test2',
                  test3: 'test3',
                },
              },
            },
          ],
        },
      },
    ],
  },
  moduleNameMapper: {
    '\\.(gif|ttf|eot|svg|png)$': '<rootDir>/src/test/__mocks__/fileMock.js',
    '\\.(css|less)$': '<rootDir>/src/test/__mocks__/styleMock.js',
  },
  setupFiles: ['<rootDir>/jest.setup.ts'],
};

保留ESM配置的适配

若必须使用ESM,添加ESM相关配置项:

export default {
  preset: 'ts-jest',
  testEnvironment: 'jest-environment-jsdom',
  extensionsToTreatAsEsm: ['.ts', '.tsx'],
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
    '\\.(gif|ttf|eot|svg|png)$': '<rootDir>/src/test/__mocks__/fileMock.js',
    '\\.(css|less)$': '<rootDir>/src/test/__mocks__/styleMock.js',
  },
  transform: {
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        useESM: true,
        diagnostics: {
          ignoreCodes: [1343],
        },
        astTransformers: {
          before: [
            {
              path: 'ts-jest-mock-import-meta',
              options: {
                metaObjectReplacement: {
                  API_ENDPOINT: 'https://www.url.com',
                  API_URL: 'https://www.url.com',
                  test2: 'test2',
                  test3: 'test3',
                },
              },
            },
          ],
        },
      },
    ],
  },
  setupFiles: ['<rootDir>/jest.setup.ts'],
};

方案2:全局模拟import.meta.env(简单直接)

跳过第三方库,直接在jest初始化阶段全局模拟import.meta.env,对.ts和.tsx文件均生效:

  1. 在jest.setup.ts中添加模拟代码:
// 全局模拟import.meta.env
Object.defineProperty(globalThis, 'import.meta', {
  value: {
    env: {
      API_ENDPOINT: 'https://www.url.com',
      API_URL: 'https://www.url.com',
      // 按需添加其他环境变量
    },
  },
});
  1. 为TypeScript添加类型声明,创建src/types/global.d.ts:
declare global {
  interface ImportMeta {
    env: {
      API_ENDPOINT?: string;
      API_URL?: string;
      // 定义所有用到的环境变量类型
    };
  }
}

export {};

适配条件调用场景

这种方式完全兼容你条件使用环境变量的代码:

const apiURL = import.meta.env.API_URL ? `${import.meta.env.API_URL}` : "http://localhost:8080"

若需要测试API_URL为undefined的场景,可在单测文件中单独覆盖:

beforeEach(() => {
  (globalThis.import.meta.env as any).API_URL = undefined;
});

test('API_URL未定义时使用默认地址', () => {
  // 执行测试逻辑
});

方案3:自定义AST转换器(灵活可控)

编写自定义ts-jest转换器,精准替换import.meta.env引用:

  1. 创建src/test/transformers/mock-import-meta.ts:
import type { ASTTransformer } from 'ts-jest';

const mockImportMetaTransformer: ASTTransformer = (tsJestService) => {
  const { types: t } = tsJestService;
  return (context) => ({
    visitor: {
      MemberExpression(path) {
        // 匹配 import.meta.env.XXX 的结构
        if (
          t.isMetaProperty(path.node.object) &&
          path.node.object.meta.name === 'import' &&
          path.node.object.property.name === 'meta' &&
          t.isMemberExpression(path.node.property) &&
          path.node.property.object.name === 'env'
        ) {
          const envVar = path.node.property.property.name;
          // 定义模拟的环境变量值
          const mockEnv = {
            API_ENDPOINT: 'https://www.url.com',
            API_URL: 'https://www.url.com',
          };
          // 替换为对应值,未定义则返回undefined
          const replacementValue = mockEnv[envVar as keyof typeof mockEnv] ?? undefined;
          path.replaceWith(
            replacementValue ? t.stringLiteral(replacementValue) : t.identifier('undefined')
          );
        }
      },
    },
  });
};

export default mockImportMetaTransformer;
  1. 在jest.config.ts中替换astTransformer配置:
transform: {
  '^.+\\.tsx?$': [
    'ts-jest',
    {
      diagnostics: {
        ignoreCodes: [1343],
      },
      astTransformers: {
        before: [
          '<rootDir>/src/test/transformers/mock-import-meta.ts'
        ],
      },
    },
  ],
},

内容的提问来源于stack exchange,提问作者João Freitas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:15:17