Search code examples
browserifybabeljsreactjs

Using Babelify to compile React results in React Router being undefined


I'm using Gulp for my build system, with Browserify for compiling my JS. I had been using Reactify for JSX compilation, but thought I'd switch to Babelify to get some additional ES2015 features. No errors are thrown when compiling, but when I load my site in the browser I get the following error in my JS console:

Uncaught ReferenceError: Router is not defined

The line the error is referring to is:

var React = require('react');

in the main component file that is being loaded on the page.

The places where I am importing React Router are in my App.jsx file (which is the entrypoint for the application) and my routes.jsx file, where I define the routes:

App.jsx

var React  = require('react'),
    Router = require('react-router'),
    routes = require('./routes.jsx');

Router.run(routes, function(Handler, state) {

    var routeClasses = '';
    for (var i = 1; i < state.routes.length; i++) {
        routeClasses += state.routes[i].name + ' ';
    }

  React.render(<Handler classes={routeClasses.trim()} />, document.getElementById('root'));
});

routes.jsx

var React        = require('react');
    Router       = require('react-router'),
    Route        = Router.Route,
    DefaultRoute = Router.DefaultRoute,
    App          = require('./_layout/App.jsx'),
    Editor       = require('./editor/Editor.jsx');

module.exports = (
  <Route name="app" path="/" handler={App}>
    <DefaultRoute name="editor" handler={Editor} />
  </Route>
);

Everything was working fine when using Reactify rather than Babelify. I'm using Gulp for my build process:

gulp.task('js', function() {
  var browserify = require('browserify'),
      watchify   = require('watchify'),
      minifyify  = require('minifyify'),
      babelify   = require('babelify');

  function bundle() {
    b.bundle()
      .on('error', function(error){
        gutil.log(error);
      })
      .pipe(source('app.js'))
      .pipe(gulp.dest(paths.client.js.build))
      .pipe(gulpif(!isStartup, browserSync.stream()));

    isStartup = false;
  }

  var map = isProd ? false : 'app.map.json';

  var b = browserify({
    cache: {},
    packageCache: {},
    entries: paths.client.js.dev,
    debug: true,
    plugin: [watchify]
  })
  .transform(babelify, {presets: ['es2015', 'react']})

  .plugin('minifyify', {
    map: map,
    output: paths.client.js.build + 'app.map.json',
  });

  b.on('update', function(){
    bundle();
  });

  b.on('log', gutil.log); // output build logs to terminal
  bundle();
});

The working version, using Reactify, simply omits the .transform(babelify...) line and adds transform: reactify to the browserify() initialization code, i.e.

  var b = browserify({
    cache: {},
    packageCache: {},
    entries: paths.client.js.dev,
    debug: true,
    transform: reactify,
    plugin: [watchify]
  });

Solution

  • It's working with es2015 import X from Y syntax, e.g.

    import React from 'react'