Skip to content

Commit

Permalink
Doc updates (#1155)
Browse files Browse the repository at this point in the history
  • Loading branch information
justin808 authored Oct 14, 2018
1 parent d4be0b8 commit d4ccd9c
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 15 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ React on Rails integrates Rails with (server rendering of) Facebook's [React](ht

Intersted in optimizing your webpack setup for React on Rails including code splitting with react-router v4, webpack v4, and react-loadable? [Contact me](mailto:[email protected]).

ShakaCode is **[currently looking to hire](http://www.shakacode.com/about/#work-with-us)** like-minded developers that wish to work on our projects, including [Hawaii Chee](https://www.hawaiichee.com). Your main coding interview will be pairing with us on our open source! We're getting into [Reason](https://reasonml.github.io/)!

# Intro

## Project Objective
Expand All @@ -16,8 +14,9 @@ To provide an opinionated and optimal framework for integrating Ruby on Rails wi

## Features and Why React on Rails?

Given that rails/webpacker gem already provides basic React integration, why would you use "React on Rails"? Server rendering, often used for SEO and performance, is not offered by rails/webpacker.
Given that rails/webpacker gem already provides basic React integration, why would you use "React on Rails"?

1. Server rendering, often used for SEO crawler indexing and UX performance, is not offered by rails/webpacker.
1. The easy passing of props directly from your Rails view to your React components rather than having your Rails view load and then make a separate 1request to your API.
1. [Redux](https://github.com/reactjs/redux) and [React Router](https://github.com/reactjs/react-router) integration.
1. [Internationalization (I18n) and (localization)](https://github.com/shakacode/react_on_rails/blob/master/docs/basics/i18n.md)
Expand All @@ -37,6 +36,7 @@ React on Rails Pro provides Node server rendering and other performance enhancem

![2018-09-11_10-31-11](https://user-images.githubusercontent.com/1118459/45467845-5bcc7400-b6bd-11e8-91e1-e0cf806d4ea4.png)

* [HVMN Testimonial, Written by Paul Benigeri, October 12, 2018](./docs/testimonials/hvmn.md)
* [HVMN’s 90% Reduction in Server Response Time from React on Rails Pro](https://blog.shakacode.com/hvmns-90-reduction-in-server-response-time-from-react-on-rails-pro-eb08226687db)
* [Egghead React on Rails Pro Deployment Highlights](https://github.com/shakacode/react_on_rails/wiki/Egghead-React-on-Rails-Pro-Deployment-Highlights)

Expand All @@ -59,6 +59,10 @@ Please [email me (Justin Gordon), the creator of React on Rails](mailto:justin@s

## Testimonials for Hiring ShakaCode and our "Pro Support"

[HVMN Testimonial, Written by Paul Benigeri, October 12, 2018](./docs/testimonials/hvmn.md)

> The price we paid for the consultation + the React on Rails pro license has already been made back a couple of times from hosting fees alone. The entire process was super hands off, and our core team was able to focus on shipping new feature during that sprint.
From Kyle Maune of Cooper Aerial, May 4, 2018

![image](https://user-images.githubusercontent.com/1118459/40891236-9b0b406e-671d-11e8-80ee-c026dbd1d5a2.png)
Expand Down Expand Up @@ -288,7 +292,7 @@ Here are some highly recommended next articles to read:
1. [How React on Rails Works](./docs/basics/how-react-on-rails-works.md)
1. [Recommended Project Structure](./docs/basics/recommended-project-structure.md)
1. [Webpack Configuration](./docs/basics/webpack-configuration.md)
1. [View Helpers API](./docs/view-helpers-api.md)
1. [View Helpers API](./docs/api/view-helpers-api.md)
1. [Caching and Performance: React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki).
1. [Deployment](docs/basics/deployment.md).
Expand Down Expand Up @@ -326,6 +330,9 @@ The following companies support this open source project, and ShakaCode uses the
Aloha and best wishes from Justin and the ShakaCode team!
# Work with Us
ShakaCode is **[currently looking to hire](http://www.shakacode.com/about/#work-with-us)** like-minded, remote-first, developers that wish to work on our projects, including [Hawaii Chee](https://www.hawaiichee.com). Your main coding interview will be pairing with us on our open source! We're getting into [Reason](https://reasonml.github.io/)!
# License
The gem is available as open source under the terms of the [MIT License](LICENSE.md).
2 changes: 2 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
+ [React on Rails Basic Installation Tutorial](./docs/tutorial.md)
+ [Webpack Configuration](./docs/basics/webpack-configuration.md)
+ [How React on Rails Works](./docs/basics/how-react-on-rails-works.md)
+ [Client vs. Server Rendering](./docs/basics/client-vs-server-rendering.md)
+ [React Server Rendering](./docs/basics/react-server-rendering.md)
+ [Recommended Project Structure](./docs/basics/recommended-project-structure.md)
+ [Generator Functions and the RailsContext](docs/basics/generator-functions-and-railscontext.md)
+ [Caching and Performance: React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki).
Expand Down
2 changes: 1 addition & 1 deletion docs/basics/generator-details.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ More Details:
Another good option is to create a simple test app per the [Tutorial](../tutorial.md).

# Understanding the Organization of the Generated Client Code
The generated client code follows our organization scheme. Each unique set of functionality, is given its own folder inside of `client/app/bundles`. This encourages for modularity of *domains*.
The generated client code follows our organization scheme. Each unique set of functionality, is given its own folder inside of `app/javascript/app/bundles`. Note, the recommended for bigger projects is `client/app/bundles`. This encourages for modularity of *domains*.

Inside of the generated "HelloWorld" domain you will find the following folders:

Expand Down
4 changes: 3 additions & 1 deletion docs/basics/react-server-rendering.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# React Server Rendering

See also [Client vs. Server Rendering](./client-vs-server-rendering.md)

## What is Server Rendering?

Here's a [decent article to introduce you to server rendering](https://medium.freecodecamp.org/server-side-rendering-your-react-app-in-three-simple-steps-7a82b95db82e). Note, React on Rails takes care of calling the methods in [ReactDOMServer](https://reactjs.org/docs/react-dom-server.html).
Expand All @@ -8,7 +10,7 @@ During the Rails rendering of HTML per a browser request, the Rails server will

The default JavaScript interpretter is [ExecJS](https://github.com/rails/execjs). If you want to maximize the perfomance of your server rendering, then you want to use React on Rails Pro which uses NodeJS to do the server rendering. See the [docs for React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki).

See [this note](basics/how-react-on-rails-works.md#client-side-rendering-vs-server-side-rendering)
See [this note](./how-react-on-rails-works.md#client-side-rendering-vs-server-side-rendering)


## How do you do Server Rendering with React on Rails?
Expand Down
25 changes: 24 additions & 1 deletion docs/basics/recommended-project-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ app/javascript:
The problems with this structure and using rails/webpacker to configure Webpack for you:

1. No support for different entry points for server rendering.
2. Webpacker adds an ex``tra layer of abstraction over Webpack, which you probably don't want.
2. Webpacker adds an extra layer of abstraction over Webpack, which you probably don't want.

This default rails/webpacker configuration is used for the generator because:

Expand All @@ -28,6 +28,29 @@ This default rails/webpacker configuration is used for the generator because:

Thus, the generator structure and using rails/webpacker for Webpack configuration **is not recommended** for any commercial projects, especially those that will use server rendering. Instead, the recommended structure is shown in this example app: [github.com/shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) and described below.

## Steps to convert from the generator defaults to use the recommended `/client` directory structure.

1. Move the directory:

```
mv app/javascript client
```

2. Edit your `/config/webpacker.yml` file. Change the `default/source_path`:

```yml
source_path: client
```
## Moving node_modules from `/` to `/client` with a custom webpack setup.

`rails/webpacker` probably doesn't support having your main node_modules directory under `/client`, so only follow these steps if you want to use your own webpack configuration (which is highly recommended!).

1. Move the `/package.json` to `/client/package.json`
2. Create a `/pacage.json` that delegates to `/client/package.json`. See the example in [spec/dummy/package.json](../../spec/dummy/package.json).
3. See the webpack configuration in [spec/dummy/client](../../spec/dummy/client) for a webpack configuration example.


## JavaScript Assets
1. `/client`: All client side JavaScript goes under the `/client` directory. Place all the major domains of the client side app under client.
1. `/client/app`: All application JavaScript. Note the adherence to the [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript#naming-conventions) where we name the files to correspond to exported Objects (PascalCase) or exported functions (camelCase). We don't use dashes or snake_case for JavaScript files, except for possibly some config files.
Expand Down
11 changes: 11 additions & 0 deletions docs/basics/webpack-configuration.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Webpack Configuration: custom setup for Webpack or rails/webpacker?

## Webpack vs. rails/webpacker

[Webpack](https://webpack.js.org) is the JavaScript npm package that prepares all your client-side assets. The Rails asset pipeline used to be the preferable way to prepare client-side assets.

[rails/webpacker](https://github.com/rails/webpacker) is the Ruby gem that mainly gives us 2 things:

1. View helpers for placing the Webpack bundles on your Rails views. React on Rails depends on these view helpers.
2. A layer of abstraction on top of Webpack customization. This is great for demo projects, but most real world projects will want a customized version of Webpack.

# React on Rails

Version 9 of React on Rails added support for the rails/webpacker view helpers so that Webpack produced assets would no longer pass through the Rails asset pipeline. As part of this change, React on Rails added a configuration option to support customization of the node_modules directory. This allowed React on Rails to support the rails/webpacker configuration of the Webpack configuration.

A key decision in your use React on Rails is whether you go with the rails/webpacker default setup or the traditional React on Rails setup of putting all your client side files under the `/client` directory. While there are technically 2 independent choices involved, the directory structure and the mechanism of Webpack configuration, for simplicity sake we'll assume that these choices go together.
Expand Down
25 changes: 25 additions & 0 deletions docs/testimonials/hvmn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# HVMN Testimonial, Written by Paul Benigeri, October 12, 2018

For some years, we used React on Rails for server-side rendering at [HVMN](https://hvmn.com). Our entire backend was already built in Rails, and we love React. As a content & e-commerce site, server-side rendering is critical, for UX performance and SEO crawler indexing.

During the 12 months leading up to our React on Rails Pro transition, our traffic grew 10x. Our team of 2 engineers was focused on shipping features, and we started to face performance issues. We had some fragment caching of our React server rending, but it didn’t work that well.

I discussed our growing pains with Justin, and as it turned out, ShakaCode just came out with React on Rails Pro and set it up on [egghead.io](https://egghead.io). The performance improvements were impressive, and Justin’s team was an ideal partner to help with the integration.

We decided to give it a shot. Over three weeks, the ShakaCode team helped us migrate to React on Rails Pro, set up Webpack v4, migrated our entire asset pipeline to Webpack v4.

Results were great. Our blog and product pages are 80-90% faster after that effort. The improved fragment caching was quick to set up and made a huge dent in our average server response times. We also observed an additional drop in response times when ShakaCode shipped the standalone Node server-side React renderer.

Working with ShakaCode was a pleasure. Justin is one of the smartest Rails architects I know, and his team was responsive and productive.

The price we paid for the consultation + the React on Rails pro license has already been made back a couple of times from hosting fees alone. The entire process was super hands off, and our core team was able to focus on shipping new feature during that sprint.

If you have any questions, please reach out.

Paul Benigeri
[[email protected]](mailto:[email protected])
[LinkedIn](https://www.linkedin.com/in/benigeri/)

Related Article: [HVMN’s 90% Reduction in Server Response Time from React on Rails Pro](https://blog.shakacode.com/hvmns-90-reduction-in-server-response-time-from-react-on-rails-pro-eb08226687db)

[![image](https://user-images.githubusercontent.com/1118459/46911126-577abd00-ceee-11e8-86c6-6703ff80fc2f.png)](https://www.linkedin.com/in/benigeri/)
85 changes: 77 additions & 8 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@ cd <directory where you want to create your new Rails app>
rails new test-react-on-rails --webpack=react
cd test-react-on-rails
bundle
```

Note: if you are installing React On Rails in an existing app or an app that uses Rails pre 5.1.3, you will need to run these two commands as well:
Note: if you are installing React On Rails in an existing app or an app that uses **Rails pre 5.1.3** (*not for Rails > 5.2*), you will need to run these two commands as well:

```
bundle exec rails webpacker:install
Expand All @@ -59,7 +60,7 @@ bundle exec rails webpacker:install:react
Add the **React On Rails** gem to your Gemfile:

```
gem 'react_on_rails', '11.1.4' # prefer exact gem version to match npm version
gem 'react_on_rails', '11.1.7' # prefer exact gem version to match npm version
```

Note: Latest released React On Rails version is considered stable. Please use the latest version to ensure you get all the security patches and the best support.
Expand Down Expand Up @@ -89,7 +90,7 @@ and then run server with
foreman start -f Procfile.dev
```

Visit http://localhost:3000/hello_world and see your **React On Rails** app running!
Visit [http://localhost:3000/hello_world](http://localhost:3000/hello_world) and see your **React On Rails** app running!
Note, foreman defaults to PORT 5000 unless you set the value of PORT in your environment or in the Procfile.

### Custom IP & PORT setup (Cloud9 example)
Expand All @@ -115,7 +116,7 @@ It's super important to exclude certain directories from RubyMine or else it wil
### Create Your Heroku App
*Assuming you can login to heroku.com and have logged into to your shell for heroku.*

1. Visit https://dashboard.heroku.com/new and create an app, say named `my-name-react-on-rails`:
1. Visit [https://dashboard.heroku.com/new](https://dashboard.heroku.com/new) and create an app, say named `my-name-react-on-rails`:

![06](https://cloud.githubusercontent.com/assets/20628911/17465014/1f29bf3c-5cf4-11e6-869f-4215987ae854.png)

Expand All @@ -137,10 +138,11 @@ Set heroku to use multiple buildpacks:
gem 'pg'
```

![07](https://cloud.githubusercontent.com/assets/20628911/17465015/1f2f4042-5cf4-11e6-8287-2fb077550809.png)
2. Run `bundle`

![07](https://cloud.githubusercontent.com/assets/20628911/17465015/1f2f4042-5cf4-11e6-8287-2fb077550809.png)

2. Replace your `database.yml` file with this (assuming your app name is "ror").
3. Replace your `database.yml` file with this (assuming your app name is "ror").

```yml
default: &default
Expand Down Expand Up @@ -185,11 +187,15 @@ root "hello_world#index"

Next, configure your app for Puma, per the [instructions on Heroku](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server).

Create `/Procfile`. This is what Heroku uses to start your app.

`Procfile`
```
web: bundle exec puma -C config/puma.rb
```

Note, newer versions of Rails create this file automatically. However, the [docs on Heroku](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#config) have something a bit different, so please make it conform to those docs. As of 2018-10-13, the docs looked like this:

`config/puma.rb`
```rb
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
Expand All @@ -212,9 +218,72 @@ end
Then after all changes are done don't forget to commit them with git and finally you can push your app to Heroku!

```
git add -A
git commit -m "Latest changes"
git add -a
git commit -m "Changes for Heroku"
git push heroku master
```

Then run:

```
heroku open
```

and you will see your live app and you can share this URL with your friends. Congrats!


## Turning on Server Rendering

You can turn on server rendering by simply changing the `prerender` option to `true`:

```erb
<%= react_component("HelloWorld", props: @hello_world_props, prerender: true) %>
```

Then push to Heroku:

```
git add -a
git commit -m "Enable server rendering"
git push heroku master
```

When you look at the source code for the page (right click, view source in Chrome), you can see the difference between non-server rendering, where your DIV containing your React looks like this:

```html
<div id="HelloWorld-react-component-b7ae1dc6-396c-411d-886a-269633b3f604"></div>
```

versus with server rendering:

```html
<div id="HelloWorld-react-component-d846ce53-3b82-4c4a-8f32-ffc347c8444a"><div data-reactroot=""><h3>Hello, <!-- -->Stranger<!-- -->!</h3><hr/><form><label for="name">Say hello to:</label><input type="text" id="name" value="Stranger"/></form></div></div>
```

For more details on server rendering, see:

+ [Client vs. Server Rendering](./basics/client-vs-server-rendering.md)
+ [React Server Rendering](./basics/react-server-rendering.md)

## Moving from the Rails default `/app/javascript` to the recommended `/client` structure

ShakaCode recommends that you use `/client` for your client side app. This way a non-Rails, front-end developer can be at home just by opening up the `/client` directory.


1. Move the directory:

```
mv app/javascript client
```

2. Edit your `/config/webpacker.yml` file. Change the `default/source_path`:

```yml
source_path: client
```
At this point, you can optionally turn off server rendering and use `foreman start -f Procfile.dev-server`.

Hot reloading using default rails/webpacker configuration with server rendering is not supported.

Feedback is greatly appreciated! As are stars on github! If you want personalized help, don't hesitate to get in touch with us at [[email protected]](mailto:[email protected]).

0 comments on commit d4ccd9c

Please sign in to comment.