I'm using browserify-rails + babelify to transpile jsx in a react + rails project.
I'm very puzzled why // require('');
is needed in components.js
(which is the mounting point of react) for the jsx transpilation to work.
If I delete the line of comment // require('');
, I would get "SyntaxError: Unexpected token import"
Currently I have no leads as why would a line of comment affect the transpilation. I'm also puzzled about if this is a problem of react, or babelify, or browserify, or browserify-rails, or rails asset pipeline.
Please refer to https://github.com/sidazhou/react_rails_skeleton/tree/v0.0.1 for the full code base
components.js
// require(''); // somehow this is necessary, why?! Otherwise we get: "SyntaxError: Unexpected token import"
import React from 'react';
import ReactDOM from 'react-dom';
import Widgets from './components/Widgets.jsx';
ReactDOM.render( <Widgets />, document.getElementById('react_component') );
package.json
{
"name": "react-sample",
"dependencies": {
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babelify": "^7.2.0",
"browserify": "^12.0.1",
"browserify-incremental": "^3.0.1",
"history": "^1.13.1",
"material-ui": "^0.13.4",
"react": "^0.14.3",
"react-dom": "^0.14.3",
"react-router": "^1.0.2",
"react-tap-event-plugin": "^0.2.1"
},
"engines": {
"node": ">= 0.10"
}
}
application.rb
config.browserify_rails.commandline_options = "-t [ babelify --presets [ es2015 react ] ]"
There is an open issue for browserify-rails
about that:
#124 transforms are only applied to files loaded with require()
.
I'm trying to summarize the thread by quoting some of cymen posts that I think are relevant (he's the author of browserify-rails).
cymen commented on 10 Dec 2015:
One hack to try to debug it is to put a comment in your source that is
// require
or// module.exports
. Does that solve it? We would of course want to add a proper fix of detecting es6 (import, etc).
cymen commented on 18 Dec 2015
After rereading your initial post, the simple solution is to just have application.js require the application and kick it off -- just don't use ES6 or anything in it. That will get you where you want without a lot of messing around. Later on, when you're off the asset pipeline (ideally), you'll have more control over the compilation and can refactor it back into the main file if that is what you want. But why fight such a minor problem?
mockdeep(he opened the issue) commented on 18 Dec 2015:
Yeah, we're doing that. We've just got a couple of globals defined in application.js at this point. It's just a surprising issue, and won't necessarily surface if you test on Chrome or Firefox, since they both support a bunch of ES6 features.
Why would we want to get off the asset pipeline, though? Seems like it provides some pretty solid value in terms of precompiling assets.
cymen commented on 18 Dec 2015:
Because the asset pipeline is becoming an anti-pattern. The only reason browserify-rails exists is because the asset pipeline is keeping JavaScript development about -5 or so years from current best practices. While browserify-rails will work, at a certain point, it's much easier to just go directly to browserify or webpack.
So my perspective is that browserify-rails is best to migrate from legacy JavaScript to CommonJS and then jump off the asset pipeline.
But everyone is free to use it as they see fit of course. There is some benefit to hooking up a page refresh to an asset build. For Ruby developers used to working with Rails, that simple "this is the way it works" makes sense. Although with a Procfile, it's not hard to kick off webpack/browserify watching the assets and recompiling as needed. So I understand there are a variety of use cases.
cymen commented on 18 Dec 2015:
I switched employers and am now using webpack directly (which I like -- a prior engineer made that choice and it's working fine, I think browserify is good too). But I'm working on client-side web applications so our backend is typically Ruby-based APIs running Sinatra (with NodeJS to do some service-side rendering).
My prior employer was using browserify-rails for a while but I think they have jumped off the asset pipeline. I'm not sure (I haven't had a chance yet to talk about it in detail with those still working on that project).
One of the issues was the time to run browserify-rails was taking longer particularly on lower end MacBooks (Airs, older 13). With browserify-rails 2.x, I think we have a much better chance of keeping performance high if we can work around the issues with using Sprockets directly instead of using Tilt as an intermediary (as we do on browserify-rails 1.x). In fact, the Sprockets caching should be good enough that we can potentially get rid of browserify-incremental (which is caching browserify builds to try to keep performance up -- but now with 2.x we have caching in Sprockets and caching in browserify-incremental which is likely too complex).
That was his last comment on the issue (3 months ago). So that workaround you already have is the best solution available at this moment (until someone implements ES6 detection in browserify-rails).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With