Skip to content

Conversation

@toto6038
Copy link
Contributor

Description

This PR introduces support for loading environment variables via a file, specifically --env-file and --env-prefix command line flags and corresponding config options.

dotenv is used to parse env file, and variables are filtered by prefix (default is TSDOWN_) to prevent accidental exposure of sensitive information.

Regarding variable priority, explicit CLI arguments take precedence. Specifically, if a user defines a variable using both the --env.* flag and within an --env-file simultaneously, the value provided via the --env.* flag will override the one in the file.

Linked Issues

Resolves #652

Additional context

Note on Node.js Conflict: Since Node.js v20.6.0, the runtime includes a native --env-file flag. If a user provides an invalid path or forgets to use the -- separator between Node and tsdown arguments, Node.js may intercept the flag and throw an error before tsdown even executes.

@netlify
Copy link

netlify bot commented Dec 22, 2025

Deploy Preview for tsdown ready!

Name Link
🔨 Latest commit 3e4ad28
🔍 Latest deploy log https://app.netlify.com/projects/tsdown/deploys/694bec164a1fca0008b95216
😎 Deploy Preview https://deploy-preview-664--tsdown.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 22, 2025

Open in StackBlitz

npm i https://pkg.pr.new/tsdown@664
npm i https://pkg.pr.new/create-tsdown@664
npm i https://pkg.pr.new/tsdown-migrate@664

commit: 3e4ad28

@toto6038 toto6038 marked this pull request as draft December 22, 2025 03:57
@toto6038 toto6038 marked this pull request as ready for review December 22, 2025 05:17
Copy link
Member

@sxzz sxzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use process.loadEnvFile instead of dotenv.

@toto6038
Copy link
Contributor Author

Use process.loadEnvFile instead of dotenv.

The main reason for using dotenv over process.loadEnvFile is that the built-in Node.js method does not return the parsed results; it directly mutates process.env.

This makes it impossible to distinguish between variables specifically defined in the file and those already present in the system environment. For example, if a user runs TSDOWN_FOO=bar tsdown --env-file .env, and the .env file contains TSDOWN_BAR=baz, process.loadEnvFile would mix them both into process.env.

By using dotenv, we get an isolated object of just the file's contents. This allows us to precisely apply prefix filtering and handle precedence logic without accidentally picking up or re-processing system-level variables that shouldn't go through the resolution logic.

@toto6038 toto6038 requested a review from sxzz December 22, 2025 09:21
@sxzz
Copy link
Member

sxzz commented Dec 22, 2025

@toto6038 I found util.parseEnv is also available https://nodejs.org/api/util.html#utilparseenvcontent

}

if (envFile) {
// MARK: - handling envFile
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -1,7 +1,9 @@
import fs from 'node:fs'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import fs from 'node:fs'
import { readFile } from 'node:fs/promises'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

})
}

function loadEnvFile(filePath: string, envPrefixes: string[], logger: Logger) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function loadEnvFile(filePath: string, envPrefixes: string[], logger: Logger) {
function loadEnv(filePath: string, envPrefixes: string[], logger: Logger) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also read values from existing process.env

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to read all variables from process.env, we could stick to process.env.loadEnvFile as we don't need to distinguish the variables specified in env file anymore.

Copy link
Member

@sxzz sxzz Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, { ...parsedFromEnvFile (with prefixed), ...currentProcessEnv (with prefixed), ...envsFromTsdownOptions }

Copy link
Contributor Author

@toto6038 toto6038 Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to confirm the intended behavior of the following:

  • Is loading process.env with prefix filtering exclusive to when envFile is provided?
  • Should the override precedence be --env > env file > process.env?

Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intended behaviors:

  • Always load process.env
  • Environment variables from env file and process.env should be filtered with prefix.
  • precedence
    • env option (aka CLI --env, optional, highest priority)
    • process.env (always load)
    • env file (aka CLI --env-file, optional)

@toto6038 toto6038 requested a review from sxzz December 23, 2025 11:11
@toto6038
Copy link
Contributor Author

I have reworked the merging and filtering logic of environment variables. If things look good, I can proceed to elaborate this in documentation.

@sxzz sxzz enabled auto-merge (squash) December 24, 2025 13:37
@sxzz sxzz merged commit d549334 into rolldown:main Dec 24, 2025
15 of 16 checks passed
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 this pull request may close these issues.

Add Support for Reading Environment Variables from .env Files

2 participants