Document how to works with environment variables
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);
});
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).
Yup, we should note that
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
What about this issue ? Would be very helpful ;)
A proposal has been opened on #568, but it's totally not an easy feature in fact :p
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
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})
])
)
);
})())
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:
- Check var in system (process)
- Check var in
.env.local - Check var in
.env