If you are facing this problem and you are using webpack, you can get the desired process
data injected into the client bundle by using DefinePlugin
within your webpack.config.js
.
In the example below, I show how to add several things to process.env
object to make available within the browser:
- all the environment variables inside
.env
using the library
dotenv
- the value of
NODE_ENV
, which is either 'development'
or 'production'
Working example
# .env
API_KEY=taco-tues-123
API_SECRET=secret_tacos
// webpack.config.js
const dotenv = require('dotenv').config({ path: __dirname + '/.env' })
const isDevelopment = process.env.NODE_ENV !== 'production'
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': JSON.stringify(dotenv.parsed),
'process.env.NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production'),
}),
].filter(Boolean),
}
// Within client side bundle (React)
// src/App.jsx
console.log(process.env) // {API_KEY: "taco-tues-123", API_SECRET: "secret_tacos"}
console.log(process.env.NODE_ENV) // development
Notice that console.log(process.env)
only has the values from the .env
file, and that NODE_ENV
is not a part of the process.env
object.
In the example below, I show how I was trying to inject the process.env
object which led me to this stack overflow. I also include a highlight from the webpack documentation on why the code below was not working.
Broken example
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
...dotenv.parsed,
'NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production')
}
}),
].filter(Boolean),
}
// Within client side bundle (React)
// src/App.jsx
console.log(process.env) // Uncaught ReferenceError: taco is not defined
console.log(process.env.NODE_ENV) // development
From the webpack DefinePlugin docs:
Warning When defining values for process prefer
'process.env.NODE_ENV': JSON.stringify('production')
over
process: { env: { NODE_ENV: JSON.stringify('production') } }
Using the latter
will overwrite the process object which can break compatibility with
some modules that expect other values on the process object to be
defined.
!Warning!
Injecting dotenv.parsed
into the client bundle as described will expose these secrets to the client. For development purposes, not a big deal, but in a deployed production environment, any passwords or private api keys will be visible to anyone that goes looking for them.