Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document multiple build environments via env-cmd #4071

Closed
trungdq88 opened this issue Feb 24, 2018 · 7 comments
Closed

Document multiple build environments via env-cmd #4071

trungdq88 opened this issue Feb 24, 2018 · 7 comments

Comments

@trungdq88
Copy link
Contributor

The term "development environment", "test environment" and "production environment" is used differently across the contexts and sometimes cause confusion for users.

  • create-react-app defines the environment name by the state of app code build: "development" means the code is not minified and run in live reload mode on local machines, "test" means the code is executing in unit test process, "production" means the code is minified and optimized with source map. I'll call this "development build", "test build" and "production build".

  • Mean while, in large portion of the software industry, these terms are used differently:

image

In the diagram above, I'll call them deploy environment, each deploy environment is a set of all the services that linked and worked with each other in an isolated place (servers/VPN).

"Frontend" is where create-react-app lives, and this all run "production build" of the app, which means the code is minified and optimized.

The problem

Regarding this document: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables

  • NODE_ENV always resolves to production when built with yarn build, even if we try to run NODE_ENV=staging yarn build.
  • There is no effective way to define different environment variables for each deploy environments. This is a real need.
  • There is no or very little benefit to define different environment variables for development build and production build, most of the time it is the same.

What I have been doing to resolve this

  • Put all the environment variables in source code and use domain name to identify the deployment environment the app is running. This reveals environment variables of all deployment environments, not so good.
  • or
  • Having different package.json scripts to build for different deployment environments: yarn build-staging, yarn build-production,... In the script, it creates .env file according the deployment environment and build. Ex: mv env/staging.env ./.env && yarn build.
  • or
  • On each deployment environment I setup a mini server that hosts an API endpoint and return environment variables for that deployment environment. (ex: https://staging-my-app.com/env)

Better way?

What is the best practice here? Have anyone of you run into this problem? How did you do it? Should create-react-app do something about this? Please share, thanks!

@MilllerTime
Copy link

You described the situation well 🙂

The default use of NODE_ENV is intentional and is solely used to distinguish between local development builds, unit tests, and optimized production builds. You can think of 'production' as a generic "distribution" build, not necessarily a build literally destined for a public-facing production server.

As you mentioned, it is common to have a few types of server environments for an application. These should all run the optimized NODE_ENV=production build, so that you can test your app with production-level performance. In order to programmatically differentiate between environments at runtime, you'll need to use a different environment variable, something other than NODE_ENV.

Create-react-app mandates that you prefix any custom environment variables with REACT_APP_. You can set custom prefixed environment variables from a CLI, see this section of the readme. In Bash for example, you could run:

REACT_APP_DIST_ENV=staging yarn build

You can access the variable in your app with process.env.REACT_APP_DIST_ENV. For example:

if (process.env.REACT_APP_DIST_ENV === 'staging') {
    analytics.setEnvironment('staging');
}

I haven't personally tried this with create-react-app, but check out the cross-env package. It allows setting environment variables in a cross-platform manner. You could then simplify your package.json scripts to something like this:

"build:staging": "cross-env REACT_APP_DIST_ENV=staging && yarn build"

Then run yarn build:staging on any machine to compile an optimized build ready to be deployed on a staging server.

@Timer
Copy link
Contributor

Timer commented Feb 24, 2018

The easiest way to achieve this is via .env files, injecting each variable you'd like to use in your app, most close to your second solution.

Instead, create one for each environment.

.env.staging

REACT_APP_API_URL=http://api-stg.example.com

.env.qa

REACT_APP_API_URL=http://api-qa.example.com

Then you can just add some extra scripts in your package.json:

{
  "scripts": {
    "build:staging": "env-cmd .env.staging yarn build",
    "build:qa": "env-cmd .env.qa yarn build"
  }
}

In this scenario, .env.production would only be used for fallback if a variable isn't specified in .env.staging or .env.qa.

@Timer Timer changed the title ENV vars in multiple "production" environments. Document multiple build environments via env-cmd Mar 5, 2018
@jmuzsik
Copy link

jmuzsik commented Mar 5, 2018

Hi i'd like to do this.

But as a quick note, basically what I am going to do is edit the docs to state what you guys just stated in a higher level way?

Should I simply do so, with say, a few sentences and a short code snippet or ought I be more detailed?

@Timer
Copy link
Contributor

Timer commented Mar 5, 2018

I'd say add a section under "Building for Relative Paths" in "Deployment" named "Building for Multiple Environments" and then give a more doc-y explanation of the solution I gave above.
I'd make it a bit more detailed.

@jmuzsik
Copy link

jmuzsik commented Mar 5, 2018

Great, going to start working on it today

@moersing
Copy link

moersing commented Mar 6, 2018

@Timer Good guy , That is good idea , tks.

Timer pushed a commit that referenced this issue Apr 15, 2018
* Docs - Document multiple build environments via

* Docs - Document multiple build environments via

* Docs - Document multiple build environments via

* Docs - Document multiple build environments via env-cmd

* fix - based upon requests

* Update README.md
@Timer
Copy link
Contributor

Timer commented Apr 15, 2018

Documentation added in #4117.

@Timer Timer closed this as completed Apr 15, 2018
kellyrmilligan added a commit to kellyrmilligan/create-react-app that referenced this issue May 2, 2018
* upstream/next: (35 commits)
  Update envinfo and issue template (facebook#4375)
  Update sass-loader to 7.0.1 (facebook#4376)
  Support package distribution tags (facebook#4350)
  fix broken css module support in prod (facebook#4361)
  Bumped jest version to 22.4.1 (facebook#4362)
  bump babel 7 to beta 46
  bump lint-staged to node 10 compatible version
  documentation: Added License to the README.md (facebook#4294)
  Bump `fsevents`. (facebook#4331)
  Fix typo in e2e-simple.sh comment (facebook#4323)
  Add Sass loader (facebook#4195)
  Fix some typos in README.md (facebook#4286)
  Added learnstorybook.com to Storybook links (facebook#4298)
  Document multiple build environments via `env-cmd` facebook#4071 (facebook#4117)
  Fixed link to CSS imports blog post
  Update CSS Modules localIndetName (facebook#4192)
  Enable loose mode for `class-properties` (facebook#4248)
  bump babel 7 beta (facebook#4253)
  Small typo fix facebook#4217
  Changelog for 1.1.4
  ...
kellyrmilligan added a commit to kellyrmilligan/create-react-app that referenced this issue May 2, 2018
* next: (35 commits)
  Update envinfo and issue template (facebook#4375)
  Update sass-loader to 7.0.1 (facebook#4376)
  Support package distribution tags (facebook#4350)
  fix broken css module support in prod (facebook#4361)
  Bumped jest version to 22.4.1 (facebook#4362)
  bump babel 7 to beta 46
  bump lint-staged to node 10 compatible version
  documentation: Added License to the README.md (facebook#4294)
  Bump `fsevents`. (facebook#4331)
  Fix typo in e2e-simple.sh comment (facebook#4323)
  Add Sass loader (facebook#4195)
  Fix some typos in README.md (facebook#4286)
  Added learnstorybook.com to Storybook links (facebook#4298)
  Document multiple build environments via `env-cmd` facebook#4071 (facebook#4117)
  Fixed link to CSS imports blog post
  Update CSS Modules localIndetName (facebook#4192)
  Enable loose mode for `class-properties` (facebook#4248)
  bump babel 7 beta (facebook#4253)
  Small typo fix facebook#4217
  Changelog for 1.1.4
  ...
zmitry pushed a commit to zmitry/create-react-app that referenced this issue Sep 30, 2018
…ebook#4117)

* Docs - Document multiple build environments via

* Docs - Document multiple build environments via

* Docs - Document multiple build environments via

* Docs - Document multiple build environments via env-cmd

* fix - based upon requests

* Update README.md
@lock lock bot locked and limited conversation to collaborators Jan 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants