react_on_rails 12.0.5.beta.0 → 12.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +11 -1
  3. data/.eslintrc +2 -0
  4. data/.prettierrc +0 -3
  5. data/.rubocop.yml +38 -1
  6. data/CHANGELOG.md +22 -13
  7. data/CONTRIBUTING.md +3 -2
  8. data/Gemfile.development_dependencies +3 -2
  9. data/README.md +68 -65
  10. data/docs/{basics → additional-details}/generator-details.md +1 -6
  11. data/docs/{outdated → additional-details}/manual-installation-overview.md +6 -6
  12. data/docs/{basics → additional-details}/migrating-from-react-rails.md +0 -0
  13. data/docs/{additional-reading → additional-details}/recommended-project-structure.md +0 -0
  14. data/docs/{additional-reading → additional-details}/updating-dependencies.md +0 -0
  15. data/docs/additional-details/upgrade-webpacker-v3-to-v4.md +10 -0
  16. data/docs/api/javascript-api.md +2 -2
  17. data/docs/api/redux-store-api.md +3 -3
  18. data/docs/api/view-helpers-api.md +7 -8
  19. data/docs/basics/client-vs-server-rendering.md +3 -3
  20. data/docs/basics/configuration.md +42 -25
  21. data/docs/basics/deployment.md +2 -2
  22. data/docs/{outdated → basics}/how-react-on-rails-works.md +8 -9
  23. data/docs/basics/installation-into-an-existing-rails-app.md +2 -2
  24. data/docs/basics/react-server-rendering.md +3 -3
  25. data/docs/basics/rspec-configuration.md +10 -10
  26. data/docs/{tutorial.md → basics/tutorial.md} +9 -9
  27. data/docs/basics/upgrading-react-on-rails.md +7 -7
  28. data/docs/basics/webpack-configuration.md +4 -6
  29. data/docs/contributor-info/linters.md +5 -6
  30. data/docs/contributor-info/pull-requests.md +2 -4
  31. data/docs/contributor-info/releasing.md +1 -1
  32. data/docs/{additional-reading → deployment}/elastic-beanstalk.md +0 -0
  33. data/docs/{basics → deployment}/heroku-deployment.md +0 -0
  34. data/docs/home.md +382 -0
  35. data/docs/{additional-reading → javascript}/angular-js-integration-migration.md +0 -0
  36. data/docs/{additional-reading → javascript}/asset-pipeline.md +0 -0
  37. data/docs/{additional-reading → javascript}/capistrano-deployment.md +0 -0
  38. data/docs/{outdated → javascript}/code-splitting.md +3 -3
  39. data/docs/{additional-reading → javascript}/converting-from-custom-webpack-config-to-rails-webpacker-config.md +3 -3
  40. data/docs/{additional-reading → javascript}/credits.md +0 -0
  41. data/docs/{additional-reading → javascript}/foreman-issues.md +0 -0
  42. data/docs/{additional-reading → javascript}/images.md +5 -6
  43. data/docs/{additional-reading → javascript}/node-dependencies-and-npm.md +0 -0
  44. data/docs/{additional-reading → javascript}/react-and-redux.md +0 -0
  45. data/docs/{additional-reading → javascript}/react-helmet.md +0 -0
  46. data/docs/{additional-reading → javascript}/react-router.md +0 -0
  47. data/docs/{additional-reading → javascript}/server-rendering-tips.md +0 -0
  48. data/docs/{additional-reading → javascript}/troubleshooting-when-using-webpacker.md +0 -0
  49. data/docs/{additional-reading → javascript}/webpack-v1-notes.md +0 -0
  50. data/docs/{additional-reading → javascript}/webpack.md +0 -0
  51. data/docs/{articles.md → misc/articles.md} +1 -1
  52. data/docs/misc/doctrine.md +5 -5
  53. data/docs/{coding-style → misc}/style.md +0 -0
  54. data/docs/{additional-reading → misc}/tips.md +0 -0
  55. data/docs/outdated/deferred-rendering.md +39 -0
  56. data/docs/outdated/rails-assets-relative-paths.md +3 -3
  57. data/docs/outdated/rails-assets.md +8 -8
  58. data/docs/outdated/rails3.md +2 -2
  59. data/docs/rails-webpacker-react-integration-options.md +182 -0
  60. data/docs/{additional-reading → rails}/convert-rails-5-api-only-app.md +1 -1
  61. data/docs/{additional-reading → rails}/rails-engine-integration.md +0 -0
  62. data/docs/{additional-reading → rails}/rails_view_rendering_from_inline_javascript.md +0 -0
  63. data/docs/{additional-reading → rails}/turbolinks.md +0 -0
  64. data/docs/testimonials/testimonials.md +6 -6
  65. data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -1
  66. data/lib/generators/react_on_rails/templates/dev_tests/spec/rails_helper.rb +4 -1
  67. data/lib/generators/react_on_rails/templates/dev_tests/spec/{features → system}/hello_world_spec.rb +2 -2
  68. data/lib/react_on_rails/helper.rb +5 -0
  69. data/lib/react_on_rails/utils.rb +16 -2
  70. data/lib/react_on_rails/version.rb +1 -1
  71. data/lib/react_on_rails/webpacker_utils.rb +5 -1
  72. data/lib/tasks/assets.rake +14 -5
  73. data/package.json +24 -29
  74. data/rakelib/release.rake +19 -3
  75. data/rakelib/task_helpers.rb +15 -2
  76. data/yarn.lock +2272 -4960
  77. metadata +41 -38
  78. data/docs/additional-reading/upgrade-webpacker-v3-to-v4.md +0 -10
