Skip to content

Commit 2507eef

Browse files
committed
Adding namespaced environment variables to DefinePlugin under REACT_APP_
1 parent 11ec5d6 commit 2507eef

File tree

5 files changed

+113
-24
lines changed

5 files changed

+113
-24
lines changed

config/env.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
var REACT_APP = /^REACT_APP_/i;
11+
var NODE_ENV = JSON.stringify(process.env.NODE_ENV || 'development');
12+
13+
module.exports = Object
14+
.keys(process.env)
15+
.filter(key => REACT_APP.test(key))
16+
.reduce((env, key) => {
17+
env['process.env.' + key] = JSON.stringify(process.env[key]);
18+
return env;
19+
}, {
20+
'process.env.NODE_ENV': NODE_ENV
21+
});

config/webpack.config.dev.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var webpack = require('webpack');
1313
var HtmlWebpackPlugin = require('html-webpack-plugin');
1414
var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
1515
var paths = require('./paths');
16+
var env = require('./env');
1617

1718
module.exports = {
1819
devtool: 'eval',
@@ -104,7 +105,7 @@ module.exports = {
104105
template: paths.appHtml,
105106
favicon: paths.appFavicon,
106107
}),
107-
new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"development"' }),
108+
new webpack.DefinePlugin(env),
108109
// Note: only CSS is currently hot reloaded
109110
new webpack.HotModuleReplacementPlugin(),
110111
new CaseSensitivePathsPlugin()

config/webpack.config.prod.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
1414
var ExtractTextPlugin = require('extract-text-webpack-plugin');
1515
var url = require('url');
1616
var paths = require('./paths');
17+
var env = require('./env');
1718

