Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for local env values or multiple paths #54

Closed
danilofuchs opened this issue Apr 8, 2020 · 3 comments · Fixed by #55
Closed

Support for local env values or multiple paths #54

danilofuchs opened this issue Apr 8, 2020 · 3 comments · Fixed by #55

Comments

@danilofuchs
Copy link
Contributor

danilofuchs commented Apr 8, 2020

create-react-app has an awesome environment variables resolution pattern:
https://create-react-app.dev/docs/adding-custom-environment-variables/#what-other-env-files-can-be-used
It allows for users to define .env.development (tracked by git) and .env.development.local (not committed to the repo), .env which works on all envs, etc.

Another issue proposed to allow multiple paths, but in another context: #29.

This way, you could perhaps configure the plugin like this (given path supports variables: #52):

custom:
  dotenv:
    path: 
        - .env
        - .env.${self:stage}
        - .env.${self:stage}.local

The plugin would load each path sequentially, overriding envs as it goes.

Alternatively, the plugin would do these resolutions automatically.

This is the implementation on create-react-app. It takes into account several framework-specific things, but the main part, which applies here, is this: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/env.js#L26-L49

EDIT

Apparently, this behaviour was taken from Rails:
https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use

I made the change on a fork of mine

@danilofuchs
Copy link
Contributor Author

danilofuchs commented Apr 8, 2020

My approach looks something like this:

    /**
     * @param {string} env
     * @returns {string[]}
     */
    resolveEnvFileNames(env) {
        if (this.config && this.config.path) {
            return this.config.path;
        }

        // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
        const dotenvFiles = [
            `.env.${env}.local`,
            `.env.${env}`,
            // Don't include `.env.local` for `test` environment
            // since normally you expect tests to produce the same
            // results for everyone
            env !== "test" && `.env.local`,
            `.env`,
        ];

        const basePath =
            this.config && this.config.basePath ? this.config.basePath : "";

        const filesNames = dotenvFiles.map((file) => basePath + file);

        return filesNames.filter((fileName) => fs.existsSync(fileName));
    }

    /**
     * @param {string} env
     */
    loadEnv(env) {
        const envFileNames = this.resolveEnvFileNames(env);
        try {
            const envVarsArray = envFileNames.map(
                (fileName) =>
                    dotenvExpand(dotenv.config({ path: fileName })).parsed
            );

            const envVars = envVarsArray.reduce(
                (acc, curr) => ({ ...acc, ...curr }),
                {}
            );

           // Rest of code
           // ...

@dekked
Copy link

dekked commented Apr 18, 2020

This is great @danilofuchs! Can you link to your fork?

@danilofuchs
Copy link
Contributor Author

I actually cloned the repository directly into my project. I will open a proper fork of your repository so you can take a look.

I didn't implement the option to define the paths in the config

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants