Roll your own
If you have got two projects using the same functionality, then write a Rubygem to promote code reuse and modularity. Writing a gem is not a new thing. In fact, there are 6,710,940,000 gems and counting, as per the rubygems homepage.
Years ago Jamis Buck said in one of his blogs that if you don’t understand the inner workings of a gem, don’t use it as a dependency. Very fair comment indeed! I’m guilty of using the gems without really knowing their inner workings. To be honest, as a modern day programmer with a constant client expectation to deliver solutions, it’s okay to take your eyes of the ball.
However, I decided to make amendments when it came to integrating a react app into rails. I wanted to learn and fix the issues that comes with integrating and therefore, decided to start it from scratch. If you wish to use, there are a couple of nice integrate react with rails gems out there, namely, react_on_rails and react-rails.
What are we going to do
There are a few things to keep in mind:
- A react component will serve as the client talking to the rails as a backend.
- The rails will be used a backend.
- It’s not an isomorphic application meaning there will be no server-side rendering of react components.
- It should play nicely with rails asset pipeline.
As part of this article, we are going to set-up a react app in both development and production-mode that will play nicely with a rails app.
Setting up a rails app
As a seasoned rails developer, I expect you guys to know how to do this.
Setting up a react app
- Create a directory called
clientat the same level as the
- Create a file called
clientdirectory. Package.json is to npm what Gemfile is to Bundler. Copy the following contents into the client/package.json. Most of it is pretty self-explanatory except the scripts section. Npm allows you to create these tasks inside the scripts section runnable from the command line via
npm runcommand. Under
startstarts a webpack dev server useful for reloading the app whilst working in development.
buildis for building the app locally and uses the default webpack config and finally,
build:prodbuilds the final distributable js file using webpack’s production config.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
clientdirectory with the following contents:*
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
clientdirectory with the following contents. This is the default config used by webpack.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
- Finally, create
clientdirectory with the following contents. This is mainly used for creating a production ready distributable bundle. It is invoked with a
-poption at the command line to trigger automatic minification.
1 2 3 4 5 6 7 8 9 10 11 12 13
Create a directory called
src/jsdirectory, create a file called
app.js. This is the entry file for webpack. Entry file is the file webpack uses to workout all the other dependencies that it needs to bundle up in the final distributable file.
app.jsfile should have the following contents. This is the entry point for the app. Here it’s rendering the react app in a dom node with the id
react-app. Make sure a dom node with the same id exists in the layout file of your rails app, otherwise, react will have no place to mount the app.
1 2 3 4 5 6 7 8
- One last thing, create the following directory, src/js/components and in there create a root react component called App.react.js with the following contents. As you can see, the
Appis written in ES6 classes and takes advantage of the modular dependency provided by ES6 out of the box.
1 2 3 4 5 6 7 8 9 10 11 12 13
- Open a terminal window and navigate to the client directory that we created above.
npm run build. This will create a bundle.js (development version) and to
- Make sure to refer to it from the layout file. I added it to the
config/initializers/assets.rbas a precompiled file:
Added it at the bottom of the layout file with a script tag to ensure the DOM node that react app depends upon is there before react’s mounting kicks in.
Opened the rails root page in a browser to check the react app is being mounted correctly and
React App(the contents of the App.react.js component) is being rendered on the page.
Phew, further investigation things!
- Firstly, you will see there is an error in the dev tools. The app still works fine. This means the at the time of the mount react didn’t find the DOM node which seems bizzare because it works fine. I noticed removing the line of code that brings in
application.jsin your rails layout file fixes this issue.
- You will also notice a lot of sock.js errors in the dev tools. This is because the in the webpack development config we’ve set it up to communicate with the local webpack dev server and update any changes to the app via websocket. I haven’t quite worked out how the webpack-dev-server communication with this will work, so ignore those for now, or just build the bundle.js using webpack production config.
And, that’s it!
Update: 06 December 2015
The following error
is my fault. In my
bundle.js as a precompiled asset, so we don’t need to bring it in as part of
appication.js. There’s an easy fix in Sprockets for it. If you would like to ignore a file in your directory you use the
stub call. So, my
application.js file now looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17