I'm using webpack to bundle an isomorphic JS app (based on this example) so that the browser runs the same code as the server. Everything is running smoothly except I have a config.js
with some settings which are pulled in from environment variables on the server:
module.exports = {
servers:
auth: process.env.AUTH_SERVER_URL,
content: process.env.CONTENT_SERVER_URL
}
}
On the server this is grand, but when webpack renders this for the client process
is empty and this doesn't work.
I'm hoping there's a kind of 'find and replace' webpack plugin that will replace them with their content in that file alone?
"…config.js content…".replace(/process\.env\.([a-z0-9_]+)/, function(match, varName) {
return process.env[varName];
})
I'm using webpack to bundle an isomorphic JS app (based on this example) so that the browser runs the same code as the server. Everything is running smoothly except I have a config.js
with some settings which are pulled in from environment variables on the server:
module.exports = {
servers:
auth: process.env.AUTH_SERVER_URL,
content: process.env.CONTENT_SERVER_URL
}
}
On the server this is grand, but when webpack renders this for the client process
is empty and this doesn't work.
I'm hoping there's a kind of 'find and replace' webpack plugin that will replace them with their content in that file alone?
"…config.js content…".replace(/process\.env\.([a-z0-9_]+)/, function(match, varName) {
return process.env[varName];
})
Share
Improve this question
asked Feb 25, 2015 at 11:26
JP.JP.
5,59415 gold badges64 silver badges106 bronze badges
3
|
4 Answers
Reset to default 16Note that using the DefinePlugin
as suggested in the accepted answer is potentially a dangerous action as it completely exposes process.env
. As Tobias commented above there's actually a plugin EnvironmentPlugin
that does exactly this with an added whitelisting ability, using DefinePlugin
internally.
In your webpack.config.js
:
{
plugins: [
new webpack.EnvironmentPlugin([
'NODE_ENV',
'WHITELISTED_ENVIRONMENT_VARIABLE'
])
]
}
In your webpack.config.js
,
use the following preLoaders
(or postLoaders
),
module: {
preLoaders: [
{ test: /\.js$/, loader: "transform?envify" },
]
}
Another way using the webpack.DefinePlugin
:
plugins: [
new DefinePlugin({
'process.env': Object.keys(process.env).reduce(function(o, k) {
o[k] = JSON.stringify(process.env[k]);
return o;
}, {})
})
]
NOTE: The old method using envify-loader
was deprecated:
DEPRECATED: use transform-loader + envify instead.
Yeah; looks like envify-loader was the easy solution.
I just added the following to my webpack loaders:
{
test: /config\.js$/, loader: "envify-loader"
}
And the config.js
(and only that file) is modified to include any referenced environment variables statically :)
I needed a way to use the env variables set on the machine that is running the code, no the env variables of the machine building the app.
I do not see a solution for this yet. This is what I did.
In publicEnv.js
:
// List of the env variables you want to use on the client. Careful on what you put here!
const publicEnv = [
'API_URL',
'FACEBOOK_APP_ID',
'GA_ID'
];
const isBrowser = typeof window !== 'undefined';
const base = (isBrowser ? window.__ENV__ : process.env) || {};
const env = {};
for (const v of publicEnv) {
env[v] = base[v];
}
export default env;
In the HTML template file of the page I have:
import publicEnv from 'publicEnv.js';
...
<script>
window.__ENV__ = ${stringify(publicEnv)};
// Other things you need here...
window.__INITIAL_STATE__ = ${stringify(initialState)};
</script>
So now I can get the value of the env variable on both frontend and backend with:
import publicEnv from 'publicEnv.js';
...
console.log("Google Analytic code is", publicEnv.GA_ID);
I hope it can help.
new webpack.EnvironmentPlugin(["AUTH_SERVER_URL", "CONTENT_SERVER_URL"])
– Tobias K. Commented Feb 28, 2015 at 0:15global
and inwindow
in the HTML but it is not my favorite solution. – Chris Cinelli Commented Jan 19, 2017 at 22:31