简体   繁体   中英

Environment Variables in an isomorphic JS app: Webpack find & replace?

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];
})

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM