[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

feat: allow changing import.meta.env (#714)

authored by

Vladimir and committed by
GitHub
(Feb 10, 2022, 12:52 AM +0800) 5f007889 d02db1b4

+86
+3
test/core/vitest.config.ts
··· 17 17 }, 18 18 }, 19 19 ], 20 + define: { 21 + 'import.meta.env.TEST_NAME': '"hello world"', 22 + }, 20 23 test: { 21 24 testTimeout: 2000, 22 25 // threads: false,
+3
test/core/src/env.ts
··· 1 + export function getAuthToken() { 2 + return import.meta.env.AUTH_TOKEN 3 + }
+19
test/core/test/env.test.ts
··· 1 + import { expect, test } from 'vitest' 2 + import { getAuthToken } from '../src/env' 3 + 4 + test('can reassign env locally', () => { 5 + import.meta.env.VITEST_ENV = 'TEST' 6 + expect(import.meta.env.VITEST_ENV).toBe('TEST') 7 + }) 8 + 9 + test('can reassign env everywhere', () => { 10 + import.meta.env.AUTH_TOKEN = '123' 11 + expect(getAuthToken()).toBe('123') 12 + process.env.AUTH_TOKEN = '321' 13 + expect(getAuthToken()).toBe('321') 14 + }) 15 + 16 + test('can see env in "define"', () => { 17 + expect(import.meta.env.TEST_NAME).toBe('hello world') 18 + expect(process.env.TEST_NAME).toBe('hello world') 19 + })
+12
test/core/types/env.d.ts
··· 1 + interface ImportMeta { 2 + readonly env: ImportMetaEnv 3 + } 4 + 5 + interface ImportMetaEnv { 6 + [key: string]: string | boolean | undefined 7 + BASE_URL: string 8 + MODE: string 9 + DEV: boolean 10 + PROD: boolean 11 + SSR: boolean 12 + }
+30
packages/vitest/src/node/plugins/envReplacer.ts
··· 1 + import MagicString from 'magic-string' 2 + import type { Plugin } from 'vite' 3 + 4 + export const EnvReplacerPlugin = (): Plugin => { 5 + return { 6 + name: 'vitest:env-replacer', 7 + enforce: 'pre', 8 + transform(code) { 9 + let s: MagicString | null = null 10 + 11 + const envs = code.matchAll(/\bimport\.meta\.env\b/g) 12 + 13 + for (const env of envs) { 14 + s ||= new MagicString(code) 15 + 16 + const startIndex = env.index! 17 + const endIndex = startIndex + env[0].length 18 + 19 + s.overwrite(startIndex, endIndex, 'process.env') 20 + } 21 + 22 + if (s) { 23 + return { 24 + code: s.toString(), 25 + map: s.generateMap({ hires: true }), 26 + } 27 + } 28 + }, 29 + } 30 + }
+19
packages/vitest/src/node/plugins/index.ts
··· 6 6 import { Vitest } from '../core' 7 7 import { GlobalSetupPlugin } from './globalSetup' 8 8 import { MocksPlugin } from './mock' 9 + import { EnvReplacerPlugin } from './envReplacer' 9 10 10 11 export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest()): Promise<VitePlugin[]> { 11 12 let haveStarted = false ··· 57 58 ) 58 59 options.api = resolveApiConfig(options) 59 60 options.watch = options.watch && !options.run 61 + 62 + process.env.BASE_URL ??= viteConfig.base 63 + process.env.MODE ??= viteConfig.mode 64 + // process.env can have only string values and will cast string on it if we pass other type, 65 + // so we are making them truthy 66 + process.env.PROD ??= viteConfig.env.PROD ? '1' : '' 67 + process.env.DEV ??= viteConfig.env.DEV ? '1' : '' 68 + process.env.SSR ??= '1' 69 + 70 + // account for user env defines 71 + for (const key in viteConfig.define) { 72 + if (key.startsWith('import.meta.env.')) { 73 + const val = viteConfig.define[key] 74 + const envKey = key.slice('import.meta.env.'.length) 75 + process.env[envKey] = typeof val === 'string' ? JSON.parse(val) : val 76 + } 77 + } 60 78 }, 61 79 async configureServer(server) { 62 80 if (haveStarted) ··· 71 89 await server.watcher.close() 72 90 }, 73 91 }, 92 + EnvReplacerPlugin(), 74 93 MocksPlugin(), 75 94 GlobalSetupPlugin(ctx), 76 95 options.ui