Skip to content

Commit 8b8e29a

Browse files
committed
process.env respect .env file, but @env can grab from anything
1 parent 9bdac1b commit 8b8e29a

4 files changed

Lines changed: 29 additions & 25 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
### Fixed
66

7-
- `process.env.X` is only inlined when `X` comes from a `.env` file (or `NODE_ENV` / `BABEL_ENV` / `envName`). Host/build tooling vars like `JEST_WORKER_ID` no longer leak into the app bundle ([#574](https://github.com/dotenvx/react-native-dotenv/issues/574)).
7+
- `process.env.X` is only inlined when `X` is defined in a `.env` file (plus `NODE_ENV` / `BABEL_ENV` / `envName`). Stops build-tooling leaks into the bundle without hardcoding tool-specific names. Host/CI-only values still work through `@env` imports ([#574](https://github.com/dotenvx/react-native-dotenv/issues/574)).
88

99
### Removed
1010

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,7 @@ Prevent these env variable names from being imported.
164164
</details>
165165
<details><summary><code>safe</code> (default: <code>false</code>)</summary><br>
166166

167-
Only allow environment variables defined in the `.env` file. This completely ignores everything already defined in the environment.
168-
169-
The `.env` file has to exist.
167+
Only allow variables defined in your `.env` files. Host environment variables can still override values for those same keys at build time, but keys that exist only in the environment (and not in `.env`) are not imported.
170168

171169
```json
172170
{
@@ -228,7 +226,9 @@ console.log(`Hello ${process.env.HELLO}`)
228226
fetch(`${process.env.API_URL}/users`)
229227
```
230228

231-
Only keys present in your `.env` files are inlined (plus `NODE_ENV` / `BABEL_ENV` / `envName`). Other host environment variables — including build-tooling vars like `JEST_WORKER_ID` — are left alone so they do not leak into the app bundle.
229+
`process.env.X` is only inlined when `X` is in your `.env` files (plus `NODE_ENV` / `BABEL_ENV` / `envName`). That keeps build-tooling noise out of the bundle without special-casing tool names.
230+
231+
For host/CI-only values, use `@env` imports — or put the key in `.env` and let CI override the value.
232232

233233
</details>
234234
<details><summary>Expo</summary><br>
@@ -492,8 +492,9 @@ Prefer [Zod](https://zod.dev) to validate and infer types — see Types with Zod
492492

493493
By default, we will never modify any environment variables that have already been set. In particular, if there is a variable in your `.env` file which collides with one that already exists in your environment, then that variable will be skipped (the existing value wins at build time).
494494

495-
</details>
495+
`process.env.X` is only inlined when `X` appears in a `.env` file. Host/CI-only keys still work via `import { X } from '@env'`.
496496

497+
</details>
497498
&nbsp;
498499

499500
## CHANGELOG

index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ module.exports = (api, options) => {
9494
const modeExceptions = ['NODE_ENV', 'BABEL_ENV', options.envName]
9595
const fileEnv = undefObjectAssign(undefObjectAssign(undefObjectAssign(parsed, modeParsed), localParsed), modeLocalParsed)
9696

97-
// Keys that may be inlined for process.env.X only what came from .env files,
98-
// plus mode-selection exceptions. Prevents host/build tooling vars (e.g.
99-
// JEST_WORKER_ID from Metro's jest-worker) from leaking into the app bundle.
100-
const inlineKeys = new Set(Object.keys(fileEnv))
97+
// process.env.X is only inlined for keys from .env files (+ mode exceptions).
98+
// That stops build-tooling pollution (e.g. Metro jest-worker) without hardcoding
99+
// tool-specific names. Host/CI values still flow through @env imports below.
100+
const processEnvInlineKeys = new Set(Object.keys(fileEnv))
101101
for (const exception of modeExceptions) {
102-
inlineKeys.add(exception)
102+
processEnvInlineKeys.add(exception)
103103
}
104104

105105
env = (options.safe)
@@ -161,7 +161,7 @@ module.exports = (api, options) => {
161161
const key = filepath.toComputedKey()
162162
if (t.isStringLiteral(key)) {
163163
const importedId = key.value
164-
if (!inlineKeys.has(importedId)) {
164+
if (!processEnvInlineKeys.has(importedId)) {
165165
return
166166
}
167167
const value = Object.hasOwn(env, importedId) ? env[importedId] : process.env[importedId]

tests/index.test.js

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -175,29 +175,32 @@ describe('react-native-dotenv', () => {
175175
expect(code).toBe('console.log("abc123456");\nconsole.log("username123456");')
176176
})
177177

178-
// #574 — Metro/jest-worker sets JEST_WORKER_ID on transform workers. Only keys
179-
// from .env files (plus NODE_ENV/BABEL_ENV/envName) may be inlined for process.env.X.
180-
it('should not inline host-only process.env vars like JEST_WORKER_ID', () => {
178+
// #574 — process.env.X only inlines keys from .env (no host-only / tooling leaks).
179+
it('should not inline process.env keys that are absent from .env', () => {
181180
process.env.JEST_WORKER_ID = '123'
181+
process.env.MY_CI_VAR = 'from-ci'
182182

183-
const { code } = transformSync('console.log(process.env.JEST_WORKER_ID)', {
184-
configFile: false,
185-
babelrc: false,
186-
plugins: [[require('../index.js'), { path: FIXTURES + 'default/.env' }]]
187-
})
183+
const { code } = transformSync(
184+
'console.log(process.env.JEST_WORKER_ID);\nconsole.log(process.env.MY_CI_VAR);',
185+
{
186+
configFile: false,
187+
babelrc: false,
188+
plugins: [[require('../index.js'), { path: FIXTURES + 'default/.env' }]]
189+
}
190+
)
188191

189-
expect(code).toBe('console.log(process.env.JEST_WORKER_ID);')
192+
expect(code).toBe('console.log(process.env.JEST_WORKER_ID);\nconsole.log(process.env.MY_CI_VAR);')
190193
})
191194

192-
it('should still inline process.env keys that are defined in .env', () => {
193-
process.env.JEST_WORKER_ID = 'from-host'
195+
it('should still allow @env imports from host/CI without the key in .env', () => {
196+
process.env.MY_CI_VAR = 'from-ci'
194197

195-
const { code } = transformSync('console.log(process.env.API_KEY)', {
198+
const { code } = transformSync('import { MY_CI_VAR } from "@env";\nconsole.log(MY_CI_VAR);', {
196199
configFile: false,
197200
babelrc: false,
198201
plugins: [[require('../index.js'), { path: FIXTURES + 'default/.env' }]]
199202
})
200203

201-
expect(code).toBe('console.log("abc123");')
204+
expect(code).toBe('console.log("from-ci");')
202205
})
203206
})

0 commit comments

Comments
 (0)