Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set React to production mode when using Gulp

I need to run React in production mode, which presumably entails defining the following somewhere in the enviornment:

process.env.NODE_ENV = 'production'; 

The issue is that I'm running this behind Tornado (a python web-server), not Node.js. I also use Supervisord to manage the tornado instances, so it's not abundantly clear how to set this in the running environment.

I do however use Gulp to build my jsx files to javascript.

Is it possible to somehow set this inside Gulp? And if so, how do I check that React is running in production mode?

Here is my Gulpfile.js:

'use strict';  var gulp = require('gulp'),         babelify = require('babelify'),         browserify = require('browserify'),         browserSync = require('browser-sync'),         source = require('vinyl-source-stream'),         uglify = require('gulp-uglify'),         buffer = require('vinyl-buffer');  var vendors = [     'react',     'react-bootstrap',     'jquery', ];  gulp.task('vendors', function () {         var stream = browserify({                         debug: false,                         require: vendors                 });          stream.bundle()                     .pipe(source('vendors.min.js'))                     .pipe(buffer())                     .pipe(uglify())                     .pipe(gulp.dest('build/js'));          return stream; });  gulp.task('app', function () {         var stream = browserify({                         entries: ['./app/app.jsx'],                         transform: [babelify],                         debug: false,                         extensions: ['.jsx'],                         fullPaths: false                 });          vendors.forEach(function(vendor) {                 stream.external(vendor);         });          return stream.bundle()                                  .pipe(source('build.min.js'))                                  .pipe(buffer())                                  .pipe(uglify())                                  .pipe(gulp.dest('build/js'));  });  gulp.task('watch', [], function () {     // gulp.watch(['./app/**/*.jsx'], ['app', browserSync.reload]);     gulp.watch(['./app/**/*.jsx'], ['app']); });  gulp.task('browsersync',['vendors','app'], function () {         browserSync({             server: {                 baseDir: './',             },             notify: false,             browser: ["google chrome"]     }); });  gulp.task('default',['browsersync','watch'], function() {}); 
like image 634
vgoklani Avatar asked Sep 11 '15 14:09

vgoklani


People also ask

Can you use gulp With react?

ReactJs is one of the most trending Javascript libraries open-sourced by Facebook for creating fluent apps. ReactJs makes most of ECMAScript6 specification and hence the need for transforming the code into something that can run across browsers/devices, this is where Gulp comes to the rescue.

What is production mode in react?

The production build creates minified bundles, lighter-weight source maps, and optimized assets. This improves the load time. React recommends using production mode while deploying the react app. We now know that production build helps in optimizing performance.


2 Answers

2017 - Edit: anyone trying to set up React in Gulp for a new project: Just use create-react-app


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!!!! 
like image 153
Monarch Wadia Avatar answered Sep 24 '22 13:09

Monarch Wadia


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.

like image 37
Chris Avatar answered Sep 20 '22 13:09

Chris