Webpacker: Staging vs production environment

Created on 4 Mar 2019  Â·  9Comments  Â·  Source: rails/webpacker

process.env.NODE_ENV returns production (not "staging") even though I have the following environment variable NODE_ENV=staging on my staging app.

This is on Heroku, so not sure if this is a Heroku issue or Webpacker.

  • I am using 4.0.1 for both the gem and npm library, and on Rails 5.2.2
  • I have a staging: configuration in webpacker.yml which looks like production:

config/webpack/staging.js -

process.env.NODE_ENV = process.env.NODE_ENV || 'staging'

const environment = require('./environment')

module.exports = environment.toWebpackConfig()

EDIT: looks like definitely a Webpacker issue. I ran Heroku bash console to check process.env.NODE_ENV and looks ok to me, but somehow Webpacker is not picking it.

$ heroku run bash -a my-heroku-app-staging
Running bash on ⬢ my-heroku-app-staging... up, run.5321 (Hobby)
~ $ node -v
v11.10.1
~ $ node 
> process.env.NODE_ENV
'staging'

Most helpful comment

thanks, but that doesn't mean that this doesn't need fixing, right?

No that's correct because we don't want to support anything beyond standard environments for nodeJS world. As clearly explained by Jake, standard environment names have specific meaning for various libraries, example: React will optimise the build if set to "production", whereas "staging" has no meaning. The same applies to Webpack as well.

Therefore, please use standard environment names as NODE_ENV - test, development, production but to control the internal config use environment variables to change during build-time.

For example: API_URL: "app.test", API_URL: "app.dev", API_URL: "app.production", "API_URL": "app.staging"

All 9 comments

Short answer: You want your client-side assets to be built "as if it were production" when you deploy to staging. This is because NODE_ENV pulls different levers than RAILS_ENV, especially when it comes to how your build & dependencies behave.

Long answer: https://github.com/rails/webpacker/issues/1212#issuecomment-442228316



Here is the line where your staging is being overwritten, just in case you wanted to make a PR or change yourself:

https://github.com/rails/webpacker/blob/227661b546701e107213aa9b6f83451bc89cf7d5/package/env.js#L18

With that said, I would not characterize this as an issue with Webpacker, it just needs better documentation. Like here:

Please note, NODE_ENV can either be set to production, development or test.

@jakeNiemiec Yea I guess from compilation point of view staging & production are same.

But in our code, we are doing something like this. I am new to React/Webpacker, so perhaps theres a better way of doing this?

switch (process.env.NODE_ENV) {
  case 'production':
    apiUrl = `https://server.com`;
    break;
  case 'staging':
    apiUrl = `https://staging.server.com`;
}

What about switch (process.env.RAILS_ENV) {?

Or you could even do:

const DEFAULT_API_URL = `https://server.com`;
apiUrl = process.env.API_URL || DEFAULT_API_URL;

Yea thats why I did as a temp fix. But I will nice to have no rails dependency in JS code.

@kapso Hey, As pointed out by Jake, please use env variables to set these options - https://12factor.net/config. You don't need Rails env then, just have different API_URL env variable value for different environments.

@gauravtiwari thanks, but that doesn't mean that this doesn't need fixing, right? https://github.com/rails/webpacker/blob/227661b546701e107213aa9b6f83451bc89cf7d5/package/env.js#L18

image

I believe Gaurav is saying that having more environment names would be worse than forcing you to use the NODE_ENV environments that your dependencies will look for.

Unknown to many Rails users: Angular, React and others have separate internal modes of operation based on development and production. If you set NODE_ENV to staging, you rely on that platform's default mode of operation (which could be either).

Thus, you are given the option to set it to either based on what you are currently testing in staging:

  • Testing server-only stuff? Don't let NODE_ENV=development mode slow you down with stuff you aren't worried about. (plus it will be smaller)
  • Have a weird JS error that only happens when deployed? NODE_ENV=development will expose internals so that you can step over things line-by-line if you wish.

Hope this helps.

thanks, but that doesn't mean that this doesn't need fixing, right?

No that's correct because we don't want to support anything beyond standard environments for nodeJS world. As clearly explained by Jake, standard environment names have specific meaning for various libraries, example: React will optimise the build if set to "production", whereas "staging" has no meaning. The same applies to Webpack as well.

Therefore, please use standard environment names as NODE_ENV - test, development, production but to control the internal config use environment variables to change during build-time.

For example: API_URL: "app.test", API_URL: "app.dev", API_URL: "app.production", "API_URL": "app.staging"

Sounds good. @gauravtiwari @jakeNiemiec

I will make a point however is what you have here is a "mode" not environment. Meaning it's ok to have different environments (staging, production, sandbox etc) but all represent the same mode i.e production which is what you guys are alluding to. Perhaps the nomenclature here deserves some refactoring environment => mode.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amandapouget picture amandapouget  Â·  3Comments

christianrojas picture christianrojas  Â·  3Comments

suhomlineugene picture suhomlineugene  Â·  3Comments

eriknygren picture eriknygren  Â·  3Comments

towry picture towry  Â·  3Comments