Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Add dryRun option to parse env files without modifying process.env #4638

Closed
curlykay opened this issue Feb 23, 2025 · 4 comments · Fixed by #4645
Closed

[Feature]: Add dryRun option to parse env files without modifying process.env #4638

curlykay opened this issue Feb 23, 2025 · 4 comments · Fixed by #4645
Assignees

Comments

@curlykay
Copy link

What problem does this feature solve?

Description
Currently, loadEnv() merges environment variables from .env,.env[.local] .env[.mode], and .env[.mode[.local]] files into process.env. While useful for build processes, this causes environment pollution when using custom CLI tools outside rsbuild's build/dev flows.

The current loadEnv() + cleanup() pattern has limitations when environment variables already exist before loading:

  1. cleanup simply deletes injected variables rather than restoring original values
  2. Pre-existing values get permanently erased when using this pattern

Proposal
Add a dryRun boolean option to loadEnv(). When enabled:

  1. Files are still loaded/merged using existing priority rules
  2. Parsed values are returned in the parsed field
  3. No modifications are made to process.env

(Note: loadEnv() May need a separate processEnv configuration for advanced environment injection control,like:https://dotenvx.com/docs/advanced/parse-process-env)

What does the proposed API look like?

Use Case
Creating custom CLI tools that need env values without side effects:

# .env
HELLO=WORLD
import { loadEnv } from '@rsbuild/core';

// In custom CLI script
const { parsed } = loadEnv({
  dryRun: true, // Prevent env injection
  mode: 'production'
});

console.log(parsed.HELLO); //   WORLD   Value from .env files
console.log(process.env.HELLO); // undefined (no pollution)

Behavior Comparison

Option Returns parsed Modifies process.env
dryRun:true
Default

Implementation Notes

  1. Should maintain full compatibility with existing API
  2. Should preserve existing environment variable merging logic
  3. Documentation update needed for new option
@chenjiahan
Copy link
Member

I prefer to add a new processEnv option instead if adding the dryRun option:

// copied from `dotenv-expand`
export interface DotenvExpandOptions {
  /**
   * Default: `process.env`
   *
   * Specify an object to write your secrets to. Defaults to process.env environment variables.
   *
   * example: `const processEnv = {}; require('dotenv').config({ processEnv: processEnv })`
   */
  processEnv?: DotenvPopulateInput;
}

When the user needs to dry run, just pass an empty object in processEnv option:

loadEnv({ processEnv: {} }); 

@curlykay
Copy link
Author

curlykay commented Feb 24, 2025

Yes, I revisited it, and providing the processEnv configuration would then be able to cover the dryRun and advanced environment injection control usage scenarios.

// default: use real environment variables
loadEnv({ processEnv: process.env }); 

// dryRun: mock cloned environment (isolated from real process.env)
loadEnv({ processEnv: {...process.env}}); 

// dryRun: empty environment (no variables)
loadEnv({ processEnv: {} }); 

Providing processEnv configurations is indeed a much better approach, thanks for the exchange

@curlykay
Copy link
Author

Do you plan to add a processEnv option to loadEnv?

@chenjiahan
Copy link
Member

Yes I will

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants