Skip to content

Commit

Permalink
fix(build): avoid re-define __vite_import_meta_env__ (#17876)
Browse files Browse the repository at this point in the history
Co-authored-by: bluwy <bjornlu.dev@gmail.com>
  • Loading branch information
yuzheng14 and bluwy committed Aug 15, 2024
1 parent 1b3b702 commit e686d74
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 17 deletions.
27 changes: 27 additions & 0 deletions packages/vite/src/node/__tests__/plugins/define.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,31 @@ describe('definePlugin', () => {
/const __vite_import_meta_env__ = .*;\nconst env = __vite_import_meta_env__;/,
)
})

test('already has marker', async () => {
const transform = await createDefinePluginTransform()
expect(
await transform(
'console.log(__vite_import_meta_env__);\nconst env = import.meta.env;',
),
).toMatch(
/const __vite_import_meta_env__1 = .*;\nconsole.log\(__vite_import_meta_env__\);\nconst env = __vite_import_meta_env__1;/,
)

expect(
await transform(
'console.log(__vite_import_meta_env__, __vite_import_meta_env__1);\n const env = import.meta.env;',
),
).toMatch(
/const __vite_import_meta_env__2 = .*;\nconsole.log\(__vite_import_meta_env__, __vite_import_meta_env__1\);\nconst env = __vite_import_meta_env__2;/,
)

expect(
await transform(
'console.log(__vite_import_meta_env__);\nconst env = import.meta.env;\nconsole.log(import.meta.env.UNDEFINED);',
),
).toMatch(
/const __vite_import_meta_env__1 = .*;\nconsole.log\(__vite_import_meta_env__\);\nconst env = __vite_import_meta_env__1;\nconsole.log\(undefined {26}\);/,
)
})
})
62 changes: 45 additions & 17 deletions packages/vite/src/node/plugins/define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { isHTMLRequest } from './html'
const nonJsRe = /\.json(?:$|\?)/
const isNonJsRequest = (request: string): boolean => nonJsRe.test(request)
const importMetaEnvMarker = '__vite_import_meta_env__'
const bareImportMetaEnvRe = new RegExp(`${importMetaEnvMarker}(?!\\.)\\b`)
const importMetaEnvKeyRe = new RegExp(`${importMetaEnvMarker}\\..+?\\b`, 'g')
const importMetaEnvKeyReCache = new Map<string, RegExp>()

export function definePlugin(config: ResolvedConfig): Plugin {
const isBuild = config.command === 'build'
Expand Down Expand Up @@ -80,7 +79,6 @@ export function definePlugin(config: ResolvedConfig): Plugin {
SSR: ssr + '',
...userDefineEnv,
})
const banner = `const ${importMetaEnvMarker} = ${importMetaEnvVal};\n`

// Create regex pattern as a fast check before running esbuild
const patternKeys = Object.keys(userDefine)
Expand All @@ -94,7 +92,7 @@ export function definePlugin(config: ResolvedConfig): Plugin {
? new RegExp(patternKeys.map(escapeRegex).join('|'))
: null

return [define, pattern, banner] as const
return [define, pattern, importMetaEnvVal] as const
}

const defaultPattern = generatePattern(false)
Expand Down Expand Up @@ -122,28 +120,49 @@ export function definePlugin(config: ResolvedConfig): Plugin {
return
}

const [define, pattern, banner] = ssr ? ssrPattern : defaultPattern
let [define, pattern, importMetaEnvVal] = ssr
? ssrPattern
: defaultPattern
if (!pattern) return

// Check if our code needs any replacements before running esbuild
pattern.lastIndex = 0
if (!pattern.test(code)) return

const result = await replaceDefine(code, id, define, config)
const hasDefineImportMetaEnv = 'import.meta.env' in define
let marker = importMetaEnvMarker

// Replace `import.meta.env.*` with undefined
result.code = result.code.replaceAll(importMetaEnvKeyRe, (m) =>
'undefined'.padEnd(m.length),
)
if (hasDefineImportMetaEnv && code.includes(marker)) {
// append a number to the marker until it's unique, to avoid if there is a
// marker already in the code
let i = 1
do {
marker = importMetaEnvMarker + i++
} while (code.includes(marker))

// If there's bare `import.meta.env` references, prepend the banner
if (bareImportMetaEnvRe.test(result.code)) {
result.code = banner + result.code
if (marker !== importMetaEnvMarker) {
define = { ...define, 'import.meta.env': marker }
}
}

if (result.map) {
const map = JSON.parse(result.map)
map.mappings = ';' + map.mappings
result.map = map
const result = await replaceDefine(code, id, define, config)

if (hasDefineImportMetaEnv) {
// Replace `import.meta.env.*` with undefined
result.code = result.code.replaceAll(
getImportMetaEnvKeyRe(marker),
(m) => 'undefined'.padEnd(m.length),
)

// If there's bare `import.meta.env` references, prepend the banner
if (result.code.includes(marker)) {
result.code = `const ${marker} = ${importMetaEnvVal};\n` + result.code

if (result.map) {
const map = JSON.parse(result.map)
map.mappings = ';' + map.mappings
result.map = map
}
}
}

Expand Down Expand Up @@ -219,3 +238,12 @@ function handleDefineValue(value: any): string {
if (typeof value === 'string') return value
return JSON.stringify(value)
}

function getImportMetaEnvKeyRe(marker: string): RegExp {
let re = importMetaEnvKeyReCache.get(marker)
if (!re) {
re = new RegExp(`${marker}\\..+?\\b`, 'g')
importMetaEnvKeyReCache.set(marker, re)
}
return re
}

0 comments on commit e686d74

Please sign in to comment.