Skip to content

Commit 908c9e4

Browse files
authored
feat: preserve process env vars in lib build (#8090)
1 parent e2e44ff commit 908c9e4

File tree

4 files changed

+47
-37
lines changed

4 files changed

+47
-37
lines changed

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

+22-22
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,23 @@ const isNonJsRequest = (request: string): boolean => nonJsRe.test(request)
1010

1111
export function definePlugin(config: ResolvedConfig): Plugin {
1212
const isBuild = config.command === 'build'
13-
14-
const processNodeEnv: Record<string, string> = {
15-
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || config.mode),
16-
'global.process.env.NODE_ENV': JSON.stringify(
17-
process.env.NODE_ENV || config.mode
18-
),
19-
'globalThis.process.env.NODE_ENV': JSON.stringify(
20-
process.env.NODE_ENV || config.mode
21-
)
13+
const isBuildLib = isBuild && config.build.lib
14+
15+
// ignore replace process.env in lib build
16+
const processEnv: Record<string, string> = {}
17+
const processNodeEnv: Record<string, string> = {}
18+
if (!isBuildLib) {
19+
const nodeEnv = process.env.NODE_ENV || config.mode
20+
Object.assign(processEnv, {
21+
'process.env.': `({}).`,
22+
'global.process.env.': `({}).`,
23+
'globalThis.process.env.': `({}).`
24+
})
25+
Object.assign(processNodeEnv, {
26+
'process.env.NODE_ENV': JSON.stringify(nodeEnv),
27+
'global.process.env.NODE_ENV': JSON.stringify(nodeEnv),
28+
'globalThis.process.env.NODE_ENV': JSON.stringify(nodeEnv)
29+
})
2230
}
2331

2432
const userDefine: Record<string, string> = {}
@@ -27,7 +35,8 @@ export function definePlugin(config: ResolvedConfig): Plugin {
2735
userDefine[key] = typeof val === 'string' ? val : JSON.stringify(val)
2836
}
2937

30-
// during dev, import.meta properties are handled by importAnalysis plugin
38+
// during dev, import.meta properties are handled by importAnalysis plugin.
39+
// ignore replace import.meta.env in lib build
3140
const importMetaKeys: Record<string, string> = {}
3241
if (isBuild) {
3342
const env: Record<string, any> = {
@@ -47,22 +56,13 @@ export function definePlugin(config: ResolvedConfig): Plugin {
4756
function generatePattern(
4857
ssr: boolean
4958
): [Record<string, string | undefined>, RegExp | null] {
50-
const processEnv: Record<string, string> = {}
51-
const isNeedProcessEnv = !ssr || config.ssr?.target === 'webworker'
52-
53-
if (isNeedProcessEnv) {
54-
Object.assign(processEnv, {
55-
'process.env.': `({}).`,
56-
'global.process.env.': `({}).`,
57-
'globalThis.process.env.': `({}).`
58-
})
59-
}
59+
const replaceProcessEnv = !ssr || config.ssr?.target === 'webworker'
6060

6161
const replacements: Record<string, string> = {
62-
...(isNeedProcessEnv ? processNodeEnv : {}),
62+
...(replaceProcessEnv ? processNodeEnv : {}),
6363
...userDefine,
6464
...importMetaKeys,
65-
...processEnv
65+
...(replaceProcessEnv ? processEnv : {})
6666
}
6767

6868
const replacementsKeys = Object.keys(replacements)

playground/lib/__tests__/lib.spec.ts

+13-15
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import path from 'path'
2-
import fs from 'fs'
31
import {
42
isBuild,
53
isServe,
64
page,
5+
readFile,
76
serverLogs,
8-
testDir,
97
untilUpdated
108
} from '~utils'
119

@@ -16,20 +14,14 @@ describe.runIf(isBuild)('build', () => {
1614

1715
test('umd', async () => {
1816
expect(await page.textContent('.umd')).toBe('It works')
19-
const code = fs.readFileSync(
20-
path.join(testDir, 'dist/my-lib-custom-filename.umd.js'),
21-
'utf-8'
22-
)
17+
const code = readFile('dist/my-lib-custom-filename.umd.js')
2318
// esbuild helpers are injected inside of the UMD wrapper
2419
expect(code).toMatch(/^\(function\(/)
2520
})
2621

2722
test('iife', async () => {
2823
expect(await page.textContent('.iife')).toBe('It works')
29-
const code = fs.readFileSync(
30-
path.join(testDir, 'dist/my-lib-custom-filename.iife.js'),
31-
'utf-8'
32-
)
24+
const code = readFile('dist/my-lib-custom-filename.iife.js')
3325
// esbuild helpers are injected inside of the IIFE wrapper
3426
expect(code).toMatch(/^const MyLib=function\(\){"use strict";/)
3527
})
@@ -39,10 +31,7 @@ describe.runIf(isBuild)('build', () => {
3931
() => page.textContent('.dynamic-import-message'),
4032
'hello vite'
4133
)
42-
const code = fs.readFileSync(
43-
path.join(testDir, 'dist/lib/dynamic-import-message.es.mjs'),
44-
'utf-8'
45-
)
34+
const code = readFile('dist/lib/dynamic-import-message.es.mjs')
4635
expect(code).not.toMatch('__vitePreload')
4736

4837
// Test that library chunks are hashed
@@ -55,6 +44,15 @@ describe.runIf(isBuild)('build', () => {
5544
expect(log).not.toMatch('All "@import" rules must come first')
5645
})
5746
})
47+
48+
test('preserve process.env', () => {
49+
const es = readFile('dist/my-lib-custom-filename.mjs')
50+
const iife = readFile('dist/my-lib-custom-filename.iife.js')
51+
const umd = readFile('dist/my-lib-custom-filename.umd.js')
52+
expect(es).toMatch('process.env.NODE_ENV')
53+
expect(iife).toMatch('process.env.NODE_ENV')
54+
expect(umd).toMatch('process.env.NODE_ENV')
55+
})
5856
})
5957

6058
test.runIf(isServe)('dev', async () => {

playground/lib/index.dist.html

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
<div class="iife"></div>
55
<div class="dynamic-import-message"></div>
66

7+
<script>
8+
// shim test preserve process.env.NODE_ENV
9+
globalThis.process = {
10+
env: {
11+
NODE_ENV: 'production'
12+
}
13+
}
14+
</script>
15+
716
<script type="module">
817
import myLib from './my-lib-custom-filename.mjs'
918

playground/lib/src/main.js

+3
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@ export default function myLib(sel) {
33
console.log({ ...'foo' })
44

55
document.querySelector(sel).textContent = 'It works'
6+
7+
// Env vars should not be replaced
8+
console.log(process.env.NODE_ENV)
69
}

0 commit comments

Comments
 (0)