diff --git a/docs/react/guides/environment-variables.md b/docs/react/guides/environment-variables.md index f8f4460513..d3b27eefd7 100644 --- a/docs/react/guides/environment-variables.md +++ b/docs/react/guides/environment-variables.md @@ -41,20 +41,22 @@ set "NODE_ENV=development" && nx build myapp By default, Nx will load any environment variables you place in the following files: 1. `workspaceRoot/apps/my-app/.local.env` -2. `workspaceRoot/apps/my-app/.env` -3. `workspaceRoot/.local.env` -4. `workspaceRoot/.env` +2. `workspaceRoot/apps/my-app/.env.local` +3. `workspaceRoot/apps/my-app/.env` +4. `workspaceRoot/.local.env` +5. `workspaceRoot/.env.local` +6. `workspaceRoot/.env` Order is important. Nx will move through the above list, ignoring files it can't find, and loading environment variables into the current process for the ones it can find. If it finds a variable that has already been loaded into the process, it will ignore it. It does this for two reasons: 1. Developers can't accidentally overwrite important system level variables (like `NODE_ENV`) -2. Allows developers to create `.local.env` files for their local environment and override any project defaults set in `.env` +2. Allows developers to create `.env.local` or `.local.env` files for their local environment and override any project defaults set in `.env` For example: -1. `workspaceRoot/apps/my-app/.local.env` contains `AUTH_URL=http://localhost/auth` +1. `workspaceRoot/apps/my-app/.env.local` contains `AUTH_URL=http://localhost/auth` 2. `workspaceRoot/apps/my-app/.env` contains `AUTH_URL=https://prod-url.com/auth` -3. Nx will first load the variables from `apps/my-app/.local.env` into the process. When it tries to load the variables from `apps/my-app/.env`, it will notice that `AUTH_URL` already exists, so it will ignore it. +3. Nx will first load the variables from `apps/my-app/.env.local` into the process. When it tries to load the variables from `apps/my-app/.env`, it will notice that `AUTH_URL` already exists, so it will ignore it. We recommend nesting your **app** specific `env` files in `apps/your-app`, and creating workspace/root level `env` files for workspace-specific settings (like the [Nx Cloud token](/{{framework}}/core-concepts/computation-caching#nx-cloud-and-distributed-computation-memoization)). diff --git a/e2e/web/src/web.test.ts b/e2e/web/src/web.test.ts index 6813cba450..afb5f5f693 100644 --- a/e2e/web/src/web.test.ts +++ b/e2e/web/src/web.test.ts @@ -128,7 +128,7 @@ describe('Web Components Applications', () => { function sealed(target: any) { return target; } - + @sealed class Foo { @enumerable(false) bar() {} @@ -174,20 +174,40 @@ describe('CLI - Environment Variables', () => { `.env`, 'NX_WS_BASE=ws-base\nNX_SHARED_ENV=shared-in-workspace-base' ); + updateFile( + `.env.local`, + 'NX_WS_ENV_LOCAL=ws-env-local\nNX_SHARED_ENV=shared-in-workspace-env-local' + ); updateFile( `.local.env`, - 'NX_WS_LOCAL=ws-local\nNX_SHARED_ENV=shared-in-workspace-local' + 'NX_WS_LOCAL_ENV=ws-local-env\nNX_SHARED_ENV=shared-in-workspace-local-env' ); updateFile( `apps/${appName}/.env`, 'NX_APP_BASE=app-base\nNX_SHARED_ENV=shared-in-app-base' ); + updateFile( + `apps/${appName}/.env.local`, + 'NX_APP_ENV_LOCAL=app-env-local\nNX_SHARED_ENV=shared-in-app-env-local' + ); updateFile( `apps/${appName}/.local.env`, - 'NX_APP_LOCAL=app-local\nNX_SHARED_ENV=shared-in-app-local' + 'NX_APP_LOCAL_ENV=app-local-env\nNX_SHARED_ENV=shared-in-app-local-env' ); const main = `apps/${appName}/src/main.ts`; - const newCode = `const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_LOCAL, process.env.NX_APP_BASE, process.env.NX_APP_LOCAL, process.env.NX_SHARED_ENV];`; + const newCode = ` + const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_ENV_LOCAL, process.env.NX_WS_LOCAL_ENV, process.env.NX_APP_BASE, process.env.NX_APP_ENV_LOCAL, process.env.NX_APP_LOCAL_ENV, process.env.NX_SHARED_ENV]; + const nodeEnv = process.env.NODE_ENV; + const nxBuild = process.env.NX_BUILD; + const nxApi = process.env.NX_API; + const nxWsBase = process.env.NX_WS_BASE; + const nxWsEnvLocal = process.env.NX_WS_ENV_LOCAL; + const nxWsLocalEnv = process.env.NX_WS_LOCAL_ENV; + const nxAppBase = process.env.NX_APP_BASE; + const nxAppEnvLocal = process.env.NX_APP_ENV_LOCAL; + const nxAppLocalEnv = process.env.NX_APP_LOCAL_ENV; + const nxSharedEnv = process.env.NX_SHARED_ENV; + `; runCLI(`generate @nrwl/web:app ${appName} --no-interactive`); @@ -201,12 +221,16 @@ describe('CLI - Environment Variables', () => { `apps/${appName2}/.env`, 'NX_APP_BASE=app2-base\nNX_SHARED_ENV=shared2-in-app-base' ); + updateFile( + `apps/${appName2}/.env.local`, + 'NX_APP_ENV_LOCAL=app2-env-local\nNX_SHARED_ENV=shared2-in-app-env-local' + ); updateFile( `apps/${appName2}/.local.env`, - 'NX_APP_LOCAL=app2-local\nNX_SHARED_ENV=shared2-in-app-local' + 'NX_APP_LOCAL_ENV=app2-local-env\nNX_SHARED_ENV=shared2-in-app-local-env' ); const main2 = `apps/${appName2}/src/main.ts`; - const newCode2 = `const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_LOCAL, process.env.NX_APP_BASE, process.env.NX_APP_LOCAL, process.env.NX_SHARED_ENV];`; + const newCode2 = `const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_ENV_LOCAL, process.env.NX_WS_LOCAL_ENV, process.env.NX_APP_BASE, process.env.NX_APP_ENV_LOCAL, process.env.NX_APP_LOCAL_ENV, process.env.NX_SHARED_ENV];`; runCLI(`generate @nrwl/web:app ${appName2} --no-interactive`); @@ -223,10 +247,10 @@ describe('CLI - Environment Variables', () => { }, }); expect(readFile(`dist/apps/${appName}/main.js`)).toContain( - 'const envVars = ["test", "52", "QA", "ws-base", "ws-local", "app-base", "app-local", "shared-in-app-local"];' + 'const envVars = ["test", "52", "QA", "ws-base", "ws-env-local", "ws-local-env", "app-base", "app-env-local", "app-local-env", "shared-in-app-env-local"];' ); expect(readFile(`dist/apps/${appName2}/main.js`)).toContain( - 'const envVars = ["test", "52", "QA", "ws-base", "ws-local", "app2-base", "app2-local", "shared2-in-app-local"];' + 'const envVars = ["test", "52", "QA", "ws-base", "ws-env-local", "ws-local-env", "app2-base", "app2-env-local", "app2-local-env", "shared2-in-app-env-local"];' ); }); }); diff --git a/packages/workspace/src/tasks-runner/task-orchestrator.ts b/packages/workspace/src/tasks-runner/task-orchestrator.ts index 909125cc52..16124bef87 100644 --- a/packages/workspace/src/tasks-runner/task-orchestrator.ts +++ b/packages/workspace/src/tasks-runner/task-orchestrator.ts @@ -350,8 +350,10 @@ export class TaskOrchestrator { const envsFromFiles = { ...parseEnv('.env'), ...parseEnv('.local.env'), + ...parseEnv('.env.local'), ...parseEnv(`${task.projectRoot}/.env`), ...parseEnv(`${task.projectRoot}/.local.env`), + ...parseEnv(`${task.projectRoot}/.env.local`), }; const env: NodeJS.ProcessEnv = {