.env 变量未正确加载/读取

问题描述 投票:0回答:1

我们的项目是一个React和TypeScript项目,首先使用React App Rewired制作,但现在迁移到Vite。

我一直致力于让 Jest 工作(在尝试使用 Vitest 后,我遇到了完全不同的问题)。我现在遇到的问题是它给了我这个错误消息:

Test suite failed to run

    TypeError: Cannot read properties of undefined (reading 'VITE_HOST')

其中

VITE_HOST
在我们的
.test.env
文件中定义如下:

VITE_HOST="http://localhost:3000"

我正在运行的脚本如下:

    "test": "dotenv -e ./src/environments/.env.test jest --testResultsProcessor --detectOpenHandles --bail",

我已经通过这样做测试了

.env
文件是否正在加载:

dotenv -e ./src/environments/.env.test node -e
// Followed by:
 console.log(process.env)

实际上正确记录了所有环境变量。

我的

jest.config.js
看起来像这样:

/** @type {import('ts-jest').JestConfigWithTsJest} **/
module.exports = {
  testEnvironment: 'jest-environment-jsdom',
  transform: {
    '^.+\\.m?[tj]sx?$': [
      'ts-jest',
      {
        moduleNameMapper: {
          '\\.(css|less|scss|sass)$': '<rootDir>/__mocks__/styleMock.js',
          '\\.(gif|ttf|eot|svg|png)$': '<rootDir>/__mocks__/fileMock.js',
          '@testing-library/jest-dom/extend-expect':
            '@testing-library/jest-dom',
        },
        transformIgnorePatterns: ['node_modules/(?!variables/.*)'],
        useESM: true,
        babelConfig: true,
        diagnostics: {
          ignoreCodes: [1343],
        },
        astTransformers: {
          before: [
            {
              path: 'node_modules/ts-jest-mock-import-meta',
              options: {
                metaObjectReplacement: { url: 'https://www.url.com' },
              },
            },
          ],
        },
      },
    ],
  },
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  setupFiles: ['dotenv/config'],
  maxWorkers: 1,
  moduleNameMapper: {
    '\\.(css|less|scss|sass)$': '<rootDir>/__mocks__/styleMock.js',
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '<rootDir>/__mocks__/fileMock.js',
    '@testing-library/jest-dom/extend-expect': '@testing-library/jest-dom',
  },
};

为了获取环境变量,我们有一个执行以下操作的函数:

export const getProcessEnv = (key: string): ProcessEnv =>
  new ProcessEnv(key, import.meta.env[key]);

export class ProcessEnv {
  constructor(public name: string, public rawValue: string | undefined) {}

然后在我们的

environment.ts
文件中使用它,如下所示:

import { getProcessEnv } from '../utils/environmentValidator';

const allowedEnvironmentTypes = [
  'local',
  'staging',
  'production',
  'test',
] as const;

export const ENV = {
  HOST: getProcessEnv('VITE_HOST').asString(''),

之后我们使用导出的

ENV
const 中的环境变量。然而,即使只是做
import.meta.env.VITE_HOST
也不起作用。显然,它不应该返回“未定义”。

reactjs typescript jestjs vite ts-jest
1个回答
0
投票

Vite使用

import.meta.env
访问环境变量,这些变量在构建时静态替换。

另一方面,

Jest 在通常使用

Node.js
process.env
环境中运行。

由于您在

import.meta.env.VITE_HOST
函数中使用了
getProcessEnv
,因此它不适用于 Jest,因为 Jest 不理解
import.meta.env

修改

getProcessEnv
函数以同时检查
import.meta.env
process.env
。这样,它就可以在 Vite 和 Jest 环境中无缝运行:

export const getProcessEnv = (key: string): ProcessEnv => {
  const value = import.meta.env[key] || process.env[key];
  return new ProcessEnv(key, value);
};

export class ProcessEnv {
  constructor(public name: string, public rawValue: string | undefined) {}
  
  asString(defaultValue: string): string {
    return this.rawValue ?? defaultValue;
  }
}

通过结合对 Vite 配置的更新和调整 getProcessEnv 函数,您可以确保在 Vite 和 Jest 环境中一致地访问环境变量。

还可以通过添加测试用例来验证 process.env.VITE_HOST 是否可以在 Jest 中访问:

test('Environment variable VITE_HOST is defined', () => {
  expect(process.env.VITE_HOST).toBeDefined();
});

如果通过,问题确实与 Jest 中无法访问 import.meta.env 有关。

要使环境变量在整个项目中可作为

process.env
访问,请更新您的 vite.config.ts,如下所示:

import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react-swc';
import checker from 'vite-plugin-checker';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');

  return {
    plugins: [
      react(),
      tsconfigPaths(),
      checker({
        typescript: true,
        eslint: {
          lintCommand: 'eslint "./src/**/*.{ts,tsx}"',
        },
      }),
    ],
    define: {
      'process.env': JSON.stringify(env), // Makes all env variables available globally
    },
    build: {
      outDir: 'build',
      sourcemap: true,
      chunkSizeWarningLimit: 1000,
    },
  };
});

此设置确保 process.env.VITE_HOST 和其他环境变量在 Vite 构建的代码和 Jest 测试中都可用。

© www.soinside.com 2019 - 2024. All rights reserved.