Rails, the hard way

Just posting stuff which freaks me out...

React/Redux With Rails 3.2 & Sprockets

| Comments

Another frustrating night went over and today morning I finished something I wanted to archieve over the last couple of days. Yay! :)

I tried to make the Redux Exampe TodoApp work with Rails 3.2.21, together with the ES6 format and requiring the modules via require / browserify.

I tried so many different ways to install all requirements - from npm over webpack, but got a lot of different error messages and nothin really worked well… But today I found a configuration, which works quite ok - and I wanted to share it.

The only thing to mention is, that you have to specify the imports with the correct filename, so really append “file.js.jsx” at the end, if you use the same naming convention like me.

So here is my config:

/Gemfile
1
2
3
4
...
gem 'react-rails' # for parsing jsx files
gem "browserify-rails" #react dependencies
...
/package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# transform-object-rest-spread makes the Object Spread Operator work
# http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html
{
  "name": "something",
  "license": "MIT",
  "engines": {
    "node": ">= 0.10"
  },
  "dependencies": {
    "babel-plugin-transform-object-rest-spread": "^6.6.5",
    "babel-preset-es2015": "^6.1.18",
    "babel-preset-react": "^6.5.0",
    "babelify": "^7.2.0",
    "browserify": "~> 10.2.4",
    "browserify-incremental": "^3.0.1",
    "react": "^0.14.7",
    "react-dom": "^0.14.7",
    "react-redux": "^4.4.1",
    "redux": "^3.3.1"
  },
  "devDependencies": {
    "redux-devtools": "^3.1.1"
  }
}
/config/application.rb
1
2
3
4
5
6
7
8
9
...
module MyApp
  class Application < Rails::Application
    ...
    config.react.addons = true

    config.browserify_rails.commandline_options = "-t [ babelify --presets [ es2015 react ] ]"
  end
end
/.babelrc
1
2
3
4
5
6
# transform-object-rest-spread makes the Object Spread Operator work
# http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html
{
  "presets": ["es2015", "react"],
  "plugins": ["transform-object-rest-spread"]
}
/app/assets/javascripts/application.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'

# Take care, you really have to specify the correct filename!
# "import todoApp from './reducers'" like in the original redux example didn't work out for me
import todoApp from './reducers/index.js.jsx'
import App from './components/app.js.jsx'
let store = createStore(todoApp)

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)