21

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?

4
  • 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). Commented Jun 12, 2014 at 19:25
  • 1
    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. Commented Jun 13, 2014 at 14:19
  • 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/… Commented Jun 20, 2014 at 14:34
  • Did using browserify with vinyl-source stream improve your workflow? Commented Jul 11, 2014 at 2:59

7 Answers 7

12

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!

Sign up to request clarification or add additional context in comments.

6 Comments

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?
Hm, you might have to bind it? [reactify.bind(null, {harmony: true}]. Glad it helped out :-)
Not sure what the diff between your /app/main.js and main.js is... Are they different files?
Giving out your package.json for this would be great.
Check out the article mentioned :-) It also has a boilerplate with all you need
|
8

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.

Comments

2

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']);

Comments

1

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']); 

Comments

0

I don't see directly what is wrong with your code, but I'm using this

gulp.src('./src/js/index.js') .pipe(browserify()) .on('prebundle', function(bundle) { // React Dev Tools tab won't appear unless we expose the react bundle bundle.require('react'); }) .pipe(concat('bundle.js'))

I used https://www.npmjs.org/package/gulp-react to transform the .jsx but nowadays I prefer to use regular javascript.

Let me know if this works for you, if not I could extract an example template...

1 Comment

This code fails with the error TypeError: Object #<Browserify> has no method 'pipe'
0

package.json:

{ "devDependencies": { "gulp": "^3.8.11", "gulp-browserify": "^0.5.1", "reactify": "^1.1.0" }, "browserify": { "transform": [["reactify", { "es6": true }]], "insertGlobals": true, "debug": true } } 

gulpfile.js:

var gulp = require('gulp'); var browserify = require('gulp-browserify'); gulp.task('browserify', function() { return gulp.src("./assets/index.js") .pipe(browserify()) .pipe(gulp.dest("./www/assets")); }); 

1 Comment

It is not recommended to use gulp-browserify since it is currently blacklisted. You are better off using the browserify package instead.
0

Define

React=require('react'); ReactDOM = require('react-dom'); 

those global javascript value in a App.js, than put this

var stream = require('vinyl-source-stream'); var browserify = require('browserify'); browserify(source + '/app/app.js') // bundles it and creates a file called main.js .bundle() .pipe(stream('main.js')) // saves it the dest directory .pipe(gulp.dest(destination +'/assets/js')); 

in Gulpfile.js.

And for last, put main.js in HTML, and it should work.

The problem is if we use var React=require('react'), the object React is not visible from other script, but React=require('react') define a global value.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.