-
Notifications
You must be signed in to change notification settings - Fork 755
Using npm addons with react-rails #413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It would be great to add a section about this in README.md or on a wiki page. |
Not clear to me either how to use custom babel plugins :( |
You could use With If you decide to use browserify, just follow the gem installation instructions and setup your app like so: Using browserifyApplication.js Setup//= require_self
//= require components
//= require turbolinks
//= require react-server
//= require react_ujs
// Setup React in global scope
var React = window.React = global.React = require('react');
var ReactDOM= window.ReactDOM = global.ReactDOM = require('react-dom');
window.$ = window.jQuery = require('jquery')
require('jquery-ujs') Components.js// Setup app into global name space for server rendering
var app = window.app = global.app = {};
// Component::Manifest
var NoContent = require('./components/no_content.es6.js');
// Include into app namespace
app.NoContent = NoContent; Loading NPM modules// Require React
React = require('react/addons');
import component from './component.js'
import mui from 'material-ui';
// Your third party add-ons from react component
// Define component
const NoContent = React.createClass({
render() {
return (
<span className="no_content">
Empty content
</span>
);
},
});
module.exports = NoContent; # render in rails views
<%= react_component 'app.NoContent', {prerender: true} %> For Babel Plugins:From babel 6.0, there are no plugins included by default, you will have to use .babelrc file in project root (in this case rails root) to define presets and plugins like so or pass command line options:
You could also use react-rails configuration to load es6 functions or plugins like so:
# application.rb
config.react.jsx_transform_options = {
plugins: ['transform-class-properties']
} Make sure you install the plugin via npm There are others solutions like using: |
@gauravtiwari in you application.js file, why is it needed to require react via sprockets ? Wouldn't that load react two times ? |
@smnplk Yeah you are right :) I will edit the comment, thanks |
Ok, thank you :) Also, I think folks that use react >= 0.14.0 need to require ReactDOM too, because react_ujs.js depends on it. So if you can add the following line: var ReactDOM= window.ReactDOM = global.ReactDOM = require('react-dom'); |
@smnplk Yes that's right :) As you have pointed out - React DOM is now a separate package therefore, it must be included for rendering components. I have updated the comment. |
I can not get this working without multiple copies of React being loaded.
|
Hey @TSMMark Just double check if you are loading it twice anyhow - both in Sprockets and NPM. You may also want to reinstall node modules ( |
@gauravtiwari: Thanks for showing a way with browserify. Do you also know how to do it with the asset-pipeline? Thank you for any support! |
You could try copying this file into your app: https://github.com/PaulLeCam/react-leaflet/blob/master/dist/react-leaflet.js For example, if you copied it to
This line ( FWIW, that's how I bring third party components into my app:
|
Hi @gauravtiwari, thanks for the guide above - can you help with a few questions? I am trying to reconcile your instructions with those at browserify-rails but both assume a level of understanding a little beyond mine. Following your browserify instructions, where do you put the "Loading NPM modules" code? Where do you run "npm install" to actually install the module? What is no_content.es6.js? Is NoContent the name of the hypothetical NPM module you are loading? Also, the browserify-rails documentation says to create a package.json file with "name": "something" in it. Is that where I'm supposed to specify the NPM module I want to use? The NPM module I am trying to include in my react-rails app is 'react-data-grid'. |
@gauravtiwari, I've since proceeded based on some assumptions. I created a package.json file like this and ran npm install:
This installed a huge amount of JS (55MB) under node_modules. I ran This produced errors about react and react-dom being missing but since it seems they are included already I excluded them like this: The result was a Then I tried modifying application.js and components.js as you mention above. First I had to rename components.js to components.jsx because of the jsx content. Loading a page then produced this error:
My application.js looks like this:
components.js.jsx looks like this:
(I moved the require_tree to the bottom, you don't mention it) I've not tried to actually load the component on a page yet, I get this error as sprockets tries to compile the assets. I also tried reordering the requires in various ways by always get browserify complaining about certain files being missing. Any ideas where I went wrong? |
@awe2m2n2s You could also use rails-assets.org. which provides a lot of javascript packages bundled for Sprockets. React leaflet isn't available on rails-assets so I created it by pushing it to Bower. You could go to rails-assets.org and then search source 'https://rails-assets.org' do
gem 'rails-assets-react-leaflet'
end |
@lesliev Is |
@awe2m2n2s It depends on how it works for you. React has a standalone browser package and could be used with Sprockets, but as you go deeper and start using libraries around React, you might start getting headaches and roadblocks, because not all of them are made to be compatible with Sprockets. You can of course make them if you want to. Ideally, if you are doing a lot of work on client side and not just sprinkling javascript here and there, then it would make sense to use a workflow that's more integrated and efficient for front-end development. Now, that may mean going beyond traditional workflow. There is - Webpack, Browserify, Gulp, Grunt, Brunch, Bower and tons of other package managers. You could take a look at them and see what works for you, FYI, Webpack is most full-featured and popular nowadays. There is another implementation of React for Rails using Webpack - https://github.com/shakacode/react_on_rails |
You guys are truly awesome! damn thx so much and here are some remarks:
|
@awe2m2n2s I see. Basically, you have to fork the |
@gauravtiwari thanks for being such a champ! I've spent several days toying around with different setups and I like yours a lot! I was just trying to imitate it but even with browserify running a babelify transformation it chokes on jsx, and throws How would you go about debugging something like this? I can't figure out if the problem is browserify, babelify, or my configuration! Thanks for any advice you might have. |
@jcmorrow Are you providing right presets for transforming JSX? You may want to create a .babelrc file in the root directory with following content: Then you have to install all 3 babel presets, explained here: https://babeljs.io/docs/plugins/preset-react/, after this when you run babelify it will pickup the .babelrc and transform the code using the presets provided. |
@gauravtiwari I had all of that except stage-0 (adding it doesn't seem to make a difference). .babelrc:
application.rb:
package.json:
But still no jsx transform 😭 |
@jcmorrow Can you manually run and compile from command line or terminal? |
@gauravtiwari yeah I should have mentioned browserify on the command line works 100%. |
@gauravtiwari thanks for your help above, adding jquery-ujs to package.json did work. I guess I don't understand why this is even needed, I only require it because that's what you put in your original example application.js. I also tried from scratch again without excluding react and react-dom when running browserify (I previously used -i react -i react-dom). That didn't work at all because now there's require('./emptyFunction') inside the browserified js and that package is missing. Adding emptyfunction to package.json has no effect. I'd love to find (or be able to create) a complete guide on adding NPM's to react-rails projects. |
@lesliev That's for ajax requests, jquery-ujs takes care of adding CSRF token to ajax requests so you don't get protect from forgery exceptions on Rails, plus a few more goodies using |
@jcmorrow, @awe2m2n2s and @lesliev https://github.com/gauravtiwari/brunch_on_rails Perhaps you would like to look at this setup and see if it works for you? It works without the gem and uses Brunch, which is like Webpack, but quite simple to setup and use. You could tweak it to make it work as you like without much constraints. |
Example Rails 5 application running with |
And, finally using Webpack (https://webpack.github.io/docs/tutorials/getting-started/) without App uses the |
Awesome! Thanks so much for doing this. I'd continued by dropping the distribution JS into my app but I'll need a better solution in the long run. |
@gauravtiwari I like that last implementation a lot! I actually ended up using something similar a few days ago, though with Rails 4, not 5. As you say, it is much faster than browserify and gives much better error messages in my short experience. Thanks for all your work on this! |
I have tried everything all of you said but it still duplicate importing react. |
@luccasmaso try the updated repo: https://github.com/gauravtiwari/browserify_on_rails (Added a react plugin to test) and no duplication error. See show page (ignore the weird styles :)). |
Read all of this and I still have no idea how to 'require' javascript from node_modules/ into my react-rails app. Playing with browserify and webpack, the instructions are not clear. I have browserify installed but when I put #= require lodash into application.js.coffee, it crashes, lodash not found. Webpack, I couldn't even figure out where to start. Help? |
@Tectract - Browserify uses different workflow than sprockets so, you can't do If you want to make global lodash object, in For example: You could do same for lodash. If you just use it inside component, call it locally within component like so: https://github.com/gauravtiwari/browserify_on_rails/blob/master/app/assets/javascripts/components/pages/alert.es6.js#L2 (only with babel) or just use regular |
Thanks for your response. I'm trying to use rebass, a js-generated-css library, which I'm skeptical will work with browserify. I was just testing with lodash because it's easy to test. Have not succesfully loaded either NPM module into my react-rails stack yet. Right now my site has a single React component, defined in view/view.js.cjsx, written in coffeescript. I'm using the sprockets-coffee-react gem to handle that coffeescript. I try to include var _ = require('lodash'); in view.js.cjsx, no luck, var is a reserved word in coffeescript. I try just _ = require('lodash'), no luck, component just simply does not load at all, it is undefined now because that line broke it. I can't figure out how to get browserify to have any noticeable effect at all so far, everything just breaks when I try to include any NPM code. Maybe I installed it wrong? I have: gem 'browserify-rails', '>= 0.9.1' in my gemfile, installed gem, So maybe I should try webpack instead. Does this mean I will be compiling things from node_modules/ folders int minified sources and then copying those minified sources into app/assets/javascripts every time I start the server? |
@Tectract Browserify is fine for simple setup like this, first install lodash from npm: No everything will work as before, it just that now you can use npm modules with |
For rebass, you could do same and require as outlined in the docs at NPM: |
Sorry but this is not working for me, and I'm having a hard time troubleshooting it. I have done and I have added: Page loads without the view component. It is not defined now. Adding that line at the top has caused some sort of silent error and now the web console warns that "view" is undefined. Here is the content of my view.js.cjsx right now: @cjsx React.DOM_ = require 'lodash' @view = React.createClass render: -> TopLevelView div here
|
Huh, well this is interesting, it appears that the lodash/underscore functions are available for me now in view.js.cjsx, but something in here is causing the component to become undefined. When I load the page that contains the view component now, it actually does console log out the results from an _.each function call, but the render doesn't complete and it tells me the view is undefined on the console. any ideas what's going on? here is my view.cj.cjsx: @cjsx React.DOM_ = require('lodash'); @view = React.createClass render: ->
|
ok got it working with browserify in my application.js.coffee: in view.js.cjsx:
is happy now. Next will try rebass. Not sure if JS-generated-CSS is gonna work here, let's give it a shot... |
Hey @gauravtiwari, sorry to piggyback on this issue but I'm having issue using This is my
// Component::Manifest
import APIConsole from './react/console/api_console.es6.js';
import ImagePopup from './react/table/image_popup.es6.js';
import Sidebar from './react/sidebar/sidebar.es6.js';
// Setup app into global name space for server rendering
const app = window.app = global.app = {};
// Include into app namespace
app.APIConsole = APIConsole;
app.ImagePopup = ImagePopup;
app.Sidebar = Sidebar; |
I'm also getting this error, it doesn't state where this error is coming from but I think it is when trying to use the react components in the
|
Hey @vinnyoodles Please check out this repo and see if you are missing anything. Btw, have you setup babelrc to transform es6 code? https://github.com/gauravtiwari/browserify_on_rails/blob/master/.babelrc |
I found the bug fix here http://www.we-edit.de/stackoverflow/question/babelify-browserify-rails-react-uncaught-syntaxerror-unexpected-token-import-34645619.html. For some reason, the
|
@vinnyoodles Strange, I guess you are missing .babelrc or babel is not picking up proper transformer. Did you looked at the code I posted? |
Yeah, I included the |
@Tectract I'm trying to load rebass into react-rails as well, do you have a repo that is working up I could look at? |
This is a giant beast. In future, we'll switch off this Asset Pipeline completely. Meantime, we continuse to use it follow this references: - reactjs/react-rails#413 - https://github.com/gauravtiwari/browserify_on_rails/ Basically, we use ES6 import on `components.js`. We then expose those components into a global variable. Then sprocket include them and we use `react-rails` to render those component.
|
This is not an issue. I just need to know how to go about this.
How to add addons, let's say from react-components.com, to use with this gem?
The text was updated successfully, but these errors were encountered: