Commit 80a7fc39 authored by Valerii Sorokobatko's avatar Valerii Sorokobatko Committed by Dan Abramov
Browse files

Feature/different env config files #1343 (#1344)

* support different env configs.

* fomrat code

* Hide doc

* Slightly rework the PR

* Remove .env in default template
* Use just one entry in the paths
* Unify env.js and loadEnv.js

* Oops, forgot these folks
parent 2de95c40
Showing with 103 additions and 22 deletions
+103 -22
...@@ -10,6 +10,36 @@ ...@@ -10,6 +10,36 @@
// @remove-on-eject-end // @remove-on-eject-end
'use strict'; 'use strict';
var fs = require('fs');
var paths = require('./paths');
var NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
throw new Error(
'The NODE_ENV environment variable is required but was not specified.'
);
}
// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
var dotenvFiles = [
paths.dotenv + '.' + NODE_ENV + '.local',
paths.dotenv + '.' + NODE_ENV,
paths.dotenv + '.local',
paths.dotenv,
];
// 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.
// https://github.com/motdotla/dotenv
dotenvFiles.forEach(dotenvFile => {
if (fs.existsSync(dotenvFile)) {
require('dotenv').config({
silent: true,
path: dotenvFile,
});
}
});
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration. // injected into the application via DefinePlugin in Webpack configuration.
const REACT_APP = /^REACT_APP_/i; const REACT_APP = /^REACT_APP_/i;
......
...@@ -74,6 +74,7 @@ function getServedPath(appPackageJson) { ...@@ -74,6 +74,7 @@ function getServedPath(appPackageJson) {
// config after eject: we're in ./config/ // config after eject: we're in ./config/
module.exports = { module.exports = {
dotenv: resolveApp('.env'),
appBuild: resolveApp('build'), appBuild: resolveApp('build'),
appPublic: resolveApp('public'), appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'), appHtml: resolveApp('public/index.html'),
...@@ -95,6 +96,7 @@ function resolveOwn(relativePath) { ...@@ -95,6 +96,7 @@ function resolveOwn(relativePath) {
// config before eject: we're in ./node_modules/react-scripts/config/ // config before eject: we're in ./node_modules/react-scripts/config/
module.exports = { module.exports = {
dotenv: resolveApp('.env'),
appPath: resolveApp('.'), appPath: resolveApp('.'),
appBuild: resolveApp('build'), appBuild: resolveApp('build'),
appPublic: resolveApp('public'), appPublic: resolveApp('public'),
...@@ -124,6 +126,7 @@ if ( ...@@ -124,6 +126,7 @@ if (
__dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1 __dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1
) { ) {
module.exports = { module.exports = {
dotenv: resolveOwn('template/.env'),
appPath: resolveApp('.'), appPath: resolveApp('.'),
appBuild: resolveOwn('../../build'), appBuild: resolveOwn('../../build'),
appPublic: resolveOwn('template/public'), appPublic: resolveOwn('template/public'),
......
REACT_APP_FILE_ENV_MESSAGE=fromtheenvfile 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_X = x-from-development-env
REACT_APP_DEVELOPMENT = development
REACT_APP_X = x-from-original-local-env
REACT_APP_ORIGINAL_2 = override-from-original-local-env-2
REACT_APP_X = x-from-production-env
REACT_APP_PRODUCTION = production
...@@ -16,8 +16,27 @@ describe('Integration', () => { ...@@ -16,8 +16,27 @@ describe('Integration', () => {
const doc = await initDOM('file-env-variables'); const doc = await initDOM('file-env-variables');
expect( expect(
doc.getElementById('feature-file-env-variables').textContent doc.getElementById('feature-file-env-original-1').textContent
).to.equal('fromtheenvfile.'); ).to.equal('from-original-env-1');
expect(
doc.getElementById('feature-file-env-original-2').textContent
).to.equal('override-from-original-local-env-2');
if (process.env.NODE_ENV === 'production') {
expect(doc.getElementById('feature-file-env').textContent).to.equal(
'production'
);
expect(doc.getElementById('feature-file-env-x').textContent).to.equal(
'x-from-production-env'
);
} else {
expect(doc.getElementById('feature-file-env').textContent).to.equal(
'development'
);
expect(doc.getElementById('feature-file-env-x').textContent).to.equal(
'x-from-development-env'
);
}
}); });
it('NODE_PATH', async () => { it('NODE_PATH', async () => {
......
...@@ -10,7 +10,16 @@ ...@@ -10,7 +10,16 @@
import React from 'react'; import React from 'react';
export default () => ( export default () => (
<span id="feature-file-env-variables"> <span>
{process.env.REACT_APP_FILE_ENV_MESSAGE}. <span id="feature-file-env-original-1">
{process.env.REACT_APP_ORIGINAL_1}
</span>
<span id="feature-file-env-original-2">
{process.env.REACT_APP_ORIGINAL_2}
</span>
<span id="feature-file-env">
{process.env.REACT_APP_DEVELOPMENT}{process.env.REACT_APP_PRODUCTION}
</span>
<span id="feature-file-env-x">{process.env.REACT_APP_X}</span>
</span> </span>
); );
...@@ -20,11 +20,8 @@ process.on('unhandledRejection', err => { ...@@ -20,11 +20,8 @@ process.on('unhandledRejection', err => {
throw err; throw err;
}); });
// Load environment variables from .env file. Suppress warnings using silent // Ensure environment variables are read.
// if this file is missing. dotenv will never modify any environment variables require('../config/env');
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({ silent: true });
const chalk = require('chalk'); const chalk = require('chalk');
const fs = require('fs-extra'); const fs = require('fs-extra');
......
...@@ -19,11 +19,8 @@ process.on('unhandledRejection', err => { ...@@ -19,11 +19,8 @@ process.on('unhandledRejection', err => {
process.env.NODE_ENV = 'development'; process.env.NODE_ENV = 'development';
// Load environment variables from .env file. Suppress warnings using silent // Ensure environment variables are read.
// if this file is missing. dotenv will never modify any environment variables require('../config/env');
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({ silent: true });
const fs = require('fs'); const fs = require('fs');
const chalk = require('chalk'); const chalk = require('chalk');
......
...@@ -20,11 +20,8 @@ process.on('unhandledRejection', err => { ...@@ -20,11 +20,8 @@ process.on('unhandledRejection', err => {
throw err; throw err;
}); });
// Load environment variables from .env file. Suppress warnings using silent // Ensure environment variables are read.
// if this file is missing. dotenv will never modify any environment variables require('../config/env');
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({ silent: true });
const jest = require('jest'); const jest = require('jest');
const argv = process.argv.slice(2); const argv = process.argv.slice(2);
......
...@@ -739,6 +739,24 @@ To define permanent environment variables, create a file called `.env` in the ro ...@@ -739,6 +739,24 @@ To define permanent environment variables, create a file called `.env` in the ro
REACT_APP_SECRET_CODE=abcdef REACT_APP_SECRET_CODE=abcdef
``` ```
<!--
TODO: uncomment (and tweak) the doc for 0.10
What .env* files are used?
* `.env` - Default
* `.env.development`, `.env.test`, `.env.production` - Environment-specific settings.
* `.env.local` - Local overrides. This file is loaded for all environments except test.
* `.env.development.local`, `.env.test.local`, `.env.production.local` - Local overrides of environment-specific settings.
Files priority (file is skipped if does not exist):
* npm test - `.env.test.local`, `env.test`, `.env.local`, `.env`
* npm run build - `.env.production.local`, `env.production`, `.env.local`, `.env`
* npm start - `.env.development.local`, `env.development`, `.env.local`, `.env`
Priority from left to right.
-->
These variables will act as the defaults if the machine does not explicitly set them.<br> These variables will act as the defaults if the machine does not explicitly set them.<br>
Please refer to the [dotenv documentation](https://github.com/motdotla/dotenv) for more details. Please refer to the [dotenv documentation](https://github.com/motdotla/dotenv) for more details.
......
...@@ -11,8 +11,11 @@ ...@@ -11,8 +11,11 @@
# misc # misc
.DS_Store .DS_Store
.env .env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment