Envify CLI not removing process.env.NODE_ENV

928 views Asked by At

I am trying to reduce the size of my React bundle.js.

I am attempting to use Envify with Browserify to replace process.env.NODE_ENV with the string "production", in order to use uglifyjs and remove all the extra development code.

Here is my command: browserify -t [envify --NODE_ENV production] assets/js/app.js -o assets/js/bundle.js

So my bundle.js is successfully created, but it still has some of the instances of process.env.NODE_ENV.

All the instances that are in my "app.js" or my other components are correctly replaced with "production".

...But in all of my required modules from the node_modules folder (like react etc), the instances are not replaced.

Any help greatly appreciated! THX!

******************* Edit **********************

JMM's solution successfully answered the original question, but I still had an issue because I am using React-Router (I think).

I created a simple example that shows the situation.

Here is my app.js file:

var React = require('react');           
var ReactDOM = require('react-dom');
var Router = require('react-router').Router; 
var Route = require('react-router').Route;

var Example = React.createClass({
    render: function(){
        console.log(process.env.NODE_ENV);
        if (process.env.NODE_ENV === "development") { 
          console.log('Development Version');
        } else {
            console.log('Production Version');
        }
        return <span>Hello World!</span>;
    }
});

var AppRoutes = ( <Route name="/" path="/" component={Example} /> );


ReactDOM.render(
    (<Router>
        {AppRoutes}
    </Router>), 
    document.getElementById('ExampleApp')
    );

If I run NODE_ENV=production browserify -t envify assets/js/app.js -o assets/js/bundle.js, I still have some instances of process.env.NODE_ENV in the bundle.js.

I found a work-around by simply creating the bundle.js with: browserify assets/js/app.js -o assets/js/bundle.js, and then running envify on the bundle with: NODE_ENV=production envify assets/js/bundle.js > assets/js/bundle2.js

This solves my problem, but I am still unsure why react-router doesn't allow browserify and envify to work together.

I hope this helps others with a similar problem!!

2

There are 2 answers

1
JMM On BEST ANSWER

Browserify doesn't run transforms on stuff in node_modules. However, React has envify (actually loose-envify now) configured in its package.json. I think the reason it's not working for you is passing the environment to envify as an option (again, your invocation of envify there is not running on React). The envify docs are not good about explaining how this works. To get the production build of React you should do:

NODE_ENV=production browserify -t envify assets/js/app.js -o assets/js/bundle.js

I believe this should cause envify to function as expected on your app code and React.

0
Stefan Becker On

Unfortunately JMM's answer doesn't 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

  • Browserify will not require() the React production version modules,
  • the minifier will not be able to remove dead code, and
  • the application will still be running in debug mode.

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
    ...