Skip to content

Commit

Permalink
feat(core): load environment variables from configuration name
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder committed May 31, 2023
1 parent 103353a commit a53be8f
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 29 deletions.
28 changes: 16 additions & 12 deletions docs/shared/guides/define-environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@ By default, Nx will load any environment variables you place in the following fi

1. `apps/my-app/.env.[target-name].[configuration-name]`
2. `apps/my-app/.[target-name].[configuration-name].env`
3. `apps/my-app/.env.[target-name]`
4. `apps/my-app/.[target-name].env`
5. `apps/my-app/.env.local`
6. `apps/my-app/.local.env`
7. `apps/my-app/.env`
8. `.env.[target-name].[configuration-name]`
9. `.[target-name].[configuration-name].env`
10. `.env.[target-name]`
11. `.[target-name].env`
12. `.local.env`
13. `.env.local`
14. `.env`
3. `apps/my-app/.env.[configuration-name]`
4. `apps/my-app/.[configuration-name].env`
5. `apps/my-app/.env.[target-name]`
6. `apps/my-app/.[target-name].env`
7. `apps/my-app/.env.local`
8. `apps/my-app/.local.env`
9. `apps/my-app/.env`
10. `.env.[target-name].[configuration-name]`
11. `.[target-name].[configuration-name].env`
12. `.env.[configuration-name]`
13. `.[configuration-name].env`
14. `.env.[target-name]`
15. `.[target-name].env`
16. `.local.env`
17. `.env.local`
18. `.env`

{% callout type="warning" title="Order is important" %}
Nx will move through the above list, ignoring files it can't find, and loading environment variables
Expand Down
11 changes: 10 additions & 1 deletion e2e/nx-run/src/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,28 @@ describe('Nx Running Tests', () => {
const myapp = uniq('app');
const target = uniq('script');
const expectedOutput = uniq('myEchoedString');
const expectedEnvOutput = uniq('myEnvString');

runCLI(`generate @nx/web:app ${myapp}`);
updateFile(
`apps/${myapp}/.env.production`,
`ENV_VAR=${expectedEnvOutput}`
);
updateFile(
`apps/${myapp}/package.json`,
JSON.stringify({
name: myapp,
scripts: {
[target]: `echo ${expectedOutput}`,
[target]: `echo ${expectedOutput} $ENV_VAR`,
},
})
);

expect(runCLI(`${target} ${myapp}`)).toContain(expectedOutput);
expect(runCLI(`${target} ${myapp}`)).not.toContain(expectedEnvOutput);
expect(runCLI(`${target} ${myapp} --configuration production`)).toContain(
expectedEnvOutput
);
}, 10000);

it('should run targets inferred from plugin-specified project files', () => {
Expand Down
36 changes: 24 additions & 12 deletions packages/nx/src/tasks-runner/forked-process-task-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,25 +415,37 @@ export class ForkedProcessTaskRunner {
...parseEnv(`.${task.target.target}.env`),
...parseEnv(`.env.${task.target.target}`),
...(task.target.configuration
? parseEnv(`.${task.target.target}.${task.target.configuration}.env`)
: {}),
...(task.target.configuration
? parseEnv(`.env.${task.target.target}.${task.target.configuration}`)
? {
...parseEnv(`.${task.target.configuration}.env`),
...parseEnv(
`.${task.target.target}.${task.target.configuration}.env`
),
...parseEnv(`.env.${task.target.configuration}`),
...parseEnv(
`.env.${task.target.target}.${task.target.configuration}`
),
}
: {}),
...parseEnv(`${task.projectRoot}/.env`),
...parseEnv(`${task.projectRoot}/.local.env`),
...parseEnv(`${task.projectRoot}/.env.local`),
...parseEnv(`${task.projectRoot}/.${task.target.target}.env`),
...parseEnv(`${task.projectRoot}/.env.${task.target.target}`),
...(task.target.configuration
? parseEnv(
`${task.projectRoot}/.${task.target.target}.${task.target.configuration}.env`
)
: {}),
...(task.target.configuration
? parseEnv(
`${task.projectRoot}/.env.${task.target.target}.${task.target.configuration}`
)
? {
...parseEnv(
`${task.projectRoot}/.${task.target.configuration}.env`
),
...parseEnv(
`${task.projectRoot}/.${task.target.target}.${task.target.configuration}.env`
),
...parseEnv(
`${task.projectRoot}/.env.${task.target.configuration}`
),
...parseEnv(
`${task.projectRoot}/.env.${task.target.target}.${task.target.configuration}`
),
}
: {}),
};
} else {
Expand Down
18 changes: 14 additions & 4 deletions packages/nx/src/utils/project-graph-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { buildTargetFromScript, PackageJson } from './package-json';
import { join } from 'path';
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
import { readJsonFile } from './fileutils';
import { fileExists, readJsonFile } from './fileutils';
import { readCachedProjectGraph } from '../project-graph/project-graph';
import { TargetConfiguration } from '../config/workspace-json-project-json';
import { workspaceRoot } from './workspace-root';

export function projectHasTarget(
project: ProjectGraphProjectNode,
Expand All @@ -22,9 +23,18 @@ export function projectHasTargetAndConfiguration(
configuration: string
) {
return (
projectHasTarget(project, target) &&
project.data.targets[target].configurations &&
project.data.targets[target].configurations[configuration]
// Explicitly defined target + configuration
(projectHasTarget(project, target) &&
project.data.targets[target].configurations &&
project.data.targets[target].configurations[configuration]) ||
// Inferred configuration from presence of .env files
(projectHasTarget(project, target) &&
[
join(workspaceRoot, `.env.${configuration}`),
join(workspaceRoot, `.${configuration}.env`),
join(workspaceRoot, project.data.root, `.${configuration}.env`),
join(workspaceRoot, project.data.root, `.${configuration}.env`),
].some(fileExists))
);
}

Expand Down

0 comments on commit a53be8f

Please sign in to comment.