README.md in react_on_rails-6.0.0.rc.1 vs README.md in react_on_rails-6.0.0.rc.2

- old
+ new

@@ -16,11 +16,11 @@ # React on Rails **Project Objective**: To provide an opinionated and optimal framework for integrating **Ruby on Rails** with modern JavaScript tooling and libraries, including [**Webpack**](http://webpack.github.io/), [**Babel**](https://babeljs.io/), [**React**](https://facebook.github.io/react/), [**Redux**](https://github.com/reactjs/redux), [**React-Router**](https://github.com/reactjs/react-router). This differs significantly from typical Rails. When considering what goes into **react_on_rails**, we ask ourselves, is the functionality related to the intersection of using Rails and with modern JavaScript? If so, then the functionality belongs right here. In other cases, we're releasing separate npm packages or Ruby gems. If you are interested in implementing React using traditional Rails architecture, see [react-rails](https://github.com/reactjs/react-rails). -React on Rails integrates Facebook's [React](https://github.com/facebook/react) front-end framework with Rails. React v0.14.x and greate is supported, with server rendering. [Redux](https://github.com/reactjs/redux) and [React-Router](https://github.com/reactjs/react-redux) are supported as well, also with server rendering, using either **execJS** or a [Node.js server](https://github.com/shakacode/react_on_rails/blob/master/docs%2Fadditional-reading%2Fnode-server-rendering.md). See the Rails on Maui [blog post](http://www.railsonmaui.com/blog/2014/10/03/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/) that started it all! +React on Rails integrates Facebook's [React](https://github.com/facebook/react) front-end framework with Rails. React v0.14.x and greater is supported, with server rendering. [Redux](https://github.com/reactjs/redux) and [React-Router](https://github.com/reactjs/react-redux) are supported as well, also with server rendering, using either **execJS** or a [Node.js server](https://github.com/shakacode/react_on_rails/blob/master/docs%2Fadditional-reading%2Fnode-server-rendering.md). See the Rails on Maui [blog post](http://www.railsonmaui.com/blog/2014/10/03/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/) that started it all! ## Including your React Component in your Rails Views Please see [Getting Started](#getting-started) for how to set up your Rails project for React on Rails to understand how `react_on_rails` can see your ReactComponents. + *Normal Mode (React component will be rendered on client):* @@ -70,10 +70,11 @@ - [Globally Exposing Your React Components](#globally-exposing-your-react-components) - [ReactOnRails View Helpers API](#reactonrails-view-helpers-api) - [ReactOnRails JavaScript API](#reactonrails-javascript-api) - [React-Router](#react-router) - [Deployment](#deployment) ++ [Integration with Node](#integration-with-node) + [Additional Reading](#additional-reading) + [Contributing](#contributing) + [License](#license) + [Authors](#authors) + [About ShakaCode](#about-shakacode) @@ -99,41 +100,43 @@ Universal React with Rails: Part I](https://medium.com/@alexfedoseev/isomorphic-react-with-rails-part-i-440754e82a59). We're definitely not doing that. With react_on_rails, webpack is mainly generating a nice JavaScript file for inclusion into `application.js`. We're going to KISS. And that's all relative given how much there is to get right in an enterprise class web application. ## Getting Started -1. Add the following to your Gemfile and bundle install: +1. Add the following to your Gemfile and bundle install. ```ruby gem "react_on_rails", "~> 5" ``` -2. See help for the generator: +2. Commit this to git (you cannot run the generator unless you do this). +3. See help for the generator: + ```bash rails generate react_on_rails:install --help ``` -2. Run the generator with a simple "Hello World" example (more options below): +4. Run the generator with a simple "Hello World" example (more options below): ```bash rails generate react_on_rails:install ``` -3. NPM install. Make sure you are on a recent version of node. Please use at least Node v5. +5. NPM install. Make sure you are on a recent version of node. Please use at least Node v5. ```bash npm install ``` -4. Start your Rails server: +6. Start your Rails server: ```bash foreman start -f Procfile.dev ``` -5. Visit [localhost:3000/hello_world](http://localhost:3000/hello_world) +7. Visit [localhost:3000/hello_world](http://localhost:3000/hello_world) ### Installation Summary See the [Installation Overview](docs/basics/installation-overview.md) for a concise set summary of what's in a React on Rails installation. @@ -411,9 +414,120 @@ ## Deployment * Version 6.0 puts the necessary precompile steps automatically in the rake precompile step. You can, however, disable this by setting certain values to nil in the [config/react_on_rails.rb](config/react_on_rails.rb). * See the [Heroku Deployment](docs/additional-reading/heroku-deployment.md) doc for specifics regarding Heroku. * If you're using the node server for server rendering, you may want to do your own AWS install. We'll have more docs on this in the future. + +## Integration with Node +NodeJS can be used as the backend for server-side rendering instead of ExecJS. To do this you need to add a few files and then configure react_on_rails to use NodeJS. Here are the relevant files to add. + +```javascript +// client/node/package.json +{ + "name": "react_on_rails_node", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./server.js -s webpack-bundle.js" + }, + "dependencies": { + } +} +``` + +```javascript +// client/node/server.js +var net = require('net'); +var fs = require('fs'); + +var bundlePath = '../../app/assets/webpack/'; +var bundleFileName = 'webpack-bundle.js'; + +var currentArg; + +function Handler() { + this.queue = []; + this.initialized = false; +} + +Handler.prototype.handle = function (connection) { + var callback = function () { + connection.setEncoding('utf8'); + connection.on('data', (data)=> { + console.log('Processing request: ' + data); + var result = eval(data); + connection.write(result); + }); + }; + + if (this.initialized) { + callback(); + } else { + this.queue.push(callback); + } +}; + +Handler.prototype.initialize = function () { + console.log('Processing ' + this.queue.length + ' pending requests'); + var callback; + while (callback = this.queue.pop()) { + callback(); + } + + this.initialized = true; +}; + +var handler = new Handler(); + +process.argv.forEach((val) => { + if (val[0] == '-') { + currentArg = val.slice(1); + return; + } + + if (currentArg == 's') { + bundleFileName = val; + } +}); + +try { + fs.mkdirSync(bundlePath); +} catch (e) { + if (e.code != 'EEXIST') throw e; +} + +fs.watchFile(bundlePath + bundleFileName, (curr) => { + if (curr && curr.blocks && curr.blocks > 0) { + if (handler.initialized) { + console.log('Reloading server bundle must be implemented by restarting the node process!'); + return; + } + + require(bundlePath + bundleFileName); + console.log('Loaded server bundle: ' + bundlePath + bundleFileName); + handler.initialize(); + } +}); + +var unixServer = net.createServer(function (connection) { + handler.handle(connection); +}); + +unixServer.listen('node.sock'); + +process.on('SIGINT', () => { + unixServer.close(); + process.exit(); +}); + +``` + +The last thing you'll need to do is change the server_render_method to "NodeJS". + +```ruby +# app/config/initializers/react_on_rails.rb +config.server_render_method = "NodeJS" +``` ## Additional Reading + [JavaScript API](docs/api/javascript-api.md) + [Ruby API](docs/api/ruby-api.md) + [Setting up Hot Reloading during Rails Development, API docs](docs/api/ruby-api-hot-reload-view-helpers.md)