diff --git a/packages/react-scripts/config/env.js b/packages/react-scripts/config/env.js index fa42747f6a8..ceda79604e7 100644 --- a/packages/react-scripts/config/env.js +++ b/packages/react-scripts/config/env.js @@ -35,13 +35,16 @@ var dotenvFiles = [ // Load environment variables from .env* files. Suppress warnings using silent // if this file is missing. dotenv will never modify any environment variables -// that have already been set. +// that have already been set. Variable expansion is supported in .env files. // https://github.com/motdotla/dotenv +// https://github.com/motdotla/dotenv-expand dotenvFiles.forEach(dotenvFile => { if (fs.existsSync(dotenvFile)) { - require('dotenv').config({ - path: dotenvFile, - }); + require('dotenv-expand')( + require('dotenv').config({ + path: dotenvFile, + }) + ); } }); diff --git a/packages/react-scripts/fixtures/kitchensink/.env b/packages/react-scripts/fixtures/kitchensink/.env index 3e2f7b14a73..9f7acc60233 100644 --- a/packages/react-scripts/fixtures/kitchensink/.env +++ b/packages/react-scripts/fixtures/kitchensink/.env @@ -1,3 +1,7 @@ REACT_APP_X = x-from-original-env REACT_APP_ORIGINAL_1 = from-original-env-1 REACT_APP_ORIGINAL_2 = from-original-env-2 +REACT_APP_BASIC = basic +REACT_APP_BASIC_EXPAND = ${REACT_APP_BASIC} +REACT_APP_BASIC_EXPAND_SIMPLE = $REACT_APP_BASIC +REACT_APP_EXPAND_EXISTING = $REACT_APP_SHELL_ENV_MESSAGE diff --git a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js index 5138bc513b3..43badcbde8e 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js @@ -67,5 +67,22 @@ describe('Integration', () => { doc.getElementById('feature-shell-env-variables').textContent ).to.equal('fromtheshell.'); }); + + it('expand .env variables', async () => { + const doc = await initDOM('expand-env-variables'); + + expect(doc.getElementById('feature-expand-env-1').textContent).to.equal( + 'basic' + ); + expect(doc.getElementById('feature-expand-env-2').textContent).to.equal( + 'basic' + ); + expect(doc.getElementById('feature-expand-env-3').textContent).to.equal( + 'basic' + ); + expect( + doc.getElementById('feature-expand-env-existing').textContent + ).to.equal('fromtheshell'); + }); }); }); diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js index 5fe13accf25..0a1663192ee 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/App.js +++ b/packages/react-scripts/fixtures/kitchensink/src/App.js @@ -179,6 +179,11 @@ class App extends Component { this.setFeature(f.default) ); break; + case 'expand-env-variables': + import('./features/env/ExpandEnvVariables').then(f => + this.setFeature(f.default) + ); + break; default: throw new Error(`Missing feature "${feature}"`); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/ExpandEnvVariables.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/ExpandEnvVariables.js new file mode 100644 index 00000000000..58fc00e3a5c --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/ExpandEnvVariables.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; + +export default () => ( + + {process.env.REACT_APP_BASIC} + {process.env.REACT_APP_BASIC_EXPAND} + + {process.env.REACT_APP_BASIC_EXPAND_SIMPLE} + + + {process.env.REACT_APP_EXPAND_EXISTING} + + +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/ExpandEnvVariables.test.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/ExpandEnvVariables.test.js new file mode 100644 index 00000000000..4e4200abee8 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/ExpandEnvVariables.test.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import ExpandEnvVariables from './ExpandEnvVariables'; + +describe('expand .env variables', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + }); +}); diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index dcac53cf49f..f6bff1deaa6 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -32,6 +32,7 @@ "chalk": "1.1.3", "css-loader": "0.28.7", "dotenv": "4.0.0", + "dotenv-expand": "4.0.1", "eslint": "4.10.0", "eslint-config-react-app": "^2.0.1", "eslint-loader": "1.9.0", diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 772db475495..17b85756b4f 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -978,6 +978,25 @@ Please refer to the [dotenv documentation](https://github.com/motdotla/dotenv) f >Note: If you are defining environment variables for development, your CI and/or hosting platform will most likely need these defined as well. Consult their documentation how to do this. For example, see the documentation for [Travis CI](https://docs.travis-ci.com/user/environment-variables/) or [Heroku](https://devcenter.heroku.com/articles/config-vars). +#### Expanding Environment Variables In `.env` + +>Note: this feature is available with `react-scripts@1.0.18` and higher. + +Expand variables already on your machine for use in your .env file (using [dotenv-expand](https://github.com/motdotla/dotenv-expand)). See [#2223](https://github.com/facebookincubator/create-react-app/issues/2223). + +For example, to get the environment variable `npm_package_version`: +``` +REACT_APP_VERSION=$npm_package_version +# also works: +# REACT_APP_VERSION=${npm_package_version} +``` +Or expand variables local to the current `.env` file: +``` +DOMAIN=www.example.com +REACT_APP_FOO=$DOMAIN/foo +REACT_APP_BAR=$DOMAIN/bar +``` + ## Can I Use Decorators? Many popular libraries use [decorators](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841) in their documentation.