@@ -1,6 +1,6 @@
1
1
  # Code Splitting (Outdated)
2
2
 
3
- _Note: This document is outdated._ Please email [justin@shakacode.com](mailto:justin@shakacode.com)
3
+ _Note: This document is outdated._ Please email [justin@shakacode.com](mailto:justin@shakacode.com)
4
4
  if you would be interested in help with code splitting using
5
5
  [loadable-components.com](https://loadable-components.com/docs) with React on Rails.
6
6
 
@@ -68,7 +68,7 @@ ReactOnRails.register({
68
68
  RouterApp,
69
69
  });
70
70
  ```
71
- Note that you should not register a renderer on the server, since there won't be a domNodeId when we're server rendering. Note that the `RouterApp` imported by `serverRegistration.js` is from a different file. For an example of how to set up an app for server rendering, see the [react router docs](../additional-reading/react-router.md).
71
+ Note that you should not register a renderer on the server, since there won't be a domNodeId when we're server rendering. Note that the `RouterApp` imported by `serverRegistration.js` is from a different file. For an example of how to set up an app for server rendering, see the [react router docs](https://www.shakacode.com/react-on-rails/docs/javascript/react-router).
72
72
 
73
73
  #### RouterAppRenderer.jsx
74
74
  ```jsx
@@ -150,7 +150,7 @@ config = {
150
150
 
151
151
  This causes Webpack to prepend the code chunk filename with `/assets/` in the request url. The react on rails sets up the webpack config to put webpack bundles in `app/assets/javascripts/webpack`, and modifies `config/initializers/assets.rb` so that rails detects the bundles. This means that when we prepend the request url with `/assets/`, rails will know what webpack is asking for.
152
152
 
153
- See [rails-assets.md](docs/outdated/rails-assets.md) to learn more about static assets.
153
+ See [our rails assets documentation](https://www.shakacode.com/react-on-rails/docs/outdated/rails-assets) to learn more about static assets.
154
154
 
155
155
  If you forget to set the public path, webpack will request the code chunk at `/{filename}`. This will cause the request to be handled by the Rails router, which will send back a 404 response, assuming that you don't have a catch-all route. In your javascript console, you'll get the following error:
156
156
 
@@ -1,10 +1,10 @@
1
1
  # Converting from Custom Webpack Config to Rails Webpacker Config
2
2
 
3
- 1. Compare your package.json and the dependencies in https://github.com/rails/webpacker/blob/master/package.json#L14-L48
4
- and avoid any duplicates. We don't want different versions of the same packages.
3
+ 1. Compare your package.json and the dependencies in https://github.com/rails/webpacker/blob/master/package.json
4
+ and avoid any duplicates. We don't want different versions of the same packages.
5
5
  We want the versions from rails/webpacker unless we specifically want to override them.
6
6
  2. Search the rails/webpacker repo for anything you're not sure about in terms of package names.
7
7
  3. run `bin/webpack` and make sure there are zero errors
8
8
  4. update webpack plugins and loaders to current or close to current
9
- 5. Make sure that your bin/webpack and bin/webpacker match the latest on
9
+ 5. Make sure that your bin/webpack and bin/webpacker match the latest on
10
10
  https://github.com/rails/webpacker/tree/master/lib/install/bin
File without changes
@@ -1,8 +1,8 @@
1
1
  # Images
2
2
 
3
- 1. leading slash necessary on the
3
+ 1. leading slash necessary on the
4
4
  a. Option name for the file-loader and url-loader (todo reference)
5
- b. Option publicPath for the output (todo reference)
5
+ b. Option publicPath for the output (todo reference)
6
6
 
7
7
 
8
8
 
@@ -39,13 +39,13 @@ const assetLoaderRules = [
39
39
 
40
40
 
41
41
 
42
- A full example can be found at [spec/dummy/client/app/components/ImageExample/ImageExample.jsx](../../spec/dummy/client/app/components/ImageExample/ImageExample.jsx)
42
+ A full example can be found at [spec/dummy/client/app/components/ImageExample/ImageExample.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/components/ImageExample/ImageExample.jsx)
43
43
 
44
- You are free to use images either in image tags or as background images in SCSS files. You can
44
+ You are free to use images either in image tags or as background images in SCSS files. You can
45
45
  use a "global" location of /client/app/assets/images or a relative path to your JS or SCSS file, as
46
46
  is done with CSS modules.
47
47
 
48
- **images** is a defined alias, so "images/foobar.jpg" would point to the file at
48
+ **images** is a defined alias, so "images/foobar.jpg" would point to the file at
49
49
  `/client/app/assets/images/foobar.jpg.`
50
50
 
51
51
  ```
@@ -55,4 +55,3 @@ is done with CSS modules.
55
55
  },
56
56
  },
57
57
  ```
58
-
File without changes
@@ -6,7 +6,7 @@
6
6
  * [Webpacker Lite: Why Fork Webpacker?](https://blog.shakacode.com/webpacker-lite-why-fork-webpacker-f0a7707fac92)
7
7
  * [React on Rails, 2000+ 🌟 Stars](https://medium.com/shakacode/react-on-rails-2000-stars-32ff5cfacfbf#.6gmfb2gpy)
8
8
  * [The React on Rails Doctrine](https://medium.com/@railsonmaui/the-react-on-rails-doctrine-3c59a778c724)
9
- * [Simple Tutorial](docs/tutorial.md).
9
+ * [Simple Tutorial](https://www.shakacode.com/react-on-rails/docs/basics/tutorial).
10
10
 
11
11
  ## Videos
12
12
 
@@ -4,7 +4,7 @@ By Justin Gordon, January 26, 2016
4
4
 
5
5
  This document is an extension and complement to [The Rails Doctrine](http://rubyonrails.org/doctrine/). If you haven't read that document, I suggest you do so first.
6
6
 
7
- As stated in the [React on Rails README](../../README.md), the project objective is to provide an opinionated and optimal framework for integrating **Ruby on Rails** with modern JavaScript tooling and libraries. 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? A good example is view helper integration of React components on a Rails view. If the answer is yes, then the functionality belongs right here. In other cases, we're releasing separate npm packages or Ruby gems. For example, we needed an easy way to integrate [Twitter Bootstrap](http://getbootstrap.com/) with Webpack, and we released the [npm bootstrap-loader](https://github.com/shakacode/bootstrap-loader/).
7
+ As stated in the [React on Rails README](https://www.shakacode.com/react-on-rails/docs/), the project objective is to provide an opinionated and optimal framework for integrating **Ruby on Rails** with modern JavaScript tooling and libraries. 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? A good example is view helper integration of React components on a Rails view. If the answer is yes, then the functionality belongs right here. In other cases, we're releasing separate npm packages or Ruby gems. For example, we needed an easy way to integrate [Twitter Bootstrap](http://getbootstrap.com/) with Webpack, and we released the [npm bootstrap-loader](https://github.com/shakacode/bootstrap-loader/).
8
8
 
9
9
  Besides the project objective, let's stick with the "Rails Doctrine" and keep the following in mind.
10
10
 
@@ -19,14 +19,14 @@ The React on Rails setup provides several key components related to front-end de
19
19
  6. Happiness for us is actively participating in open source, so we want to be where the action is, which is with the npm libraries on github.com.
20
20
  7. You can get set up on React on Rails **FAST** using our application generator.
21
21
  8. By placing all client-side development inside of the `/client` directory, pure JavaScript developers can productively do development separate from Rails. Instead of Rails APIs, stub APIs on an express server can provide a simple backend, allowing for rapid iteration of UI prototypes.
22
- 9. Just because we're not relying on the Rails asset pipeline for ES6 conversion does not mean that we're deploying Rails apps in any different way. We still use the asset pipeline to include our Webpack compiled JavaScript. This only requires a few small modifications, as explained in our doc [Heroku Deployment](docs/basics/heroku-deployment.md).
22
+ 9. Just because we're not relying on the Rails asset pipeline for ES6 conversion does not mean that we're deploying Rails apps in any different way. We still use the asset pipeline to include our Webpack compiled JavaScript. This only requires a few small modifications, as explained in [our heroku deployment documentation](https://www.shakacode.com/react-on-rails/docs/deployment/heroku-deployment).
23
23
 
24
24
  ## Convention over Configuration
25
25
  * React on Rails has taken the hard work out of figuring out the JavaScript tooling that works best with Rails. Not only could you spend lots of time researching different tooling, but then you'd have to figure out how to splice it all together. This is where a lot of "JavaScript fatigue" comes from. The following keep the code clean and consistent:
26
- * [Style Guide](../coding-style/style.md)
27
- * [linters](../contributor-info/linters.md)
26
+ * [Style Guide](https://www.shakacode.com/react-on-rails/docs/misc/style)
27
+ * [linters](https://www.shakacode.com/react-on-rails/docs/contributor-info/linters)
28
28
 
29
- We're big believers in this quote from the Rails Doctrine:
29
+ We're big believers in this quote from the Rails Doctrine:
30
30
 
31
31
  > The same goes even when you understand how all the pieces go together. When there’s an obvious next step for every change, we can scoot through the many parts of an application that is the same or very similar to all the other applications that went before it. A place for everything and everything in its place. Constraints liberate even the most able minds.
32
32
 
File without changes
File without changes
@@ -0,0 +1,39 @@
1
+ # Deferred Rendering
2
+
3
+ Please see [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/] if you are interested in code splitting using
4
+ [loadable-components.com](https://loadable-components.com/docs) with React on Rails.
5
+
6
+ -----
7
+
8
+ What is code splitting? From the webpack documentation:
9
+
10
+ > For big web apps it’s not efficient to put all code into a single file, especially if some blocks of code are only required under some circumstances. Webpack has a feature to split your codebase into “chunks” which are loaded on demand. Some other bundlers call them “layers”, “rollups”, or “fragments”. This feature is called “code splitting”.
11
+
12
+ ## Server Rendering and Code Splitting
13
+
14
+ Let's say you're requesting a page that needs to fetch a code chunk from the server before it's able to render. If you do all your rendering on the client side, you don't have to do anything special. However, if the page is rendered on the server, you'll find that React will spit out the following error:
15
+
16
+ > Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
17
+
18
+ > (client) <!-- react-empty: 1 -
19
+
20
+ > (server) <div data-reactroot="
21
+ <!--This comment is here because the comment beginning on line 13 messes up Sublime's markdown parsing-->
22
+
23
+ Different markup is generated on the client than on the server. Why does this happen? When you register a component or Render-Function with `ReactOnRails.register`, React on Rails will by default render the component as soon as the page loads. However, code splitting requires that components render at a later time when the JavaScript chunks have loaded.
24
+
25
+ ## Solution
26
+
27
+ To prevent this, you have to wait until the code chunk is fetched before doing the initial render on the client side. To accomplish this, react on rails allows you to register a renderer. This works just like registering a Render-Function, except that the function you pass takes three arguments: `renderer(props, railsContext, domNodeId)`, and is responsible for calling `ReactDOM.render` or `ReactDOM.hydrate` to render the component to the DOM. React on rails will automatically detect when a Render-Function takes three arguments, and will **not** call `ReactDOM.render` or `ReactDOM.hydrate`, instead allowing you to control the initial render yourself. Note, you have to be careful to call `ReactDOM.hydrate` rather than `ReactDOM.render` if you are are server rendering.
28
+
29
+
30
+ ## Server vs. Client Code Caveats
31
+
32
+ If you're going to try to do code splitting with server rendered routes, you'll probably need to use seperate route definitions for client and server to prevent code splitting from happening for the server bundle. The server bundle should be one file containing all the JavaScript code. This will require you to have seperate webpack configurations for client and server.
33
+
34
+ Do not attempt to register a renderer function on the server. Instead, register either a Render-Function or a component. If you register a renderer in the server bundle, you'll get an error when react on rails tries to server render the component.
35
+
36
+
37
+ ## React on Rails Pro
38
+ [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/] includes a complete setup using this technique for code splitting using
39
+ [loadable-components.com](https://loadable-components.com/docs) with React on Rails.
@@ -77,7 +77,7 @@ Note: _You can output these files in the asset pipeline wherever you see fit. My
77
77
 
78
78
  Lastly, we will set the publicPath to our file(s). This will be the endpoint on our rails web server that you can visit to reach the asset (if you don't know how this works, read the [intro](#using-webpack-bundled-assets-with-the-rails-asset-pipeline)). If you've been following the previous steps, you know that we set our outputPath for our assets to be absolute at `app/assets/webpack/webpack-assets/`, which your rails app should end up hosting at `/assets/webpack-assets/file-name+hash.ext` when the server is run.
79
79
 
80
- Note: _If you're having a hard time figuring out what an asset's path will be on your rails server, simply run `rake assets:precompile` and `cd public/`. The path from there to your file will then be the path/url on your web server to that asset. On top of this, it is also a good idea to check out [this doc](docs/outdated/rails-assets.md) to understand how `react_on_rails` allows us to access these files after precompilation, when Rails applies another hash onto the asset._
80
+ Note: _If you're having a hard time figuring out what an asset's path will be on your rails server, simply run `rake assets:precompile` and `cd public/`. The path from there to your file will then be the path/url on your web server to that asset. On top of this, it is also a good idea to check out [this doc](https://www.shakacode.com/react-on-rails/docs/outdated/rails-assets) to understand how `react_on_rails` allows us to access these files after precompilation, when Rails applies another hash onto the asset._
81
81
 
82
82
  Our publicPath setting will match the path to our outputted assets on our rails web server. Given our assets in this example will be outputted to `/app/assets/webpack/webpack-assets/` and hosted at `/assets/webpack-assets/`, our publicPath would be:
83
83
 
@@ -179,7 +179,7 @@ module.exports = {
179
179
  // The important stuff
180
180
  test: /\.(jpg|jpeg|png)(\?.*)?$/, // Load only .jpg .jpeg, and .png files
181
181
  use: {
182
- loader: 'file-loader',
182
+ loader: 'file-loader',
183
183
  options: {
184
184
  name: '[name][md5:hash].[ext]', // Name of bundled asset
185
185
  outputPath: 'webpack-assets/', // Output location for assets. Final: `app/assets/webpack/webpack-assets/`
@@ -192,4 +192,4 @@ module.exports = {
192
192
  };
193
193
  ```
194
194
 
195
- If you'd like to understand how react_on_rails handles these bundled assets after asset precompilation and in production mode, check out: [Rails Assets](docs/outdated/rails-assets.md).
195
+ If you'd like to understand how react_on_rails handles these bundled assets after asset precompilation and in production mode, check out: [Rails Assets](https://www.shakacode.com/react-on-rails/docs/outdated/rails-assets).
@@ -13,24 +13,24 @@ CSS and fonts for CSS. However, this applies to any file that might be processed
13
13
  Webpack file loader.
14
14
 
15
15
  ## The Problem
16
- To understand the problem, it helps to read this article:
16
+ To understand the problem, it helps to read this article:
17
17
  [What is fingerprinting and why should I care](http://guides.rubyonrails.org/asset_pipeline.html#what-is-fingerprinting-and-why-should-i-care-questionmark)
18
18
  Basically, when Rails prepares assets for production deployments, it also adds a digest
19
- to the file names. E.g., `img1.jpg` becomes `img1-dbu097452jf2v2.jpg`.
19
+ to the file names. E.g., `img1.jpg` becomes `img1-dbu097452jf2v2.jpg`.
20
20
 
21
- When compiling its native css Rails transforms all urls and links to digested
22
- versions, i.e. `background-image: image-url(img1.jpg)` becomes
23
- `background-image: url(img1-dbu097452jf2v2.jpg)`. However this doesn't happen for js and
24
- css files compiled by webpack on the client side, because they don't use
21
+ When compiling its native css Rails transforms all urls and links to digested
22
+ versions, i.e. `background-image: image-url(img1.jpg)` becomes
23
+ `background-image: url(img1-dbu097452jf2v2.jpg)`. However this doesn't happen for js and
24
+ css files compiled by webpack on the client side, because they don't use
25
25
  `image-url` and `asset-url`. Without some fix, these assets would fail to load.
26
26
 
27
- When Webpack's client JavaScript uses images in render methods, e.g. `<img src='...' />` or
27
+ When Webpack's client JavaScript uses images in render methods, e.g. `<img src='...' />` or
28
28
  in css, e.g. `background-image: url(...)` The code (such as the CSS) generated by the Webpack
29
29
  will have the Webpack digested name (MD5 hash). Since the Webpack generated CSS expects
30
30
  just one level of "digesting", this "double-digesting" from Rails will cause such these assets
31
31
  fail to load.
32
32
 
33
- _If you are interested in learning how to use assets in your React components, read this doc: [Webpack, the Asset Pipeline, and Using Assets w/ React](../additional-reading/rails-assets-relative-paths.md)._
33
+ _If you are interested in learning how to use assets in your React components, read this doc: [Webpack, the Asset Pipeline, and Using Assets w/ React](https://www.shakacode.com/react-on-rails/docs/outdated/rails-assets-relative-paths)_
34
34
 
35
35
  ## The Solution: Symlink Original File Names to New File Names
36
36
  _Note, this solution was removed in v14. If you're intersted in this symlink solution, please create
@@ -1,9 +1,9 @@
1
1
  # Rails 3
2
2
 
3
- * Please let us know if you find any issues with Rails 3.
3
+ * Please let us know if you find any issues with Rails 3.
4
4
  * Rails 3 is confirmed to work up with versions up to 6.8.x.
5
5
  * We are not testing it for new releases. If you find an issue, you will have to submit a PR to get it fixed.
6
6
 
7
7
  ## Known Issues
8
8
 
9
- 1. If you do not skip bootstrap for the generator, you cannot generate a working app, as bootstrap-sass does not not support Rails 3, or at least the version we're using.
9
+ 1. If you do not skip bootstrap for the generator, you cannot generate a working app, as bootstrap-sass does not support Rails 3, or at least the version we're using.
@@ -0,0 +1,182 @@
1
+ # Rails/Webpacker React Integration Options
2
+
3
+ You only _need_ props hydration if you need SSR. However, there's no good reason to
4
+ have your app make a second round trip to the Rails server to get initialization props.
5
+
6
+ **Server-Side Rendering (SSR)** results in Rails rendering HTML for your React components. The main reasons to use SSR are better SEO and pages display more quickly.
7
+
8
+ These gems provide advanced integration of React with [rails/webpacker](https://github.com/rails/webpacker):
9
+
10
+ | Gem | Props Hydration | Server-Side-Rendering (SSR) | SSR with HMR | SSR with React-Router | SSR with Code Splitting | Node SSR |
11
+ | --- | --------------- | --- | --------------------- | ----------------------| ------------------------|----|
12
+ | [shakacode/react_on_rails](https://github.com/shakacode/react_on_rails) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
13
+ | [react-rails](https://github.com/reactjs/react-rails) | ✅ | ✅ | | | | | |
14
+ | [webpacker-react](https://github.com/renchap/webpacker-react) | ✅ | | | | | | |
15
+
16
+ Note, Node SSR for React on Rails requires [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro).
17
+
18
+ ---
19
+
20
+ As mentioned, you don't _need_ to use a gem to integrate Rails with React.
21
+
22
+ If you're not concerned with view helpers to pass props or server rendering, can do it yourself:
23
+
24
+ ```erb
25
+ <%# views/layouts/application.html.erb %>
26
+
27
+ <%= content_tag :div,
28
+ id: "hello-react",
29
+ data: {
30
+ message: 'Hello!',
31
+ name: 'David'
32
+ }.to_json do %>
33
+ <% end %>
34
+ ```
35
+
36
+ ```js
37
+ // app/javascript/packs/hello_react.js
38
+
39
+ const Hello = props => (
40
+ <div className='react-app-wrapper'>
41
+ <img src={clockIcon} alt="clock" />
42
+ <h5 className='hello-react'>
43
+ {props.message} {props.name}!
44
+ </h5>
45
+ </div>
46
+ )
47
+
48
+ // Render component with data
49
+ document.addEventListener('DOMContentLoaded', () => {
50
+ const node = document.getElementById('hello-react')
51
+ const data = JSON.parse(node.getAttribute('data'))
52
+
53
+ ReactDOM.render(<Hello {...data} />, node)
54
+ })
55
+ ```
56
+
57
+ ----
58
+
59
+ ## HMR and React Hot Reloading
60
+
61
+ Before turning HMR on, consider upgrading to the latest stable gems and packages:
62
+ https://github.com/rails/webpacker#upgrading
63
+
64
+ Configure `config/webpacker.yml` file:
65
+
66
+ ```yaml
67
+ development:
68
+ extract_css: false
69
+ dev_server:
70
+ hmr: true
71
+ inline: true
72
+ ```
73
+
74
+ This basic configuration alone will have HMR working with the default webpacker setup. However, an code saves will trigger a full page refresh each time you save a file.
75
+
76
+ Webpack's HMR allows the replacement of modules for React in-place without reloading the browser. To do this, you have two options:
77
+
78
+ 1. Steps below for the [github.com/pmmmwh/react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin).
79
+ 1. Deprecated steps below for using the [github.com/gaearon/react-hot-loader](https://github.com/gaearon/react-hot-loader).
80
+
81
+ ### React Refresh Webpack Plugin
82
+ [github.com/pmmmwh/react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin)
83
+
84
+ You can see an example commit of adding this [here](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/commit/7e53803fce7034f5ecff335db1f400a5743a87e7).
85
+
86
+ 1. Add react refresh packages:
87
+ `yarn add @pmmmwh/react-refresh-webpack-plugin react-refresh -D`
88
+ 2. Update `babel.config.js` adding
89
+ ```js
90
+ plugins: [
91
+ process.env.WEBPACK_DEV_SERVER && 'react-refresh/babel',
92
+ // other plugins
93
+ ```
94
+ 3. Update `config/webpack/development.js`, only including the plugin if running the WEBPACK_DEV_SERVER
95
+ ```js
96
+ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
97
+ const environment = require('./environment')
98
+
99
+ const isWebpackDevServer = process.env.WEBPACK_DEV_SERVER;
100
+
101
+ //plugins
102
+ if (isWebpackDevServer) {
103
+ environment.plugins.append(
104
+ 'ReactRefreshWebpackPlugin',
105
+ new ReactRefreshWebpackPlugin({
106
+ overlay: {
107
+ sockPort: 3035
108
+ }
109
+ })
110
+ );
111
+ }
112
+ ```
113
+
114
+ ### React Hot Loader (Deprecated)
115
+
116
+ 1. Add the `react-hot-loader` and ` @hot-loader/react-dom` npm packages.
117
+ ```sh
118
+ yarn add --dev react-hot-loader @hot-loader/react-dom
119
+ ```
120
+
121
+ 2. Update your babel config, `babel.config.js`. Add the plugin `react-hot-loader/babel`
122
+ with option `"safetyNet": false`:
123
+
124
+ ```
125
+ {
126
+ "plugins": [
127
+ [
128
+ "react-hot-loader/babel",
129
+ {
130
+ "safetyNet": false
131
+ }
132
+ ]
133
+ ]
134
+ }
135
+ ```
136
+
137
+ 3. Add changes like this to your entry points:
138
+
139
+ ```diff
140
+ // app/javascript/app.jsx
141
+
142
+ import React from 'react';
143
+ + import { hot } from 'react-hot-loader/root';
144
+
145
+ const App = () => <SomeComponent(s) />
146
+
147
+ - export default App;
148
+ + export default hot(App);
149
+ ```
150
+
151
+ 4. Adjust your webpack configuration for development so that `sourceMapContents` option for the sass
152
+ loader is `false`:
153
+
154
+ ```diff
155
+ // config/webpack/development.js
156
+
157
+ process.env.NODE_ENV = process.env.NODE_ENV || 'development'
158
+
159
+ const environment = require('./environment')
160
+
161
+ // allows for editing sass/scss files directly in browser
162
+ + if (!module.hot) {
163
+ + environment.loaders.get('sass').use.find(item => item.loader === 'sass-loader').options.sourceMapContents = false
164
+ + }
165
+ +
166
+ module.exports = environment.toWebpackConfig()
167
+ ```
168
+
169
+ 5. Adjust your `config/webpack/environment.js` for a
170
+
171
+ ```diff
172
+ // config/webpack/environment.js
173
+
174
+ // ...
175
+
176
+ // Fixes: React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work.
177
+ // https://github.com/gaearon/react-hot-loader/issues/1227#issuecomment-482139583
178
+ + environment.config.merge({ resolve: { alias: { 'react-dom': '@hot-loader/react-dom' } } });
179
+
180
+ module.exports = environment;
181
+ ```
182
+
@@ -16,4 +16,4 @@ Rails will start creating the app and will skip the files you have already creat
16
16
  3. If it is removeing some of your code then press "n" and add all additions manually
17
17
  ```
18
18
 
19
- 3. Run `bundle install` and follow [the instructions for installing into an existing Rails app](../basics/installation-into-an-existing-rails-app.md).*
19
+ 3. Run `bundle install` and follow [the instructions for installing into an existing Rails app](https://www.shakacode.com/react-on-rails/docs/basics/installation-into-an-existing-rails-app)