最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Environment Variables in an isomorphic JS app: Webpack find & replace? - Stack Overflow

programmeradmin0浏览0评论

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
  • I've found envify but I'm having a hard time configuring it. – JP. Commented Feb 25, 2015 at 12:10
  • 1 There is an plugin, which allows to whitelist environment var which should be inlined: new webpack.EnvironmentPlugin(["AUTH_SERVER_URL", "CONTENT_SERVER_URL"]) – Tobias K. Commented Feb 28, 2015 at 0:15
  • The problem is that the machine that build the environment is not always the one that one that run the code (this is true in our case). One way is to put them in global and in window in the HTML but it is not my favorite solution. – Chris Cinelli Commented Jan 19, 2017 at 22:31
Add a comment  | 

4 Answers 4

Reset to default 16

Note 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.

发布评论

评论列表(0)

  1. 暂无评论