diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts index a076e0812a0bc1..11135dcb03b0d6 100644 --- a/packages/vite/src/node/plugins/define.ts +++ b/packages/vite/src/node/plugins/define.ts @@ -6,6 +6,7 @@ import { isCSSRequest } from './css' import { isHTMLRequest } from './html' const nonJsRe = /\.json(?:$|\?)/ +const metaEnvRe = /import\.meta\.env\.(.+)/ const isNonJsRequest = (request: string): boolean => nonJsRe.test(request) export function definePlugin(config: ResolvedConfig): Plugin { @@ -30,10 +31,17 @@ export function definePlugin(config: ResolvedConfig): Plugin { }) } + const env = { ...config.env } const userDefine: Record = {} for (const key in config.define) { const val = config.define[key] userDefine[key] = typeof val === 'string' ? val : JSON.stringify(val) + + // make sure `import.meta.env` object has user define properties + const match = key.match(metaEnvRe) + if (match) { + env[match[1]] = val + } } // during dev, import.meta properties are handled by importAnalysis plugin. @@ -41,10 +49,8 @@ export function definePlugin(config: ResolvedConfig): Plugin { const importMetaKeys: Record = {} const importMetaFallbackKeys: Record = {} if (isBuild) { - const env: Record = { - ...config.env, - SSR: !!config.build.ssr, - } + env.SSR = !!config.build.ssr + // set here to allow override with config.define importMetaKeys['import.meta.hot'] = `undefined` for (const key in env) { @@ -52,7 +58,7 @@ export function definePlugin(config: ResolvedConfig): Plugin { } Object.assign(importMetaFallbackKeys, { 'import.meta.env.': `({}).`, - 'import.meta.env': JSON.stringify(config.env), + 'import.meta.env': JSON.stringify(env), }) } diff --git a/playground/env/__tests__/env.spec.ts b/playground/env/__tests__/env.spec.ts index 227f6b5c09ccfe..dc4a32653efdab 100644 --- a/playground/env/__tests__/env.spec.ts +++ b/playground/env/__tests__/env.spec.ts @@ -49,6 +49,10 @@ test('expand', async () => { expect(await page.textContent('.expand')).toBe('expand') }) +test('ssr', async () => { + expect(await page.textContent('.ssr')).toBe('false') +}) + test('env object', async () => { const envText = await page.textContent('.env-object') expect(JSON.parse(envText)).toMatchObject({ @@ -56,6 +60,8 @@ test('env object', async () => { CUSTOM_PREFIX_ENV_VARIABLE: '1', VITE_CUSTOM_ENV_VARIABLE: '1', BASE_URL: '/env/', + VITE_BOOL: true, + SSR: false, MODE: mode, DEV: !isBuild, PROD: isBuild, diff --git a/playground/env/index.html b/playground/env/index.html index 6ccfd421945418..9b698ff237e426 100644 --- a/playground/env/index.html +++ b/playground/env/index.html @@ -15,6 +15,7 @@

Environment Variables

typeof import.meta.env.VITE_BOOL:

process.env.NODE_ENV:

import.meta.env.VITE_EXPAND:

+

import.meta.env.SSR:

import.meta.env:

import.meta.url:

@@ -28,6 +29,7 @@

Environment Variables

text('.mode-file', import.meta.env.VITE_EFFECTIVE_MODE_FILE_NAME) text('.inline', import.meta.env.VITE_INLINE) text('.bool', typeof import.meta.env.VITE_BOOL) + text('.ssr', import.meta.env.SSR) text('.node-env', process.env.NODE_ENV) text('.env-object', JSON.stringify(import.meta.env, null, 2)) text('.expand', import.meta.env.VITE_EXPAND)