diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index bda226ff7d4c54..1948c169b83774 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -963,11 +963,21 @@ export function htmlEnvHook(config: ResolvedConfig): IndexHtmlTransformHook { const pattern = /%(\S+?)%/g const envPrefix = resolveEnvPrefix({ envPrefix: config.envPrefix }) const env: Record = { ...config.env } + // account for user env defines for (const key in config.define) { if (key.startsWith(`import.meta.env.`)) { const val = config.define[key] - env[key.slice(16)] = typeof val === 'string' ? val : JSON.stringify(val) + if (typeof val === 'string') { + try { + const parsed = JSON.parse(val) + env[key.slice(16)] = typeof parsed === 'string' ? parsed : val + } catch { + env[key.slice(16)] = val + } + } else { + env[key.slice(16)] = JSON.stringify(val) + } } } return (html, ctx) => { diff --git a/playground/html/__tests__/html.spec.ts b/playground/html/__tests__/html.spec.ts index 815fc68f7b88c0..a53254aba56835 100644 --- a/playground/html/__tests__/html.spec.ts +++ b/playground/html/__tests__/html.spec.ts @@ -294,6 +294,14 @@ describe('env', () => { test('env works', async () => { expect(await page.textContent('.env')).toBe('bar') expect(await page.textContent('.env-define')).toBe('5173') + expect(await page.textContent('.env-define-string')).toBe('string') + expect(await page.textContent('.env-define-object-string')).toBe( + '{ "foo": "bar" }', + ) + expect(await page.textContent('.env-define-template-literal')).toBe( + '`template literal`', // only double quotes will be unquoted + ) + expect(await page.textContent('.env-define-null-string')).toBe('null') expect(await page.textContent('.env-bar')).toBeTruthy() expect(await page.textContent('.env-prod')).toBe(isBuild + '') expect(await page.textContent('.env-dev')).toBe(isServe + '') diff --git a/playground/html/env.html b/playground/html/env.html index 056377071c19fb..5a87114201bdce 100644 --- a/playground/html/env.html +++ b/playground/html/env.html @@ -1,5 +1,9 @@

%VITE_FOO%

%VITE_NUMBER%

+

%VITE_STRING%

+

%VITE_OBJECT_STRING%

+

%VITE_TEMPLATE_LITERAL%

+

%VITE_NULL_STRING%

class name should be env-bar

%PROD%

%DEV%

diff --git a/playground/html/vite.config.js b/playground/html/vite.config.js index 78eca9ea504a9b..9115ecaf3900cd 100644 --- a/playground/html/vite.config.js +++ b/playground/html/vite.config.js @@ -36,6 +36,10 @@ export default defineConfig({ define: { 'import.meta.env.VITE_NUMBER': 5173, + 'import.meta.env.VITE_STRING': JSON.stringify('string'), + 'import.meta.env.VITE_OBJECT_STRING': '{ "foo": "bar" }', + 'import.meta.env.VITE_TEMPLATE_LITERAL': '`template literal`', + 'import.meta.env.VITE_NULL_STRING': 'null', }, plugins: [