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

add webpack-env-define-plugin package #1030

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions packages/react-scripts/config/env.js

This file was deleted.

23 changes: 18 additions & 5 deletions packages/react-scripts/config/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
var getClientEnvironment = require('./env');
var EnvDefinePlugin = require('webpack-env-define-plugin');
var paths = require('./paths');

// Webpack uses `publicPath` to determine where the app is being served from.
Expand All @@ -26,8 +26,6 @@ var publicPath = '/';
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
var publicUrl = '';
// Get environment variables to inject into our app.
var env = getClientEnvironment(publicUrl);

// This is the development configuration.
// It is focused on developer experience and fast rebuilds.
Expand Down Expand Up @@ -196,8 +194,23 @@ module.exports = {
template: paths.appHtml,
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
new webpack.DefinePlugin(env),
// if (process.env.NODE_ENV === 'development') { ... }.
new EnvDefinePlugin({
// Grab REACT_APP_* environment variables
regex: /^REACT_APP_/i,
customVariables: {
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
'NODE_ENV': JSON.stringify(
process.env.NODE_ENV || 'development'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to read process.env.NODE_ENV here at all. We don't allow overriding it. So we can just pass 'development'.

),
// Useful for resolving the correct path to static assets in `public`.
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
'PUBLIC_URL': JSON.stringify(publicUrl)
}
}),
// This is necessary to emit hot updates (currently CSS only):
new webpack.HotModuleReplacementPlugin(),
// Watcher doesn't work well if you mistype casing in a path so we use
Expand Down
29 changes: 18 additions & 11 deletions packages/react-scripts/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var ManifestPlugin = require('webpack-manifest-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var url = require('url');
var paths = require('./paths');
var getClientEnvironment = require('./env');
var EnvDefinePlugin = require('webpack-env-define-plugin');

function ensureSlash(path, needsSlash) {
var hasSlash = path.endsWith('/');
Expand All @@ -45,14 +45,6 @@ var publicPath = ensureSlash(homepagePathname, true);
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
var publicUrl = ensureSlash(homepagePathname, false);
// Get environment variables to inject into our app.
var env = getClientEnvironment(publicUrl);

// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if (env['process.env'].NODE_ENV !== '"production"') {
throw new Error('Production builds must have NODE_ENV=production.');
}

// This is the production configuration.
// It compiles slowly and is focused on producing a fast and minimal bundle.
Expand Down Expand Up @@ -228,10 +220,25 @@ module.exports = {
}
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// if (process.env.NODE_ENV === 'production') { ... }.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env),
new EnvDefinePlugin({
// Grab REACT_APP_* environment variables
regex: /^REACT_APP_/i,
customVariables: {
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
'NODE_ENV': JSON.stringify(
process.env.NODE_ENV || 'production'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Just pass 'production'?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'd need to update comments to make sense after the changes.

),
// Useful for resolving the correct path to static assets in `public`.
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
'PUBLIC_URL': JSON.stringify(publicUrl)
}
}),
// This helps ensure the builds are consistent if source hasn't changed:
new webpack.optimize.OccurrenceOrderPlugin(),
// Try to dedupe duplicated modules, if any:
Expand Down
1 change: 1 addition & 0 deletions packages/react-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"url-loader": "0.5.7",
"webpack": "1.13.2",
"webpack-dev-server": "1.16.2",
"webpack-env-define-plugin": "1.0.0",
"webpack-manifest-plugin": "1.1.0",
"whatwg-fetch": "1.0.0"
},
Expand Down
46 changes: 46 additions & 0 deletions packages/webpack-env-define-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# webpack-env-define-plugin

This package includes a webpack plugin used by [Create React App](https://github.com/facebookincubator/create-react-app).
The plugin grabs environment variables that follows a specified regex and injects them into the application using the
webpack DefinePlugin.
In addition, the plugin allows defining custom environment variables to be injected.

## Usage in Create React App Projects

See [webpack.config.dev.js](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpack.config.dev.js#L200) and [webpack.config.prod.js](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpack.config.prod.js#L234).

## Usage Outside of Create React App

If you want to use this webpack plugin in a project not built with Create React App, you can install it with following steps.

First, install this package.

```
npm install --save-dev webpack-env-define-plugin
```

Then reference it in your webpack config:

```js
var EnvDefinePlugin = require('../../webpack-env-define-plugin');
```

and define it as a plugin in the webpack config plugin section:

```js
plugins: [
...
new EnvDefinePlugin({
// Grab MY_PREFIX_* environment variables
regex: /^MY_PREFIX_/i,
customVariables: {
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
'MY_ENV_VAR': JSON.stringify(
process.env.MY_ENV_VAR || 'default'
)
}
}),
...
]
```
51 changes: 51 additions & 0 deletions packages/webpack-env-define-plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';

const DefinePlugin = require('webpack').DefinePlugin;

/**
* Webpack plugin to inject environment variables that pass a regex test. The plugin also support
* custom variables by passing them in the options argument
*
* @param {Object} options - The plugin configuration
* @param {string} options.regex - The regex to select the environment variables by
* @param {Object.<string, string>} options.customVariables - A map that its keys are the
* custom injected environment
* variable names and its values are the variable values
* @constructor - Returns a new EnvDefinePlugin instance
*/
function EnvDefinePlugin(options) {
this.regex = options.regex || /.*/;
this.customVariables = options.customVariables || {};
}

/**
* Grabs environment variables that meets the regex test and prepare them to be injected into the
* application via DefinePlugin in Webpack configuration.
* @param {string} regex - The regex to select the environment variables by
* @param {Object.<string, string>} customVariables - A map where its keys are the custom injected environment
* @returns {{[process.env]: *}} - A DefinePlugin configuration
*/
function getClientEnvironment(regex, customVariables) {
const processEnv = Object
.keys(process.env)
.filter(key => regex.test(key))
.reduce((env, key) => {
env[key] = JSON.stringify(process.env[key]);
return env;
}, customVariables);
return { 'process.env': processEnv };
}

EnvDefinePlugin.prototype.apply = function(compiler) {
compiler.apply(new DefinePlugin(getClientEnvironment(this.regex, this.customVariables)));
};

module.exports = EnvDefinePlugin;
21 changes: 21 additions & 0 deletions packages/webpack-env-define-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add yourself as a contributor to the package.json. See http://browsenpm.org/package.json#contributors for details.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

"name": "webpack-env-define-plugin",
"version": "1.0.0",
"description": "Webpack plugin to inject environment variables that meet a specificed pattern",
"main": "index.js",
"repository": "facebookincubator/create-react-app",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/facebookincubator/create-react-app/issues"
},
"dependencies": {
"webpack": "^1.13.3"
},
"contributors": [
{
"name": "Ron Meldiner",
"email": "[email protected]",
"url": "https://github.com/meldiner"
}
]
}
1 change: 1 addition & 0 deletions tasks/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ npm link $root_path/packages/babel-preset-react-app
npm link $root_path/packages/eslint-config-react-app
npm link $root_path/packages/react-dev-utils
npm link $root_path/packages/react-scripts
npm link $root_path/packages/webpack-env-define-plugin

# Test the build
npm run build
Expand Down