webpack-encore icon indicating copy to clipboard operation
webpack-encore copied to clipboard

Document how to works with environment variables

Open Kocal opened this issue 6 years ago • 17 comments

Just a reminder to write a documentation for Encore.configureDefinePlugin(), and the integration with Symfony .env files and process.env.*.

  • https://github.com/motdotla/dotenv
Encore.configureDefinePlugin(options => {
  options['process.env'].MY_OPTION = JSON.stringify('foo');
});

For example for configuring sentry DNS from .env file:

Encore.configureDefinePlugin(options => {
  const env = dotenv.config();
    
  if (env.error) {
    throw env.error;
  }

  options['process.env'].SENTRY_DSN = JSON.stringify(env.parsed.SENTRY_DSN);
});

Kocal avatar Apr 16 '19 15:04 Kocal

We'll have to be careful about that one: there could be confusion related to the fact that it will be interpretated at build time and not on the server it'll be deployed to (like Symfony).

Lyrkan avatar Apr 16 '19 16:04 Lyrkan

Yup, we should note that

Kocal avatar Apr 16 '19 16:04 Kocal

In fact, what about adding a new method like .injectEnvironmentVariables(['NODE_ENV', '...']) that will:

  • resolve environment variables like Symfony do
  • automatically inject them with DefinePlugin + JSON.stringify

?

It can be a bit hard to implement it properly, but it will be 100 times more user friendly

Kocal avatar Apr 16 '19 16:04 Kocal

What about this issue ? Would be very helpful ;)

anaelChardan avatar Jan 16 '20 09:01 anaelChardan

A proposal has been opened on #568, but it's totally not an easy feature in fact :p

Kocal avatar Jan 16 '20 12:01 Kocal

I start using https://www.npmjs.com/package/dotenv-webpack in my project.

After installation:

In webpack.config.js import it:

const Dotenv = require('dotenv-webpack');

Add it as plugin:

.addPlugin(new Dotenv( { path: './.env.local', systemvars: true } ))

start using it in code:

{process.env.npm_package_version}

@anaelChardan

yaotzin1 avatar Jun 12 '20 14:06 yaotzin1

When used wrong, dotenv-webpack can leak e.g. the database connection string into public JS code. I made a little plugin based on dotenv and define that only includes PUBLIC_ prefixed env vars from both .env and .env.local

.addPlugin((() => {
        const parse = (envs) => envs.reduce((env, current) => {
            if (current.errors) {
                console.error(current.errors);
            }

            return {
                ...env,
                ...Object.fromEntries(
                    Object.entries(current.parsed ?? {})
                        .filter(([key]) => key.startsWith('PUBLIC_'))
                        .map(([key, value]) => [`process.env.${key}`, `"${value}"`])
                )
            };
        }, {})
        const log = (result) => {
            console.log('Loaded public .env vars', result);
            return result;
        }

        return new DefinePlugin(
            log(
                parse([
                    Dotenv.config({path: '.env', override: true}),
                    Dotenv.config({path: '.env.local', override: true})
                ])
            )
        );
    })())

veewee avatar Dec 06 '22 09:12 veewee

If you want to follow the way Symfony works with .env files you can use the dotenv-webpack and the config below

Encore.addPlugin(
  new Dotenv({
    path: ".env.local",
    defaults: ".env",
    systemvars: true,
    allowEmptyValues: true,
  })
)

Unfortunately it will not let you follow all the .env.* files Symfony use, but it will follow this order of fallbacks:

  1. Check var in system (process)
  2. Check var in .env.local
  3. Check var in .env

DmitryLanda avatar May 09 '23 20:05 DmitryLanda