I need to run React in production mode, which presumably entails defining the following somewhere in the enviornment:
process.env.NODE_ENV = \'production\';
Similar to the other answers, but hopefully gives someone a starting point:
var vendorList = ['react', 'react-dom'];
gulp.task('vendor-dev', function() {
browserify()
.require(vendorList)
.bundle()
.on('error', handleErrors)
.pipe(source('vendor.js'))
.pipe(gulp.dest('./build/dev/js'));
});
gulp.task('vendor-production', function() {
process.env.NODE_ENV = 'production';
browserify()
.require(vendorList)
.bundle()
.on('error', handleErrors)
.pipe(source('vendor.js'))
.pipe(buffer())
.pipe(uglify({ mangle: false }))
.pipe(gulp.dest('./build/production/js'));
});
The main difference is I am explicitly setting the NODE_ENV prior to bundling the vendor libraries. Gulp tasks aren't guaranteed to run in order.
Am I running in production mode?
If you remove the uglify line (and prior buffer) you will notice that both the dev and production builds are near identical in size - and match in line count.
The difference is the production version will be littered with:
"production" !== "production" ? [show dev error] : [no nothing]
Most reputable minify'ers (I believe) will strip out deadend code, such as the above, which will always result in false.
But really how do I tell?
Easiest method to be sure, would be goto the console of your running application and type:
React.createClass.toString();
The output should be:
"function (e){var t=function(e,t,n){this.__reactAutoBindMap&&c(this),"[....and more and more]
If you find the createClass in the react source, you will see:
createClass: function (spec) {
var Constructor = function (props, context, updater) {
// This constructor is overridden by mocks. The argument is used
// by mocks to assert on what gets mounted.
if ("production" !== 'production') {
"production" !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: react-legacyfactory') : undefined;
}
// Wire up auto-binding
if (this.__reactAutoBindMap) {
bindAutoBindMethods(this);
}
Notice how the console output skips straight through to this.__reactAutobind
, because you are running in production mode, and using an minify'er, all the !== 'production' warngins and checks have been skipped over.
Unfortunately none of the above answers work, because setting process.env.NODE_ENV
has no effect in Browserify. The resulting bundle still has process.env.NODE_ENV
references in it and hence
require()
the React production version modules,This is unfortunately not the only place where this approach is offered as the correct answer :-(
The correct approach can be found in e.g.
You need to switch the envify transform to be a global one, e.g.
# note the "-g" instead of the usual "-t"
$ browserify ... -g [ envify --NODE_ENV production ] ....
or in gulpfile.js
browserify(...)
...
.transform('envify', {
global: true, // also apply to node_modules
NODE_ENV: debug ? 'development' : 'production',
})
...
.bundle()
...
.pipe(gulpif(!debug, babelMinify())) // my example uses gulp-babel-minify
...
Step I: Add the following to your gulpfile.js somewhere
gulp.task('apply-prod-environment', function() {
process.env.NODE_ENV = 'production';
});
Step II: Add it to your default task (or whichever task you use to serve/build your app)
// before:
// gulp.task('default',['browsersync','watch'], function() {});
// after:
gulp.task('default',['apply-prod-environment', 'browsersync','watch'], function() {});
OPTIONAL: If you want to be ABSOLUTELY CERTAIN that you are in prod mode, you can create the following slightly enhanced task instead of the one in Step I:
gulp.task('apply-prod-environment', function() {
process.stdout.write("Setting NODE_ENV to 'production'" + "\n");
process.env.NODE_ENV = 'production';
if (process.env.NODE_ENV != 'production') {
throw new Error("Failed to set NODE_ENV to production!!!!");
} else {
process.stdout.write("Successfully set NODE_ENV to production" + "\n");
}
});
Which will throw the following error if NODE_ENV is ever not set to 'production'
[13:55:24] Starting 'apply-prod-environment'...
[13:55:24] 'apply-prod-environment' errored after 77 μs
[13:55:24] Error: Failed to set NODE_ENV to production!!!!
To set React in production mode you need to set your NODE_ENV variable to production and uglify your JS as an extra step.
You're already taking care of the uglification, for setting your NODE_ENV variable :
NODE_ENV='production' gulp
gulp.task('set-production-env', function() {
return process.env.NODE_ENV = 'production';
});
Also you may use handy way with gulp-environments
:
var environments = require('gulp-environments');
var production = environments.production;
gulp.src(paths.js)
.pipe(concat("app.js"))
// only minify the compiled JS in production mode
.pipe(production(uglify()))
.pipe(gulp.dest("./public/app/js/"));
To run gulp in production mode:
gulp build --env=production