Skip to content

Commit 8f59cad

Browse files
eliperelmangaearon
authored andcommitted
Adding namespaced environment variables to DefinePlugin under REACT_APP_ (#342)
1 parent c0a2ae4 commit 8f59cad

File tree

5 files changed

+113
-24
lines changed

5 files changed

+113
-24
lines changed

config/env.js

+21
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

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
1414
var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
1515
var WatchMissingNodeModulesPlugin = require('../scripts/utils/WatchMissingNodeModulesPlugin');
1616
var paths = require('./paths');
17+
var env = require('./env');
1718

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

config/webpack.config.prod.js

+2-1
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

+1
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

+87-22
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

@@ -277,7 +278,7 @@ import { Navbar, Jumbotron, Button } from 'react-bootstrap';
277278

278279
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://gist.githubusercontent.com/gaearon/85d8c067f6af1e56277c82d19fd4da7b/raw/6158dd991b67284e9fc8d70b9d973efe87659d72/App.js) redone using React Bootstrap.
279280

280-
### Display Lint Output in the Editor
281+
### Displaying Lint Output in the Editor
281282

282283
>Note: this feature is available with `[email protected]` and higher.
283284
@@ -315,7 +316,7 @@ npm install -g eslint babel-eslint eslint-plugin-react eslint-plugin-import esli
315316

316317
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.
317318

318-
### Add Flow
319+
### Adding Flow
319320

320321
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:
321322

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

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

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

376441
#### GitHub Pages
377442

0 commit comments

Comments
 (0)