Using gulp-browserify for my React.js modules I'm getting 'require is not defined' in the browser

32,184

Solution 1

UPDATE: I wrote a new post on this, using different packaging tools. It also includes an optimized example of browserify: Choosing the correct packaging tool for React JS

To anyone reading this post to get a React JS workflow up and running:

I had a lot of issues getting this to work, and ended up writing a post on it: React JS and a browserify workflow. This is my solution, making sure that you can transform your JSX and handle separate watching of other files.

var gulp = require('gulp');
var source = require('vinyl-source-stream'); // Used to stream bundle for further handling etc.
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify'); 
var concat = require('gulp-concat');

gulp.task('browserify', function() {
    var bundler = browserify({
        entries: ['./app/main.js'], // Only need initial file, browserify finds the deps
        transform: [reactify], // We want to convert JSX to normal javascript
        debug: true, // Gives us sourcemapping
        cache: {}, packageCache: {}, fullPaths: true // Requirement of watchify
    });
    var watcher  = watchify(bundler);

    return watcher
    .on('update', function () { // When any files update
        var updateStart = Date.now();
        console.log('Updating!');
        watcher.bundle() // Create new bundle that uses the cache for high performance
        .pipe(source('main.js'))
        // This is where you add uglifying etc.
        .pipe(gulp.dest('./build/'));
        console.log('Updated!', (Date.now() - updateStart) + 'ms');
    })
    .bundle() // Create the initial bundle when starting the task
    .pipe(source('main.js'))
    .pipe(gulp.dest('./build/'));
});

// I added this so that you see how to run two watch tasks
gulp.task('css', function () {
    gulp.watch('styles/**/*.css', function () {
        return gulp.src('styles/**/*.css')
        .pipe(concat('main.css'))
        .pipe(gulp.dest('build/'));
    });
});

// Just running the two tasks
gulp.task('default', ['browserify', 'css']);

To solve the issue of using the React JS DEV-TOOLS in chrome, this is what you have to do in your main.js file:

/** @jsx React.DOM */

var React = require('react');
// Here we put our React instance to the global scope. Make sure you do not put it 
// into production and make sure that you close and open your console if the 
// DEV-TOOLS does not display
window.React = React; 

var App = require('./App.jsx');
React.renderComponent(<App/>, document.body);

I hope this will help you get going!

Solution 2

Run browserify directly on your file, and don't use use gulp-browserify plugin.

Referenced here: https://github.com/gulpjs/plugins/issues/47

"Browserify should be used as a standalone module. It returns a stream and figures out your dependency graph. If you need vinyl objects, use browserify + vinyl-source-stream"

you can achieve the results you want like this:

var source = require('vinyl-source-stream'), //<--this is the key
    browserify = require('browserify');

    function buildEverything(){
        return browserify({
               //do your config here
                entries: './src/js/index.js',
            })
            .bundle()
            .pipe(source('index.js')) //this converts to stream
             //do all processing here.
             //like uglification and so on.
            .pipe(gulp.dest('bundle.js'));
        }
    }

    gulp.task('buildTask', buildEverything);

now, in your package Json,as you have - require react, browsierify and so on. You can also shim browserify here, use transforms or whatever.

  "dependencies": {
    "react": "^0.10.0",  
  },
  "devDependencies": {
     "browserify": "3.46.0",
    "browserify-shim": "3.x.x",
   }
  "browserify": {
    "transform": [
      "browserify-shim"
    ]
  },
  "browserify-shim": {
     "react": "React", 
  }

or jsut do like you are, and include react on the page you use it

var React = require('react');

or this if you want some of the handy helper stuff:

var React = require('react/addons');

But the bottom line is to use browserify directly in gulp and use the vinyl-source-stream to get into gulp pipeline.

Solution 3

I use this one for my react work .

var gulp = require('gulp');
var source = require('vinyl-source-stream'); 
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify'); 
var concat = require('gulp-concat');
 
gulp.task('browserify', function() {
    var bundler = browserify({
        entries: ['./assets/react/main.js'], 
        transform: [reactify],
        debug: true, 
        cache: {}, packageCache: {}, fullPaths: true 
    });
    var watcher  = watchify(bundler);

    return watcher
    .on('update', function () { 
        var updateStart = Date.now();
        console.log('Updating!');
        watcher.bundle() 
        .pipe(source('main.js'))
    
        .pipe(gulp.dest('./assets/js/'));
        console.log('Updated!', (Date.now() - updateStart) + 'ms');
    })
    .bundle() 
    .pipe(source('main.js'))
    .pipe(gulp.dest('./assets/js/'));
});



gulp.task('default', ['browserify']);

Solution 4

Here's the gulp recipe for using browserify (with vinyl-transform and friends) to achieve the exact equivalent of

