From ace6c2016490e41c3c891b35b6e0cf5f4bb2cf3a Mon Sep 17 00:00:00 2001 From: Harryson <168550932+HarrysonLadines@users.noreply.github.com> Date: Wed, 18 Mar 2026 12:04:45 -0300 Subject: [PATCH] feat: replace `dotenv` with native `node:util` `parseEnv` (#2181) Co-authored-by: Aaron --- packages/wxt/package.json | 1 - packages/wxt/src/core/utils/env.ts | 52 +++++++++++++++++++++--------- pnpm-lock.yaml | 3 -- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/packages/wxt/package.json b/packages/wxt/package.json index 9ae1c4f4..38b4d0ca 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -30,7 +30,6 @@ "ci-info": "^4.4.0", "consola": "^3.4.2", "defu": "^6.1.4", - "dotenv": "^17.3.1", "dotenv-expand": "^12.0.3", "esbuild": "^0.27.1", "filesize": "^11.0.13", diff --git a/packages/wxt/src/core/utils/env.ts b/packages/wxt/src/core/utils/env.ts index 8a586b35..38871ca5 100644 --- a/packages/wxt/src/core/utils/env.ts +++ b/packages/wxt/src/core/utils/env.ts @@ -1,23 +1,45 @@ -import { config } from 'dotenv'; +import { readFileSync, existsSync } from 'node:fs'; +import { parseEnv } from 'node:util'; import { expand } from 'dotenv-expand'; import type { TargetBrowser } from '../../types'; /** Load environment files based on the current mode and browser. */ export function loadEnv(mode: string, browser: TargetBrowser) { - return expand( - config({ - quiet: true, - // Files on top override files below - path: [ - `.env.${mode}.${browser}.local`, - `.env.${mode}.${browser}`, - `.env.${browser}.local`, - `.env.${browser}`, - `.env.${mode}.local`, - `.env.${mode}`, - `.env.local`, - `.env`, - ], + const envFiles = [ + // List is ordered with general files first, specific ones last, so the more + // specific files override the more general ones in the loop below. + `.env`, + `.env.local`, + `.env.${mode}`, + `.env.${mode}.local`, + `.env.${browser}`, + `.env.${browser}.local`, + `.env.${mode}.${browser}`, + `.env.${mode}.${browser}.local`, + ]; + + const parsed = Object.fromEntries( + envFiles.flatMap((filePath) => { + if (!existsSync(filePath)) return []; + + try { + const content = readFileSync(filePath, 'utf-8'); + const parsedEnv = parseEnv(content); + return Object.entries(parsedEnv) as [string, string][]; + } catch { + return []; + } }), ); + + // Make a copy of `process.env` so that `dotenv-expand` doesn't re-assign the + // expanded values to the global `process.env`. + const processEnv = { ...process.env } as Record; + + expand({ + parsed, + processEnv, + }); + + return parsed; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2df5f796..ac1d436d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -456,9 +456,6 @@ importers: defu: specifier: ^6.1.4 version: 6.1.4 - dotenv: - specifier: ^17.3.1 - version: 17.3.1 dotenv-expand: specifier: ^12.0.3 version: 12.0.3