1819
var homepagePath = require(paths.appPackageJson).homepage;
1920
var publicPath = homepagePath ? url.parse(homepagePath).pathname : '/';
@@ -127,7 +128,7 @@ module.exports = {
127128
minifyURLs: true
128129
}
129130
}),
130-
new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }),
131+
new webpack.DefinePlugin(env),
131132
new webpack.optimize.OccurrenceOrderPlugin(),
132133
new webpack.optimize.DedupePlugin(),
133134
new webpack.optimize.UglifyJsPlugin({

scripts/eject.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ prompt(
3535
path.join('config', 'flow', 'file.js.flow'),
3636
path.join('config', 'eslint.js'),
3737
path.join('config', 'paths.js'),
38+
path.join('config', 'env.js'),
3839
path.join('config', 'polyfills.js'),
3940
path.join('config', 'webpack.config.dev.js'),
4041
path.join('config', 'webpack.config.prod.js'),

template/README.md

Lines changed: 87 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ You can find the most recent version of this guide [here](https://github.com/fac
66
- [Sending Feedback](#sending-feedback)
77
- [Folder Structure](#folder-structure)
88
- [Available Scripts](#available-scripts)
9-
- [npm start](#npm-start)
10-
- [npm run build](#npm-run-build)
11-
- [npm run eject](#npm-run-eject)
9+
- [npm start](#npm-start)
10+
- [npm run build](#npm-run-build)
11+
- [npm run eject](#npm-run-eject)
1212
- [How To...](#how-to)
13-
- [Install a Dependency](#install-a-dependency)
14-
- [Import a Component](#import-a-component)
15-
- [Add a Stylesheet](#add-a-stylesheet)
16-
- [Post-Process CSS](#post-process-css)
17-
- [Add Images and Fonts](#add-images-and-fonts)
18-
- [Install React Bootstrap](#install-react-bootstrap)
19-
- [Display Lint Output in the Editor](#display-lint-output-in-the-editor)
20-
- [Add Flow](#add-flow)
21-
- [Deploy](#deploy)
22-
- [Something Missing?](#something-missing)
13+
- [Installing a Dependency](#installing-a-dependency)
14+
- [Importing a Component](#importing-a-component)
15+
- [Adding a Stylesheet](#adding-a-stylesheet)
16+
- [Post-Processing CSS](#post-processing-css)
17+
- [Adding Images and Fonts](#adding-images-and-fonts)
18+
- [Installing React Bootstrap](#installing-react-bootstrap)
19+
- [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor)
20+
- [Adding Flow](#adding-flow)
21+
- [Adding Custom Environment Variables](#adding-custom-environment-variables)
22+
- [Deploying](#deploying)
23+
- [Something Missing?](#something-missing)
2324

2425
## Sending Feedback
2526

@@ -94,15 +95,15 @@ You don’t have to ever use `eject`. The curated feature set is suitable for sm
9495

9596
## How To...
9697

97-
### Install a Dependency
98+
### Installing a Dependency
9899

99100
The generated project includes React and ReactDOM as dependencies. It also includes a set of scripts used by Create React App as a development dependency. You may install other dependencies (for example, React Router) with `npm`:
100101

101102
```
102103
npm install --save <library-name>
103104
```
104105

105-
### Import a Component
106+
### Importing a Component
106107

107108
This project setup supports ES6 modules thanks to Babel.
108109
While you can still use `require()` and `module.exports`, we encourage you to use [`import` and `export`](http://exploringjs.com/es6/ch_modules.html) instead.
@@ -150,7 +151,7 @@ Learn more about ES6 modules:
150151
* [Exploring ES6: Modules](http://exploringjs.com/es6/ch_modules.html)
151152
* [Understanding ES6: Modules](https://leanpub.com/understandinges6/read#leanpub-auto-encapsulating-code-with-modules)
152153

153-
### Add a Stylesheet
154+
### Adding a Stylesheet
154155

155156
This project setup uses [Webpack](https://webpack.github.io/) for handling all assets. Webpack offers a custom way of “extending” the concept of `import` beyond JavaScript. To express that a JavaScript file depends on a CSS file, you need to **import the CSS from the JavaScript file**:
156157

@@ -182,7 +183,7 @@ In development, expressing dependencies this way allows your styles to be reload
182183

183184
If you are concerned about using Webpack-specific semantics, you can put all your CSS right into `src/index.css`. It would still be imported from `src/index.js`, but you could always remove that import if you later migrate to a different build tool.
184185

185-
### Post-Process CSS
186+
### Post-Processing CSS
186187

187188
This project setup minifies your CSS and adds vendor prefixes to it automatically through [Autoprefixer](https://github.com/postcss/autoprefixer) so you don’t need to worry about it.
188189

@@ -215,7 +216,7 @@ becomes this:
215216

216217
There is currently no support for preprocessors such as Less, or for sharing variables across CSS files.
217218

218-
### Add Images and Fonts
219+
### Adding Images and Fonts
219220

220221
With Webpack, using static assets like images and fonts works similarly to CSS.
221222

@@ -251,7 +252,7 @@ Please be advised that this is also a custom feature of Webpack.
251252

252253
**It is not required for React** but many people enjoy it (and React Native uses a similar mechanism for images). However it may not be portable to some other environments, such as Node.js and Browserify. If you prefer to reference static assets in a more traditional way outside the module system, please let us know [in this issue](https://github.com/facebookincubator/create-react-app/issues/28), and we will consider support for this.
253254

254-
### Install React Bootstrap
255+
### Installing React Bootstrap
255256

256257
You don’t have to use React Bootstrap together with React but it is a popular library for integrating Bootstrap with React apps. If you need it, you can integrate it with Create React App by following these steps:
257258

@@ -279,7 +280,7 @@ import { Navbar, Jumbotron, Button } from 'react-bootstrap';
279280

280281
Now you are ready to use the imported React Bootstrap components within your component hierarchy defined in the render method. Here is an example [App.js](https://github.com/manavsehgal/react-eshop/blob/master/src/App.js) redone using React Bootstrap.
281282

282-
### Display Lint Output in the Editor
283+
### Displaying Lint Output in the Editor
283284

284285
>Note: this feature is available with `[email protected]` and higher.
285286
@@ -310,7 +311,7 @@ npm install -g eslint babel-eslint eslint-plugin-react eslint-plugin-import esli
310311

311312
We recognize that this is suboptimal, but it is currently required due to the way we hide the ESLint dependency. The ESLint team is already [working on a solution to this](https://github.com/eslint/eslint/issues/3458) so this may become unnecessary in a couple of months.
312313

313-
### Add Flow
314+
### Adding Flow
314315

315316
Flow typing is currently [not supported out of the box](https://github.com/facebookincubator/create-react-app/issues/72) with the default `.flowconfig` generated by Flow. If you run it, you might get errors like this:
316317

@@ -366,7 +367,71 @@ module.name_mapper='^\(.*\)\.\(jpg\|png\|gif\|eot\|svg\|ttf\|woff\|woff2\|mp4\|w
366367

367368
We will consider integrating more tightly with Flow in the future so that you don’t have to do this.
368369

369-
### Deploy
370+
### Adding Custom Environment Variables
371+
372+
> Note: this feature is available with `[email protected]` and higher.
373+
374+
Your project can consume variables declared in your environment as if they were declared locally in your JS files. By
375+
default you will have `NODE_ENV` defined for you, and any other environment variables starting with
376+
`REACT_APP_`. These environment variables will be defined for you on `process.env`. For example, having an environment
377+
variable named `REACT_APP_SECRET_CODE` will be exposed in your JS as `process.env.REACT_APP_SECRET_CODE`, in addition
378+
to `process.env.NODE_ENV`.
379+
380+
These environment variables can be useful for displaying information conditionally based on where the project is
381+
deployed or consuming sensitive data that lives outside of version control.
382+
383+
First, you need to have environment variables defined, which can vary between OSes. For example, let's say you wanted to
384+
consume a secret defined in the environment inside a `<form>`:
385+
386+
```jsx
387+
<h6>Hello, Admin!<h6>
388+
389+
<small>You are running this application in <strong>{process.env.NODE_ENV}</strong> mode.</small>
390+
391+
<form>
392+
<input type="hidden" defaultValue={process.env.REACT_APP_SECRET_CODE} />
393+
</form>
394+
```
395+
396+
The above form is looking for a variable called `REACT_APP_SECRET_CODE` from the environment. In order to consume this
397+
value, we need to have it defined in the environment:
398+
399+
#### Windows Cmd
400+
401+
```cmd
402+
set REACT_APP_SECRET_CODE=abcdef && npm start
403+
```
404+
405+
#### Bash/Unix shells
406+
407+
```bash
408+
REACT_APP_SECRET_CODE=abcdef npm start
409+
```
410+
411+
> Note: Defining environment variables in this manner is temporary for the life of the shell session. Setting
412+
permanent environment variables is outside the scope of these docs.
413+
414+
With our environment variable defined, we start the app and consume the values. Remember that the `NODE_ENV`
415+
variable will be set for you automatically. When you load the app in the browser and inspect the `<input>`, you will see
416+
its value set to `abcdef`, and the bold text will show the environment provided when using `npm start`:
417+
418+
```html
419+
<h6>Hello, Admin!</h6>
420+
<small>You are running this application in <strong>development</strong> mode.</small>
421+
<form>
422+
<input type="hidden" value="abcdef" />
423+
</form>
424+
```
425+
426+
Having access to the `NODE_ENV` is also useful for performing actions conditionally:
427+
428+
```js
429+
if (process.env.NODE_ENV !== 'production') {
430+
analytics.disable();
431+
}
432+
```
433+
434+
### Deploying
370435

371436
#### GitHub Pages
372437

0 commit comments

Comments
 (0)