1
votes

I have been working on converting a grunt task to gulp. The grunt file looks like this:

 browserify: {
     options: {
         transform: [ require('grunt-react').browserify ]
     },
     client: {
         src: ['react/**/*.jsx'],
         dest: 'public/js/browserify/bundle.js'
     }
}

I saw many examples of browserify and gulp but all of them had just a single file start point. To get round this I tried using glob. After several false starts I came up with the following. It runs without error and creates a single bundle.js file, but reactify doesn't seem to be working correctly, as jsx does not seem to be converted so I end up with the error:

Uncaught Error: Cannot find module './components/NoteApp.jsx'

var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var glob = require('glob');
var reactify = require('reactify');

gulp.task('browserify', function (cb) {
  glob('./react/**/*.jsx', {}, function (err, files) {
    var b = browserify();

    files.forEach(function (file) {
      b.add(file);
    });

    b.transform(reactify);

    b.bundle()
      .pipe(source('bundle.js'))
      .pipe(gulp.dest('./public/js/browserify/'));
    cb();
  }); 
});

ddprrt requested some further details on structure so here is how the react folder is laid out. The code is taken from this article which uses this github zip source to demonstrate react and reflux. The project was very close to what I needed as a start point but uses Grunt instead of Gulp.

The react folder is structured like this:

react \ App.jsx \ Bootstrap.jsx \ components \ NoteApp.jsx \ NoteCreationBox.jsx \ Note.jsx \ NoteListBox.jsx \ NoteList.jsx \ TextArea.jsx

The error is coming from a line in the App.jsx file:

var React = require('react');
var NoteApp=require('./components/NoteApp.jsx');

but changing this line causes the gulp talk to fail with a missing file error.

1
I tried to recreate the sample with some basic files, and it worked like a charm. Can you show us how your files are structured? I kinda puzzles me that you take all jsx files in the "react" folder, but NoteApp.jsx is not in that folder. Maybe there's some path problems going on.ddprrt
@ddprrt Thanks for the reply, I have updated my question with further details on the structure.Finglish
I compiled said project with your code, and still works perfectly well. Guess we have to go deeper: What OS do you use? I'm thinking of case-sensitivity which might occur on your system, but didn't on the original author's (also weird, because Grunt seems to work, doesn't it?)ddprrt
Yes, Grunt worked without a problem. Gulp compiles ok, but when I start the project and test it in a browser then I get the Cannot find module './components/NoteApp.jsx'. I am running this on an Ubuntu 14.04 Digital Ocean cloud server with Nginx.Finglish
Ah, now I get you. I see that the bundles from Grunt and Gulp are different when compared to each other in different parts. Be checking the version numbers now...ddprrt

1 Answers

1
votes

I guess I got the answer now. It was really some version mixup, reactify seems to be more advanced and handle things differently than the reactify in the original did. Might be because both are still in experimental state. I also guess that React/Reflux moved on, so you ended up with some versions which didn't quite comply. However, you still can fix it and run you app:

var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var glob = require('glob');
var reactify = require('grunt-react').browserify;

gulp.task('browserify', function (cb) {
    glob('./react/Bootstrap.jsx', function (err, files) {
        var b = browserify({
            entries: files
        }).transform(reactify)
        .bundle()
        .pipe(source('bundle.js'))
        .pipe(gulp.dest('./public/js/browserify/'));
        cb();
    }); 
});

Instead of using require('reactify'), we take the reactify provided by grunt-react. See the code above. You should just be able to switch the middleware. Also, don't go over all the files, just your main entry point, which is in that case Bootstrap.jsx.

I know that this is rather inconvenient, maybe when you try your own app, start with a fresh setup.

** Update**

that was my package.json afterwards, just working into the previous project:

{
  "name": "react-note-app",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "main": "./bin/www"
  },
  "engines": {
    "node": ">= 0.10.0"
  },
  "dependencies": {
    "body-parser": "~1.8.1",
    "cookie-parser": "~1.3.3",
    "debug": "~2.0.0",
    "ejs": "~0.8.5",
    "express": "~4.9.0",
    "express-session": "^1.8.2",
    "morgan": "~1.3.0",
    "node-jsx": "^0.11.0",
    "react": "^0.11.2",
    "reflux": "^0.1.13",
    "serve-favicon": "~2.1.3"
  },
  "devDependencies": {
    "browserify": "^9.0.7",
    "glob": "^5.0.3",
    "grunt": "^0.4.5",
    "grunt-browserify": "^3.0.1",
    "grunt-contrib-watch": "^0.6.1",
    "grunt-nodemon": "^0.3.0",
    "grunt-react": "^0.9.0",
    "gulp": "^3.8.11",
    "react-tools": "^0.11.2",
    "reactify": "^1.1.0",
    "vinyl-source-stream": "^1.1.0"
  }
}