diff --git a/packages/next-env/index.ts b/packages/next-env/index.ts index 392670c7817e2b..5355b34d112012 100644 --- a/packages/next-env/index.ts +++ b/packages/next-env/index.ts @@ -16,6 +16,7 @@ let combinedEnv: Env | undefined = undefined let parsedEnv: Env | undefined = undefined let cachedLoadedEnvFiles: LoadedEnvFiles = [] let previousLoadedEnvFiles: LoadedEnvFiles = [] +let lastEnvConfigDir: string | undefined = undefined export function updateInitialEnv(newEnv: Env) { Object.assign(initialEnv || {}, newEnv) @@ -122,16 +123,20 @@ export function loadEnvConfig( parsedEnv: Env | undefined loadedEnvFiles: LoadedEnvFiles } { + const resolvedDir = path.resolve(dir) + if (!initialEnv) { initialEnv = Object.assign({}, process.env) } // only reload env when forceReload is specified - if (combinedEnv && !forceReload) { + if (combinedEnv && !forceReload && lastEnvConfigDir === resolvedDir) { return { combinedEnv, parsedEnv, loadedEnvFiles: cachedLoadedEnvFiles } } replaceProcessEnv(initialEnv) - previousLoadedEnvFiles = cachedLoadedEnvFiles + previousLoadedEnvFiles = + lastEnvConfigDir === resolvedDir ? cachedLoadedEnvFiles : [] cachedLoadedEnvFiles = [] + lastEnvConfigDir = resolvedDir const isTest = process.env.NODE_ENV === 'test' const mode = isTest ? 'test' : dev ? 'development' : 'production' diff --git a/test/unit/preserve-process-env.test.ts b/test/unit/preserve-process-env.test.ts index cbddc233040e7e..38b0c4360a630d 100644 --- a/test/unit/preserve-process-env.test.ts +++ b/test/unit/preserve-process-env.test.ts @@ -1,6 +1,44 @@ -import { loadEnvConfig } from '../../packages/next-env/' +import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'fs' +import { tmpdir } from 'os' +import { join } from 'path' +import { loadEnvConfig, resetEnv } from '../../packages/next-env/' describe('preserve process env', () => { + let tempDir: string | undefined + + afterEach(() => { + resetEnv() + delete process.env.__NEXT_PROCESSED_ENV + + if (tempDir) { + rmSync(tempDir, { force: true, recursive: true }) + tempDir = undefined + } + }) + + it('should reload env files when dir changes without forceReload', () => { + tempDir = mkdtempSync(join(tmpdir(), 'next-env-config-')) + + const firstDir = join(tempDir, 'app-a') + const secondDir = join(tempDir, 'app-b') + + mkdirSync(firstDir, { recursive: true }) + mkdirSync(secondDir, { recursive: true }) + + writeFileSync(join(firstDir, '.env'), 'FROM_APP=app-a\nSHARED=first\n') + writeFileSync(join(secondDir, '.env'), 'FROM_APP=app-b\nSHARED=second\n') + + const first = loadEnvConfig(firstDir) + const second = loadEnvConfig(secondDir) + + expect(first.parsedEnv).toEqual({ FROM_APP: 'app-a', SHARED: 'first' }) + expect(second.parsedEnv).toEqual({ FROM_APP: 'app-b', SHARED: 'second' }) + expect(second.loadedEnvFiles).toHaveLength(1) + expect(second.loadedEnvFiles[0].contents).toContain('FROM_APP=app-b') + expect(process.env.FROM_APP).toBe('app-b') + expect(process.env.SHARED).toBe('second') + }) + it('should not reassign `process.env`', () => { const originalProcessEnv = process.env loadEnvConfig('.')