browserify -t reactify -r react -r ./src/App > ../webapp/static/bundle.js`

in src/App.js

/** @jsx React.DOM */
var React = require('react');

var App = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}!</h1>;
  }
});

module.exports = App;

in gulpfile.js

var gulp = require('gulp');
var browserify = require('browserify');
var transform = require('vinyl-transform');
var reactify = require('reactify');
var rename = require("gulp-rename");

gulp.task('build', function () {

  // browserify -t reactify -r react -r ./src/App > ../webapp/static/bundle.js

  var browserified = transform(function(filename) {
    return browserify()

      // -t reactify
      .transform(reactify)

      // -r react
      // update below with the correct path to react/react.js node_module
      .require('./node_modules/react/react.js', { expose: 'react'})

      // -r ./src/App
      // filename = <full_path_to>/src/App.js
      .require(filename, {expose: 'src/App'})
      .bundle();
  });
  return gulp.src('./src/App.js')
    .pipe(browserified)
    .pipe(rename('bundle.js'))
    .pipe(gulp.dest('../webapp/static/'));
});

gulp.task('default', ['build']);
Share:
32,184

Related videos on Youtube

asolberg
Author by

asolberg

Updated on July 09, 2022

Comments

  • asolberg
    asolberg almost 2 years

    I'm trying to use gulp-browserify to generate a bundle.js file that can be included to the client's browser and begin rendering React components.

    Here is my App.js file:

    /** @jsx React.DOM */
    var React = require('react');
    
    var App = React.createClass({
      render: function() {
        return <h1>Hello {this.props.name}!</h1>;
      }
    });
    
    module.exports = App;
    

    And my package.json:

      "name":"hellosign-gulp",
      "version":"0.1.1",
      "dependencies": {
        "gulp": "3.5.x",
        "gulp-browserify": "0.5.0",
        "reactify": "~0.8.1",
        "react": "^0.10.0",
        "gulp-react": "0.2.x"
      }
    }
    

    and my gulpfile

    var   gulp = require('gulp'),
      react = require('gulp-react'),
      browserify = require('gulp-browserify');
    
    
    gulp.task('brow-test', function() {
        // Single entry point to browserify
        gulp.src('./src/App.js', {read: false})
            .pipe(browserify({
              insertGlobals : true,
              transform: ['reactify'],
              extensions: ['.jsx'],
              debug :false.
            }))
            .pipe(gulp.dest('.'))
    });
    

    Now when I run 'brow-test' I rename the output file to bundle.js and include it with the HTTP response for the browser. The bundle.js file is quite large so I won't include it here but the browser ends up throwing an error

    Uncaught ReferenceError: require is not defined

    I have this exact same setup running correctly with the regular version of browserify using these commands

    browserify -t reactify -r react -r ./src/App > ../webapp/static/bundle.js
    

    And then I don't get the error. Why is gulp-browserify not creating the require shim correctly?

    • Brigand
      Brigand almost 10 years
      I don't believe the setup is the same because you do -r react -r ./src/App on the command line, (not very familiar with gulp).
    • David Hellsing
      David Hellsing almost 10 years
      You can run the regular browserify in gulp using vinyl-source-stream and gulp-buffer. That’s what we do because the gulp-browserify never worked good enough for us.
    • asolberg
      asolberg almost 10 years
      I still can't get the global require to get exposed. I simplified the problem and posted a new question here: stackoverflow.com/questions/24329690/…
    • the_5imian
      the_5imian almost 10 years
      Did using browserify with vinyl-source stream improve your workflow?
  • asolberg
    asolberg almost 10 years
    This code fails with the error TypeError: Object #<Browserify> has no method 'pipe'
  • Con Antonakos
    Con Antonakos about 9 years
    It is not recommended to use gulp-browserify since it is currently blacklisted. You are better off using the browserify package instead.
  • David Tinker
    David Tinker almost 9 years
    I am using your post in my project, thanks! I am struggling to figure out how to get reactify to accept harmony jsx stuff. I tried transform: [[reactify, {"harmony": true}]] .. no luck?
  • christianalfoni
    christianalfoni almost 9 years
    Hm, you might have to bind it? [reactify.bind(null, {harmony: true}]. Glad it helped out :-)
  • Alexander Suraphel
    Alexander Suraphel almost 9 years
    Not sure what the diff between your /app/main.js and main.js is... Are they different files?
  • Alexander Suraphel
    Alexander Suraphel almost 9 years
    Giving out your package.json for this would be great.
  • christianalfoni
    christianalfoni almost 9 years
    Check out the article mentioned :-) It also has a boilerplate with all you need
  • Tjorriemorrie
    Tjorriemorrie over 8 years
    Are we to use the babelify transformer now?