Skip to content

Commit 3f5f2bd

Browse files
authored
fix: allow expanding env vars in reverse order (#19352)
1 parent 2b2299c commit 3f5f2bd

File tree

7 files changed

+70
-5
lines changed

7 files changed

+70
-5
lines changed

docs/guide/env-and-mode.md

+17
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,23 @@ If you want to customize the env variables prefix, see the [envPrefix](/config/s
7777
- Since any variables exposed to your Vite source code will end up in your client bundle, `VITE_*` variables should _not_ contain any sensitive information.
7878
:::
7979
80+
::: details Expanding variables in reverse order
81+
82+
Vite supports expanding variables in reverse order.
83+
For example, the `.env` below will be evaluated as `VITE_FOO=foobar`, `VITE_BAR=bar`.
84+
85+
```[.env]
86+
VITE_FOO=foo${VITE_BAR}
87+
VITE_BAR=bar
88+
```
89+
90+
This does not work in shell scripts and other tools like `docker-compose`.
91+
That said, Vite supports this behavior as this has been supported by `dotenv-expand` for a long time and other tools in JavaScript ecosystem uses older versions that supports this behavior.
92+
93+
To avoid interop issues, it is recommended to avoid relying on this behavior. Vite may start emitting warnings for this behavior in the future.
94+
95+
:::
96+
8097
### IntelliSense for TypeScript
8198
8299
By default, Vite provides type definitions for `import.meta.env` in [`vite/client.d.ts`](https://github.com/vitejs/vite/blob/main/packages/vite/client.d.ts). While you can define more custom env variables in `.env.[mode]` files, you may want to get TypeScript IntelliSense for user-defined env variables that are prefixed with `VITE_`.

docs/guide/migration.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ There are other breaking changes which only affect few users.
9999
- This PR not only introduces a breaking change mentioned above as "Default value for `resolve.conditions`", but also makes `resolve.mainFields` to not be used for no-externalized dependencies in SSR. If you were using `resolve.mainFields` and want to apply that to no-externalized dependencies in SSR, you can use [`ssr.resolve.mainFields`](/config/ssr-options#ssr-resolve-mainfields).
100100
- [[#18493] refactor!: remove fs.cachedChecks option](https://github.com/vitejs/vite/pull/18493)
101101
- This opt-in optimization was removed due to edge cases when writing a file in a cached folder and immediately importing it.
102-
- [[#18697] fix(deps)!: update dependency dotenv-expand to v12](https://github.com/vitejs/vite/pull/18697)
103-
- Variables used in interpolation should be declared before the interpolation now. For more details, see [the `dotenv-expand` changelog](https://github.com/motdotla/dotenv-expand/blob/v12.0.1/CHANGELOG.md#1200-2024-11-16).
102+
- ~~[[#18697] fix(deps)!: update dependency dotenv-expand to v12](https://github.com/vitejs/vite/pull/18697)~~
103+
- ~~Variables used in interpolation should be declared before the interpolation now. For more details, see [the `dotenv-expand` changelog](https://github.com/motdotla/dotenv-expand/blob/v12.0.1/CHANGELOG.md#1200-2024-11-16).~~ This breaking change was reverted in v6.1.0.
104104
- [[#16471] feat: v6 - Environment API](https://github.com/vitejs/vite/pull/16471)
105105

106106
- Updates to an SSR-only module no longer triggers a full page reload in the client. To return to the previous behaviour, a custom Vite plugin can be used:

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@
103103
"patchedDependencies": {
104104
105105
106-
106+
107+
107108
},
108109
"peerDependencyRules": {
109110
"allowedVersions": {

packages/vite/src/node/__tests__/env.spec.ts

+11
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ describe('loadEnv', () => {
3939
`)
4040
})
4141

42+
test('override 2', () => {
43+
expect(loadEnv('development2', join(__dirname, './env')))
44+
.toMatchInlineSnapshot(`
45+
{
46+
"VITE_APP_BASE_ROUTE": "source",
47+
"VITE_APP_BASE_URL": "source",
48+
"VITE_SOURCE": "source",
49+
}
50+
`)
51+
})
52+
4253
test('VITE_USER_NODE_ENV', () => {
4354
loadEnv('development', join(__dirname, './env'))
4455
expect(process.env.VITE_USER_NODE_ENV).toEqual(undefined)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
VITE_SOURCE=source
2+
VITE_APP_BASE_ROUTE=$VITE_SOURCE

patches/[email protected]

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
diff --git a/lib/main.js b/lib/main.js
2+
index 794f3bf512ee8cd24fe20e83d159bf8682fb901e..5567e6e282d65b87deea02f8cb396d3e7276581e 100644
3+
--- a/lib/main.js
4+
+++ b/lib/main.js
5+
@@ -64,7 +64,7 @@ function expandValue (value, processEnv, runningParsed) {
6+
7+
function expand (options) {
8+
// for use with progressive expansion
9+
- const runningParsed = {}
10+
+ // const runningParsed = {}
11+
12+
let processEnv = process.env
13+
if (options && options.processEnv != null) {
14+
@@ -79,13 +79,15 @@ function expand (options) {
15+
if (processEnv[key] && processEnv[key] !== value) {
16+
value = processEnv[key]
17+
} else {
18+
- value = expandValue(value, processEnv, runningParsed)
19+
+ // PATCH: we pass options.parsed instead of runningParsed
20+
+ // to allow variables declared in other files to be used
21+
+ value = expandValue(value, processEnv, options.parsed)
22+
}
23+
24+
options.parsed[key] = _resolveEscapeSequences(value)
25+
26+
// for use with progressive expansion
27+
- runningParsed[key] = _resolveEscapeSequences(value)
28+
+ // runningParsed[key] = _resolveEscapeSequences(value)
29+
}
30+
31+
for (const processKey in options.parsed) {

pnpm-lock.yaml

+5-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)