SHORT Question
I'm looking some way to tell Webpack that, do not do anything with process
variable, just treat as like any other global variable (so it refers to window.process in client bundle). If not possible, then a way to inject variables in process.env
of Webpack during runtime on client.
LONG Explaination
At the moment, I use Webpack to pack my React (SSR) application. I have 5 environments like dev1, dev2... staging and production. I want to re-use the same build and keep things configurable like say Google Analytics ID on each environment is different.
Backend Dot ENV module does the job. I can define all constants as KEY=value
pair in .env
file and load them run time and use as process.env.KEY
in the code.
I was trying to replicate same behaviour for the front end side (or shared files). Say I have a baseService.js
which makes call to fetch
. It can be used from node + client as well. It uses variables like process.env.HOST
. Until now I was creating separate build for each environment, therefore had this defined in Webpack using webpack.DefinePlugin
plugin to be able to use this on client side bundle.
Now as I want to re-use the builds, I capture all constants in process.env
see if any of them is usable on client side by matching them with PUBLIC_(.*)
(It would match PUBLIC_KEY), if yes pack then in array and add in main html file as object as shown below:-
window.process = {ENV: { PUBLIC_GA_ID: '1235', PUBLIC_FOO: 'bar' }}
When I bundle my client using webpack and execute process.env.PUBLIC_GA_ID
is undefined (although it is there in head html as global window.process
variable). It is because webpack still injecting process variable from Node to the front end which has env
object as blank {}
object. I had it debugged below is the screenshot.
Above is console log of process
variable in a baseService.js
file. Obviously I cannot use window.process
here because then it would fail when file is being used in Node.js
I'm looking some way to tell Webpack that, do not do anything with process
variable, just treat as like any other global variable (so it refers to window.process in client bundle). If not possible, then a way to inject variables in process.env
of Webpack during runtime on client.
I think instead playing with Webpack to do this job, I have settled with for the simplest solution. If anyone has any better answer, please do post.
I created a utility function as follows:-
export const getEnv = key => {
if (typeof window === 'undefined') {
// node
return process.env[key]
}
// browser
return window.process.env[key]
}
Now I call getEnv('PUBLIC_KEY')
or getEnv('NODE_ENV')
both in node and in browser and works perfectly fine.
Although I'd still prefer the better way Webpack supports option to take process.env
run time or inject API for browser