diff --git a/packages/vitest/src/node/plugins/index.ts b/packages/vitest/src/node/plugins/index.ts index 371e488a7f90..465471b11b25 100644 --- a/packages/vitest/src/node/plugins/index.ts +++ b/packages/vitest/src/node/plugins/index.ts @@ -12,7 +12,7 @@ import { GlobalSetupPlugin } from './globalSetup' import { CSSEnablerPlugin } from './cssEnabler' import { CoverageTransform } from './coverageTransform' import { MocksPlugin } from './mocks' -import { deleteDefineConfig, resolveOptimizerConfig } from './utils' +import { deleteDefineConfig, hijackVitePluginInject, resolveOptimizerConfig } from './utils' import { VitestResolver } from './vitestResolver' export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('test')): Promise { @@ -158,6 +158,8 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t ignored: ['**/*'], } } + + hijackVitePluginInject(viteConfig) }, async configureServer(server) { if (options.watch && process.env.VITE_TEST_WATCHER_DEBUG) { diff --git a/packages/vitest/src/node/plugins/utils.ts b/packages/vitest/src/node/plugins/utils.ts index 5e0bab6a46c2..8b0a038a9a92 100644 --- a/packages/vitest/src/node/plugins/utils.ts +++ b/packages/vitest/src/node/plugins/utils.ts @@ -1,6 +1,6 @@ import { builtinModules } from 'node:module' import { version as viteVersion } from 'vite' -import type { DepOptimizationOptions, UserConfig as ViteConfig } from 'vite' +import type { DepOptimizationOptions, ResolvedConfig, UserConfig as ViteConfig } from 'vite' import type { DepsOptimizationOptions, InlineConfig } from '../../types' export function resolveOptimizerConfig(_testOptions: DepsOptimizationOptions | undefined, viteOptions: DepOptimizationOptions | undefined, testConfig: InlineConfig) { @@ -73,3 +73,14 @@ export function deleteDefineConfig(viteConfig: ViteConfig) { } return defines } + +export function hijackVitePluginInject(viteConfig: ResolvedConfig) { + // disable replacing `process.env.NODE_ENV` with static string + const processEnvPlugin = viteConfig.plugins.find(p => p.name === 'vite:client-inject') + if (processEnvPlugin) { + const originalTransform = processEnvPlugin.transform as any + processEnvPlugin.transform = function transform(code, id, options) { + return originalTransform.call(this, code, id, { ...options, ssr: true }) + } + } +} diff --git a/packages/vitest/src/node/plugins/workspace.ts b/packages/vitest/src/node/plugins/workspace.ts index 0c88dcda76a7..97dc7639a234 100644 --- a/packages/vitest/src/node/plugins/workspace.ts +++ b/packages/vitest/src/node/plugins/workspace.ts @@ -10,7 +10,7 @@ import { CSSEnablerPlugin } from './cssEnabler' import { SsrReplacerPlugin } from './ssrReplacer' import { GlobalSetupPlugin } from './globalSetup' import { MocksPlugin } from './mocks' -import { deleteDefineConfig, resolveOptimizerConfig } from './utils' +import { deleteDefineConfig, hijackVitePluginInject, resolveOptimizerConfig } from './utils' import { VitestResolver } from './vitestResolver' interface WorkspaceOptions extends UserWorkspaceConfig { @@ -100,6 +100,9 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp return config }, + configResolved(viteConfig) { + hijackVitePluginInject(viteConfig) + }, async configureServer(server) { try { const options = deepMerge( diff --git a/test/core/test/env-jsdom.test.ts b/test/core/test/env-jsdom.test.ts new file mode 100644 index 000000000000..8b6cec40c1b9 --- /dev/null +++ b/test/core/test/env-jsdom.test.ts @@ -0,0 +1,51 @@ +// @vitest-environment jsdom + +import { afterAll, expect, test } from 'vitest' +import { getAuthToken } from '../src/env' + +const NODE_ENV = process.env.NODE_ENV + +afterAll(() => { + process.env.NODE_ENV = NODE_ENV +}) + +test('reassigning NODE_ENV', () => { + expect(process.env.NODE_ENV).toBeDefined() + process.env.NODE_ENV = 'development' + expect(process.env.NODE_ENV).toBe('development') +}) + +test('reads envs from .env file', () => { + expect(import.meta.env.VITE_TEST_ENV).toBe('local') +}) + +test('can reassign env locally', () => { + import.meta.env.VITEST_ENV = 'TEST' + expect(import.meta.env.VITEST_ENV).toBe('TEST') +}) + +test('can reassign env everywhere', () => { + import.meta.env.AUTH_TOKEN = '123' + expect(getAuthToken()).toBe('123') + process.env.AUTH_TOKEN = '321' + expect(getAuthToken()).toBe('321') +}) + +test('can see env in "define"', () => { + expect(import.meta.env.TEST_NAME).toBe('hello world') + expect(process.env.TEST_NAME).toBe('hello world') +}) + +test('has worker env', () => { + expect(process.env.VITEST_WORKER_ID).toBeDefined() + expect(process.env.VITEST_POOL_ID).toBeDefined() +}) + +test('custom env', () => { + expect(process.env.CUSTOM_ENV).toBe('foo') + expect(import.meta.env.CUSTOM_ENV).toBe('foo') +}) + +test('ignores import.meta.env in string literals', () => { + expect('import.meta.env').toBe('import' + '.meta.env') +})