I'd like to propose a method by which .env files can "extend" or "inherit" from a base .env file located on the filesystem. This is a pattern found often in tooling such as TypeScript's tsconfig, ESLint, and even TSLint in this repo.
# extends: .env.base
SOME_VALUE=batman
Code-duplication is one of the battles that maintainers and contributors to large monorepos are constantly waging. In monorepos for microservices or other forms of apps, it's very common to see the following in a directory tree:
.env
.env.dev
.env.local
.env.stage
Where each file contains roughly the same information, somethings with minor modifications. This is especially prevalent with microservice monorepos leveraging serverless and serverless-offline. In most cases, the repeated set of data contains things like keys and tokens, and baseline or default data that'll be pulled from external sources like SSM, Redis, etc one deployed. It's common to see deploy-target-specific .env files as well.
This proposal is centered around allowing for a single source-of-truth at a root filesystem location (e.g. a monorepo root) containing _most_ default data needed.
Consider this "base" file: _.env.base_
AUTH0_TOKEN=robin
OKTA_TOKEN=batman
SSM_PREFIX=joker
And this local _.env.local_ file, which extends .env.base
# extends: .env.base
DEPLOY_FRIDAY=true
At this point, process.env would contain; AUTH0_TOKEN, OKTA_TOKEN, SSM_PREFIX, and DEPLOY_FRIDAY. Say we needed a file for a staging environment that needed a slight modification to the default values, _env.stage_:
# extends: .env.base
SSM_PREFIX=stage
And process.env would contain all values from .env.base, but with SSM_PREFIX equal to stage, overriding the default value of joker.
As @maxbeatty pointed out in https://github.com/motdotla/dotenv/issues/377#issuecomment-464411650, one could author a utility method to be shared in the environment that calls multiple times:
const dotenv = require(“dotenv”);
[“.env”, “.env.whatever”].forEach(path => dotenv.config({ path }));
This is certainly valid for small projects.
The pitfall with this approach are projects which leverage dotenv to automatically load and spin up a particular environment, such as serverless-plugin-dotenv (npm link). Any consumer of dotenv that is prepackaged would need to modify their behavior to take advantage of extending other .env files. That would create fragmentation in the expected use from one environment to another.
I suggest that the value that this proposal would give to the community and userbase at large outweighs the code footprint and maintenance burden incurred by its addition. While small projects may not need this functionality, larger projects and specifically monorepos, are becoming more and more commonplace with companies such as Microsoft operating within monorepos almost exclusively. This would greatly reduce code duplication and be a large, further improvement to the developer experience.
I like this idea a lot at first glance. Need to dig in further but thumbs up!
I’d be on board. 👍
Coming from create-react-app, I'm surprised this is not implemented:
https://create-react-app.dev/docs/adding-custom-environment-variables/#what-other-env-files-can-be-used
It looks like react-scripts extends dotenv functionality?
Most helpful comment
I’d be on board. 👍