Skip to content

Commit 059070e

Browse files
committed
refactor: make define option perform direct replacement instead
BREAKING CHANGE: `define` option no longer calls `JSON.stringify` on string values. This means string define values will be now treated as raw expressions. To define a string constant, explicit quotes are now required.
1 parent 26d409b commit 059070e

File tree

7 files changed

+34
-19
lines changed

7 files changed

+34
-19
lines changed

packages/playground/define/__tests__/define.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
test('string', async () => {
22
const defines = require('../vite.config.js').define
33

4-
expect(await page.textContent('.string')).toBe(String(defines.__STRING__))
4+
expect(await page.textContent('.exp')).toBe(String(eval(defines.__EXP__)))
5+
expect(await page.textContent('.string')).toBe(JSON.parse(defines.__STRING__))
56
expect(await page.textContent('.number')).toBe(String(defines.__NUMBER__))
67
expect(await page.textContent('.boolean')).toBe(String(defines.__BOOLEAN__))
78
expect(await page.textContent('.object')).toBe(

packages/playground/define/index.html

+2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<h1>Define</h1>
22

3+
<p>Raw Expression <code class="exp"></code></p>
34
<p>String <code class="string"></code></p>
45
<p>Number <code class="number"></code></p>
56
<p>Boolean <code class="boolean"></code></p>
67
<p>Object <span class="pre object"></span></p>
78

89
<script type="module">
10+
text('.exp', __EXP__)
911
text('.string', __STRING__)
1012
text('.number', __NUMBER__)
1113
text('.boolean', __BOOLEAN__)

packages/playground/define/vite.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module.exports = {
22
define: {
3-
__STRING__: 'hello',
3+
__EXP__: '1 + 1',
4+
__STRING__: '"hello"',
45
__NUMBER__: 123,
56
__BOOLEAN__: true,
67
__OBJ__: {

packages/vite/src/node/config.ts

-9
Original file line numberDiff line numberDiff line change
@@ -269,15 +269,6 @@ export async function resolveConfig(
269269

270270
// load .env files
271271
const userEnv = loadEnv(mode, resolvedRoot)
272-
// check if user defined any import.meta.env variables
273-
if (config.define) {
274-
const prefix = `import.meta.env.`
275-
for (const key in config.define) {
276-
if (key.startsWith(prefix)) {
277-
userEnv[key.slice(prefix.length)] = config.define[key]
278-
}
279-
}
280-
}
281272

282273
// Note it is possible for user to have a custom mode, e.g. `staging` where
283274
// production-like behavior is expected. This is indicated by NODE_ENV=production

packages/vite/src/node/plugins/clientInjections.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin {
4444
.replace(`__MODE__`, JSON.stringify(config.mode))
4545
.replace(`__BASE__`, JSON.stringify(config.base))
4646
.replace(`__ROOT__`, JSON.stringify(config.root))
47-
.replace(`__DEFINES__`, JSON.stringify(config.define || {}))
47+
.replace(`__DEFINES__`, serializeDefine(config.define || {}))
4848
.replace(`__HMR_PROTOCOL__`, JSON.stringify(protocol))
4949
.replace(`__HMR_HOSTNAME__`, JSON.stringify(host))
5050
.replace(`__HMR_PORT__`, JSON.stringify(port))
@@ -60,3 +60,14 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin {
6060
}
6161
}
6262
}
63+
64+
function serializeDefine(define: Record<string, any>): string {
65+
let res = `{`
66+
for (const key in define) {
67+
const val = define[key]
68+
res += `${JSON.stringify(key)}: ${
69+
typeof val === 'string' ? `(${val})` : JSON.stringify(val)
70+
}, `
71+
}
72+
return res + `}`
73+
}

packages/vite/src/node/plugins/define.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ export function definePlugin(config: ResolvedConfig): Plugin {
99

1010
const userDefine: Record<string, string> = {}
1111
for (const key in config.define) {
12-
userDefine[key] = JSON.stringify(config.define[key])
12+
const val = config.define[key]
13+
userDefine[key] = typeof val === 'string' ? val : JSON.stringify(val)
1314
}
1415

1516
// during dev, import.meta properties are handled by importAnalysis plugin

packages/vite/src/node/plugins/importAnalysis.ts

+14-6
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,20 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
411411

412412
if (hasEnv) {
413413
// inject import.meta.env
414-
str().prepend(
415-
`import.meta.env = ${JSON.stringify({
416-
...config.env,
417-
SSR: !!ssr
418-
})};`
419-
)
414+
let env = `import.meta.env = ${JSON.stringify({
415+
...config.env,
416+
SSR: !!ssr
417+
})};`
418+
// account for user env defines
419+
for (const key in config.define) {
420+
if (key.startsWith(`import.meta.env.`)) {
421+
const val = config.define[key]
422+
env += `${key} = ${
423+
typeof val === 'string' ? val : JSON.stringify(val)
424+
};`
425+
}
426+
}
427+
str().prepend(env)
420428
}
421429

422430
if (hasHMR && !ssr) {

0 commit comments

Comments
 (0)