react_on_rails 13.4.0 → 14.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -2
- data/Gemfile.development_dependencies +10 -8
- data/README.md +2 -2
- data/lib/generators/react_on_rails/base_generator.rb +10 -2
- data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/shakapacker.yml +1 -1
- data/lib/generators/react_on_rails/templates/dev_tests/spec/rails_helper.rb +2 -2
- data/lib/generators/react_on_rails/templates/dev_tests/spec/system/hello_world_spec.rb +1 -1
- data/lib/react_on_rails/configuration.rb +39 -25
- data/lib/react_on_rails/git_utils.rb +3 -3
- data/lib/react_on_rails/helper.rb +2 -2
- data/lib/react_on_rails/json_output.rb +0 -17
- data/lib/react_on_rails/locales/base.rb +4 -4
- data/lib/react_on_rails/locales/to_js.rb +1 -1
- data/lib/react_on_rails/packs_generator.rb +2 -4
- data/lib/react_on_rails/react_component/render_options.rb +1 -1
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +9 -9
- data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +3 -3
- data/lib/react_on_rails/test_helper.rb +2 -2
- data/lib/react_on_rails/utils.rb +2 -8
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker.rb +2 -2
- data/lib/react_on_rails/webpacker_utils.rb +6 -0
- data/lib/tasks/assets.rake +1 -1
- data/react_on_rails.gemspec +4 -4
- metadata +4 -132
- data/.bookignore +0 -15
- data/.circleci/config.yml +0 -338
- data/.coveralls.yml +0 -1
- data/.dockerignore +0 -2
- data/.eslintignore +0 -17
- data/.eslintrc +0 -53
- data/.github/FUNDING.yml +0 -1
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -23
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -19
- data/.github/workflows/lint-js-and-ruby.yml +0 -54
- data/.github/workflows/main.yml +0 -183
- data/.github/workflows/package-js-tests.yml +0 -35
- data/.github/workflows/rspec-package-specs.yml +0 -46
- data/.gitignore +0 -33
- data/.npmignore +0 -22
- data/.prettierignore +0 -14
- data/.prettierrc +0 -20
- data/.rspec +0 -2
- data/.rubocop.yml +0 -134
- data/.scss-lint.yml +0 -205
- data/.travis.yml +0 -61
- data/book.json +0 -18
- data/docs/additional-details/generator-details.md +0 -56
- data/docs/additional-details/manual-installation-overview.md +0 -30
- data/docs/additional-details/migrating-from-react-rails.md +0 -17
- data/docs/additional-details/recommended-project-structure.md +0 -69
- data/docs/additional-details/tips-for-usage-with-sp6.md +0 -15
- data/docs/additional-details/updating-dependencies.md +0 -31
- data/docs/additional-details/upgrade-webpacker-v3-to-v4.md +0 -10
- data/docs/api/javascript-api.md +0 -99
- data/docs/api/redux-store-api.md +0 -102
- data/docs/api/view-helpers-api.md +0 -133
- data/docs/contributor-info/errors-with-hooks.md +0 -45
- data/docs/contributor-info/generator-testing.md +0 -11
- data/docs/contributor-info/linters.md +0 -68
- data/docs/contributor-info/pull-requests.md +0 -42
- data/docs/contributor-info/releasing.md +0 -76
- data/docs/deployment/elastic-beanstalk.md +0 -63
- data/docs/deployment/heroku-deployment.md +0 -39
- data/docs/getting-started.md +0 -196
- data/docs/guides/client-vs-server-rendering.md +0 -27
- data/docs/guides/configuration.md +0 -289
- data/docs/guides/deployment.md +0 -5
- data/docs/guides/file-system-based-automated-bundle-generation.md +0 -197
- data/docs/guides/hmr-and-hot-reloading-with-the-webpack-dev-server.md +0 -104
- data/docs/guides/how-react-on-rails-works.md +0 -44
- data/docs/guides/how-to-conditionally-server-render-based-on-device-type.md +0 -40
- data/docs/guides/how-to-use-different-files-for-client-and-server-rendering.md +0 -98
- data/docs/guides/i18n.md +0 -87
- data/docs/guides/installation-into-an-existing-rails-app.md +0 -66
- data/docs/guides/minitest-configuration.md +0 -31
- data/docs/guides/rails-webpacker-react-integration-options.md +0 -213
- data/docs/guides/react-on-rails-overview.md +0 -29
- data/docs/guides/react-server-rendering.md +0 -32
- data/docs/guides/render-functions-and-railscontext.md +0 -205
- data/docs/guides/rspec-configuration.md +0 -73
- data/docs/guides/tutorial.md +0 -371
- data/docs/guides/upgrading-react-on-rails.md +0 -304
- data/docs/guides/webpack-configuration.md +0 -42
- data/docs/home.md +0 -23
- data/docs/javascript/angular-js-integration-migration.md +0 -28
- data/docs/javascript/asset-pipeline.md +0 -12
- data/docs/javascript/capistrano-deployment.md +0 -18
- data/docs/javascript/code-splitting.md +0 -165
- data/docs/javascript/converting-from-custom-webpack-config-to-rails-webpacker-config.md +0 -10
- data/docs/javascript/credits.md +0 -10
- data/docs/javascript/foreman-issues.md +0 -15
- data/docs/javascript/images.md +0 -57
- data/docs/javascript/node-dependencies-and-npm.md +0 -19
- data/docs/javascript/react-and-redux.md +0 -36
- data/docs/javascript/react-helmet.md +0 -100
- data/docs/javascript/react-router.md +0 -90
- data/docs/javascript/server-rendering-tips.md +0 -55
- data/docs/javascript/troubleshooting-when-using-shakapacker.md +0 -77
- data/docs/javascript/troubleshooting-when-using-webpacker.md +0 -90
- data/docs/javascript/webpack-v1-notes.md +0 -23
- data/docs/javascript/webpack.md +0 -22
- data/docs/misc/articles.md +0 -20
- data/docs/misc/code_of_conduct.md +0 -13
- data/docs/misc/doctrine.md +0 -77
- data/docs/misc/style.md +0 -33
- data/docs/misc/tips.md +0 -10
- data/docs/outdated/deferred-rendering.md +0 -39
- data/docs/outdated/rails-assets-relative-paths.md +0 -195
- data/docs/outdated/rails-assets.md +0 -77
- data/docs/outdated/rails3.md +0 -9
- data/docs/rails/convert-rails-5-api-only-app.md +0 -19
- data/docs/rails/rails-engine-integration.md +0 -32
- data/docs/rails/rails_view_rendering_from_inline_javascript.md +0 -36
- data/docs/rails/turbolinks.md +0 -124
- data/docs/react-on-rails-pro/react-on-rails-pro.md +0 -43
- data/docs/testimonials/hvmn.md +0 -25
- data/docs/testimonials/resortpass.md +0 -13
- data/docs/testimonials/testimonials.md +0 -28
- data/jest.config.js +0 -4
- data/package-scripts.yml +0 -49
- data/package.json +0 -96
- data/rakelib/docker.rake +0 -26
- data/rakelib/dummy_apps.rake +0 -30
- data/rakelib/example_type.rb +0 -96
- data/rakelib/examples.rake +0 -64
- data/rakelib/examples_config.yml +0 -14
- data/rakelib/lint.rake +0 -30
- data/rakelib/node_package.rake +0 -15
- data/rakelib/release.rake +0 -92
- data/rakelib/run_rspec.rake +0 -103
- data/rakelib/task_helpers.rb +0 -62
- data/script/bootstrap +0 -33
- data/script/release +0 -3
- data/script/setup +0 -23
- data/script/test +0 -38
- data/webpackConfigLoader.js +0 -71
- data/yarn.lock +0 -7010
data/docs/guides/tutorial.md
DELETED
@@ -1,371 +0,0 @@
|
|
1
|
-
# React on Rails Basic Tutorial
|
2
|
-
|
3
|
-
_Also see the example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_demo_ssr_hmr)_
|
4
|
-
|
5
|
-
-----
|
6
|
-
|
7
|
-
*Updated for Ruby 2.7, Rails 7, React on Rails v13, and Shakapacker v7*
|
8
|
-
|
9
|
-
This tutorial guides you through setting up a new or existing Rails app with **React on Rails**, demonstrating Rails + React + Redux + Server Rendering.
|
10
|
-
|
11
|
-
After finishing this tutorial you will get an application that can do the following (live on Heroku):
|
12
|
-
|
13
|
-
![example](https://cloud.githubusercontent.com/assets/371302/17368567/111cc722-596b-11e6-9b72-ac5967a60e42.gif)
|
14
|
-
|
15
|
-
You can find it here:
|
16
|
-
* [Source code for this app in PR, using the --redux option](https://github.com/shakacode/react_on_rails-test-new-redux-generation/pull/17) and [for Heroku](https://github.com/shakacode/react_on_rails-test-new-redux-generation/pull/18).
|
17
|
-
* [Live on Heroku](https://react-on-rails-redux-gen-8-0-0.herokuapp.com/)
|
18
|
-
|
19
|
-
By the time you read this, the latest may have changed. Be sure to check the versions here:
|
20
|
-
|
21
|
-
* https://rubygems.org/gems/react_on_rails
|
22
|
-
* https://www.npmjs.com/package/react-on-rails
|
23
|
-
|
24
|
-
# Table of Content:
|
25
|
-
- [Installation](#installation)
|
26
|
-
- [Setting up your environment](#setting-up-your-environment)
|
27
|
-
- [Create a new Ruby on Rails App](#create-a-new-ruby-on-rails-app)
|
28
|
-
- [Add the Shakapacker and react_on_rails gems](#add-the-shakapacker-and-react_on_rails-gems)
|
29
|
-
- [Run the Shakapacker generator](#run-the-shakapacker-generator)
|
30
|
-
- [Run the React on Rails Generator](#run-the-react-on-rails-generator)
|
31
|
-
- [Setting up your environment variables](#setting-up-your-environment-variables)
|
32
|
-
- [Running the app](#running-the-app)
|
33
|
-
- [HMR vs. React Hot Reloading](#hmr-vs-react-hot-reloading)
|
34
|
-
- [Deploying to Heroku](#deploying-to-heroku)
|
35
|
-
- [Create Your Heroku App](#create-your-heroku-app)
|
36
|
-
- [Swap out sqlite for postgres](#swap-out-sqlite-for-postgres)
|
37
|
-
- [Other features](#other-features)
|
38
|
-
- [Turning on Server Rendering](#turning-on-server-rendering)
|
39
|
-
- [Moving from the Rails default `/app/javascript` to the recommended `/client` structure](#moving-from-the-rails-default-appjavascript-to-the-recommended-client-structure)
|
40
|
-
- [Using HMR with the shakapacker setup](#using-hmr-with-the-shakapacker-setup)
|
41
|
-
- [Custom IP & PORT setup (Cloud9 example)](#custom-ip--port-setup-cloud9-example)
|
42
|
-
- [RubyMine performance tip](#rubymine-performance-tip)
|
43
|
-
- [Conclusion](#conclusion)
|
44
|
-
# Installation
|
45
|
-
## Setting up your environment
|
46
|
-
|
47
|
-
Trying out **React on Rails** is super easy, so long as you have the basic prerequisites.
|
48
|
-
|
49
|
-
- **Ruby:** We support all active Ruby versions but recommend using the latest stable Ruby version. Solutions like [rvm](https://rvm.io) or [rbenv](https://github.com/rbenv/rbenv) make it easy to have multiple Ruby versions on your machine.
|
50
|
-
- **Rails:** We support Rails 6 and later.
|
51
|
-
- **Nodejs:** We support all [active Node versions](https://github.com/nodejs/release#release-schedule) but recommend using the latest LTS release of Nodejs for the longest support. Older inactive node versions might still work but is not guaranteed. We also recommend using [nvm](https://github.com/nvm-sh/nvm/) to ease using different node versions in different projects.
|
52
|
-
- **yarn:** We use [yarn classic](https://classic.yarnpkg.com/) as our node package manager.
|
53
|
-
- You need to have either [Overmind](https://github.com/DarthSim/overmind) or [Foreman](https://rubygems.org/gems/foreman) as a process manager.
|
54
|
-
|
55
|
-
## Create a new Ruby on Rails App
|
56
|
-
Then we need to create a fresh Rails application as follows.
|
57
|
-
|
58
|
-
First, be sure to run `rails -v` and check you are using Rails 5.1.3 or above. If you are using an older version of Rails, you'll need to install webpacker with react per the instructions [here](https://github.com/rails/webpacker).
|
59
|
-
|
60
|
-
```bash
|
61
|
-
# For Rails 6.x
|
62
|
-
rails new test-react-on-rails --skip-javascript
|
63
|
-
|
64
|
-
# For Rails 7.x
|
65
|
-
rails new test-react-on-rails --skip-javascript
|
66
|
-
|
67
|
-
cd test-react-on-rails
|
68
|
-
```
|
69
|
-
Note: You can use `--database=postgresql` option to use Postgresql for the database.
|
70
|
-
|
71
|
-
## Add the Shakapacker and react_on_rails gems
|
72
|
-
We recommend using the latest version of these gems. Otherwise, specify the
|
73
|
-
exact versions of both the gem and npm packages. In other words, don't use
|
74
|
-
the `^` or `~` in the version specifications.
|
75
|
-
|
76
|
-
```bash
|
77
|
-
bundle add react_on_rails --strict
|
78
|
-
bundle add shakapacker --strict
|
79
|
-
```
|
80
|
-
|
81
|
-
Note: The latest released React On Rails version is considered stable. Please use the latest
|
82
|
-
version to ensure you get all the security patches and the best support.
|
83
|
-
|
84
|
-
## Run the Shakapacker generator
|
85
|
-
|
86
|
-
```bash
|
87
|
-
bundle exec rails shakapacker:install
|
88
|
-
```
|
89
|
-
|
90
|
-
Commit all the changes so far to avoid getting errors in the next step.
|
91
|
-
|
92
|
-
```bash
|
93
|
-
git commit -am "Initial commit"
|
94
|
-
```
|
95
|
-
|
96
|
-
Alternatively, you can use `--ignore-warnings` in the next step.
|
97
|
-
|
98
|
-
## Run the React on Rails Generator
|
99
|
-
|
100
|
-
```bash
|
101
|
-
rails generate react_on_rails:install
|
102
|
-
```
|
103
|
-
|
104
|
-
You will be prompted to approve changes in certain files. Press `enter` to proceed
|
105
|
-
one by one or enter `a` to replace all configuration files required by the project.
|
106
|
-
You can check the diffs before you commit to see what changed.
|
107
|
-
|
108
|
-
Note, using `redux` is no longer recommended as the basic installer uses React Hooks.
|
109
|
-
If you want the redux install, run:
|
110
|
-
|
111
|
-
```bash
|
112
|
-
rails generate react_on_rails:install --redux
|
113
|
-
```
|
114
|
-
|
115
|
-
## Setting up your environment variables
|
116
|
-
|
117
|
-
Add the following variable to your environment:
|
118
|
-
|
119
|
-
```
|
120
|
-
EXECJS_RUNTIME=Node
|
121
|
-
```
|
122
|
-
|
123
|
-
Then run the server with one of the following options:
|
124
|
-
|
125
|
-
## Running the app
|
126
|
-
|
127
|
-
```bash
|
128
|
-
./bin/dev # For HMR
|
129
|
-
# or
|
130
|
-
./bin/dev-static # Without HMR, statically creating the bundles
|
131
|
-
```
|
132
|
-
|
133
|
-
Visit [http://localhost:3000/hello_world](http://localhost:3000/hello_world) and see your **React On Rails** app running!
|
134
|
-
|
135
|
-
# HMR vs. React Hot Reloading
|
136
|
-
|
137
|
-
First, check that the `hmr` and the `inline` options are `true` in your `config/shakapacker.yml` file.
|
138
|
-
|
139
|
-
The basic setup will have HMR working with the default Shakapacker setup. The basic
|
140
|
-
[HMR](https://webpack.js.org/concepts/hot-module-replacement/), without a special
|
141
|
-
React setup, will cause a full page refresh each time you save a file.
|
142
|
-
|
143
|
-
# Deploying to Heroku
|
144
|
-
|
145
|
-
## Create Your Heroku App
|
146
|
-
*Assuming you can log in to heroku.com and have logged into your shell for Heroku.*
|
147
|
-
|
148
|
-
1. Visit [https://dashboard.heroku.com/new](https://dashboard.heroku.com/new) and create an app, say named `my-name-react-on-rails`:
|
149
|
-
|
150
|
-
![06](https://cloud.githubusercontent.com/assets/20628911/17465014/1f29bf3c-5cf4-11e6-869f-4215987ae854.png)
|
151
|
-
|
152
|
-
Run this command that looks like this from your new Heroku app
|
153
|
-
|
154
|
-
```bash
|
155
|
-
heroku git:remote -a my-name-react-on-rails
|
156
|
-
```
|
157
|
-
|
158
|
-
Set heroku to use multiple buildpacks:
|
159
|
-
|
160
|
-
```bash
|
161
|
-
heroku buildpacks:set heroku/ruby
|
162
|
-
heroku buildpacks:add --index 1 heroku/nodejs
|
163
|
-
```
|
164
|
-
|
165
|
-
## Swap out sqlite for postgres:
|
166
|
-
Heroku requires your app to use Postgresql. If you have not setup your app
|
167
|
-
with Postgresql, you need to change your app settings to use this database.
|
168
|
-
|
169
|
-
Run the following command (in Rails 6+):
|
170
|
-
|
171
|
-
```bash
|
172
|
-
rails db:system:change --to=postgresql
|
173
|
-
```
|
174
|
-
|
175
|
-
If for any reason you want to do this process manually, run these two commands:
|
176
|
-
|
177
|
-
```bash
|
178
|
-
bundle remove sqlite3
|
179
|
-
bundle add pg
|
180
|
-
```
|
181
|
-
|
182
|
-
![07](https://cloud.githubusercontent.com/assets/20628911/17465015/1f2f4042-5cf4-11e6-8287-2fb077550809.png)
|
183
|
-
|
184
|
-
Now replace your `database.yml` file with this (assuming your app name is "ror").
|
185
|
-
|
186
|
-
```yml
|
187
|
-
default: &default
|
188
|
-
adapter: postgresql
|
189
|
-
username:
|
190
|
-
password:
|
191
|
-
host: localhost
|
192
|
-
|
193
|
-
development:
|
194
|
-
<<: *default
|
195
|
-
database: ror_development
|
196
|
-
|
197
|
-
# Warning: The database defined as "test" will be erased and
|
198
|
-
# re-generated from your development database when you run "rake".
|
199
|
-
# Do not set this db to the same as development or production.
|
200
|
-
test:
|
201
|
-
<<: *default
|
202
|
-
database: ror_test
|
203
|
-
|
204
|
-
production:
|
205
|
-
<<: *default
|
206
|
-
database: ror_production
|
207
|
-
```
|
208
|
-
|
209
|
-
Then you need to setup postgres so you can run locally:
|
210
|
-
|
211
|
-
```bash
|
212
|
-
rake db:setup
|
213
|
-
rake db:migrate
|
214
|
-
```
|
215
|
-
|
216
|
-
![08](https://cloud.githubusercontent.com/assets/20628911/17465016/1f3559f0-5cf4-11e6-8ab4-c5572e4644a5.png)
|
217
|
-
|
218
|
-
Optionally you can add this line to your `routes.rb`. That way, your root page will go to the Hello World page for React On Rails.
|
219
|
-
|
220
|
-
```ruby
|
221
|
-
root "hello_world#index"
|
222
|
-
```
|
223
|
-
|
224
|
-
![09](https://cloud.githubusercontent.com/assets/20628911/17465018/1f3b685e-5cf4-11e6-93f8-105fc48517d0.png)
|
225
|
-
|
226
|
-
Next, configure your app for Puma, per the [instructions on Heroku](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server).
|
227
|
-
|
228
|
-
Create `./Procfile` with the following content. This is what Heroku uses to start your app.
|
229
|
-
|
230
|
-
```
|
231
|
-
web: bundle exec puma -C config/puma.rb
|
232
|
-
```
|
233
|
-
|
234
|
-
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 2020-06-04, the docs looked like this:
|
235
|
-
|
236
|
-
`config/puma.rb`
|
237
|
-
```rb
|
238
|
-
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
|
239
|
-
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
|
240
|
-
threads threads_count, threads_count
|
241
|
-
|
242
|
-
preload_app!
|
243
|
-
|
244
|
-
rackup DefaultRackup
|
245
|
-
port ENV['PORT'] || 3000
|
246
|
-
environment ENV['RACK_ENV'] || 'development'
|
247
|
-
|
248
|
-
on_worker_boot do
|
249
|
-
# Worker specific setup for Rails 4.1+
|
250
|
-
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
|
251
|
-
ActiveRecord::Base.establish_connection
|
252
|
-
end
|
253
|
-
```
|
254
|
-
|
255
|
-
Next, update your `package.json` to specify the version of yarn and node. Add this section:
|
256
|
-
|
257
|
-
```json
|
258
|
-
"engines": {
|
259
|
-
"node": "16.19.0",
|
260
|
-
"yarn": "1.22.4"
|
261
|
-
},
|
262
|
-
```
|
263
|
-
|
264
|
-
Then after all changes are done don't forget to commit them with git and finally, you can push your app to Heroku!
|
265
|
-
|
266
|
-
```bash
|
267
|
-
git add -A
|
268
|
-
git commit -m "Changes for Heroku"
|
269
|
-
git push heroku master
|
270
|
-
```
|
271
|
-
|
272
|
-
Then run:
|
273
|
-
|
274
|
-
```bash
|
275
|
-
heroku open
|
276
|
-
```
|
277
|
-
|
278
|
-
and you will see your live app and you can share this URL with your friends. Congrats!
|
279
|
-
|
280
|
-
# Other features
|
281
|
-
## Turning on Server Rendering
|
282
|
-
|
283
|
-
You can turn on server rendering by simply changing the `prerender` option to `true`:
|
284
|
-
|
285
|
-
```erb
|
286
|
-
<%= react_component("HelloWorld", props: @hello_world_props, prerender: true) %>
|
287
|
-
```
|
288
|
-
|
289
|
-
If you want to test this out with HMR, then you also need to add this line to your
|
290
|
-
`config/intializers/react_on_rails.rb`
|
291
|
-
|
292
|
-
```ruby
|
293
|
-
config.same_bundle_for_client_and_server = true
|
294
|
-
```
|
295
|
-
|
296
|
-
More likely, you will create a different build file for server rendering. However, if you want to
|
297
|
-
use the same file from the shakapack-dev-server, you'll need to add that line.
|
298
|
-
|
299
|
-
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:
|
300
|
-
|
301
|
-
```html
|
302
|
-
<div id="HelloWorld-react-component-b7ae1dc6-396c-411d-886a-269633b3f604"></div>
|
303
|
-
```
|
304
|
-
|
305
|
-
versus with server rendering:
|
306
|
-
|
307
|
-
```html
|
308
|
-
<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>
|
309
|
-
```
|
310
|
-
|
311
|
-
For more details on server rendering, see:
|
312
|
-
|
313
|
-
+ [Client vs. Server Rendering](https://www.shakacode.com/react-on-rails/docs/guides/client-vs-server-rendering/)
|
314
|
-
+ [React Server Rendering](https://www.shakacode.com/react-on-rails/docs/guides/react-server-rendering/)
|
315
|
-
|
316
|
-
## Moving from the Rails default `/app/javascript` to the recommended `/client` structure
|
317
|
-
|
318
|
-
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.
|
319
|
-
|
320
|
-
|
321
|
-
1. Move the directory:
|
322
|
-
|
323
|
-
```bash
|
324
|
-
mv app/javascript client
|
325
|
-
```
|
326
|
-
|
327
|
-
2. Edit your `/config/shakapacker.yml` file. Change the `default/source_path`:
|
328
|
-
|
329
|
-
```yml
|
330
|
-
source_path: client
|
331
|
-
```
|
332
|
-
|
333
|
-
## Using HMR with the shakapacker setup
|
334
|
-
|
335
|
-
Start the app using `overmind start -f Procfile.dev` or `foreman start -f Procfile.dev`.
|
336
|
-
|
337
|
-
When you change and save a JSX file, the browser will automatically refresh!
|
338
|
-
|
339
|
-
So you get some basics from HMR with no code changes. If you want to go further, take a look at these links:
|
340
|
-
|
341
|
-
* [webpack-dev-server](https://github.com/rails/webpacker/blob/5-x-stable/docs/webpack-dev-server.md)
|
342
|
-
* [DevServer](https://webpack.js.org/configuration/dev-server/)
|
343
|
-
* [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/)
|
344
|
-
|
345
|
-
React on Rails will automatically handle disabling server rendering if there is only one bundle file created by the Webpack development server by `shakapcker`.
|
346
|
-
|
347
|
-
|
348
|
-
## Custom IP & PORT setup (Cloud9 example)
|
349
|
-
|
350
|
-
In case you are running some custom setup with different IP or PORT you should also edit Procfile.dev. For example, to be able to run on free Cloud9 IDE we are putting IP 0.0.0.0 and PORT 8080. The default generated file `Procfile.dev` uses `-p 3000`.
|
351
|
-
|
352
|
-
``` Procfile.dev
|
353
|
-
web: rails s -p 8080 -b 0.0.0.0
|
354
|
-
```
|
355
|
-
|
356
|
-
Then visit https://your-shared-addr.c9users.io:8080/hello_world
|
357
|
-
|
358
|
-
## RubyMine performance tip
|
359
|
-
|
360
|
-
It's super important to exclude certain directories from RubyMine or else it will slow to a crawl as it tries to parse all the npm files.
|
361
|
-
|
362
|
-
* Generated files, per the settings in your `config/shakapacker.yml`, which default to `public/packs` and `public/packs-test`
|
363
|
-
* `node_modules`
|
364
|
-
|
365
|
-
# Conclusion
|
366
|
-
|
367
|
-
* Browse the docs on [our documentation website](https://www.shakacode.com/react-on-rails/docs/)
|
368
|
-
|
369
|
-
Feedback is greatly appreciated! As are stars on github!
|
370
|
-
|
371
|
-
If you want personalized help, don't hesitate to get in touch with us at [contact@shakacode.com](mailto:contact@shakacode.com). We offer [React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki) and consulting so you can focus on your app and not on how to make Webpack plus Rails work optimally.
|
@@ -1,304 +0,0 @@
|
|
1
|
-
# Upgrading React on Rails
|
2
|
-
|
3
|
-
## Need Help Migrating?
|
4
|
-
If you would like help in migrating between React on Rails versions or help with implementing server rendering, please contact [justin@shakacode.com](mailto:justin@shakacode.com) for more information about our [React on Rails Pro Support](https://www.shakacode.com/react-on-rails-pro).
|
5
|
-
|
6
|
-
We specialize in helping companies to quickly and efficiently upgrade. The older versions use the Rails asset pipeline to package client assets. The current and recommended way is to use Webpack 4+ for asset preparation. You may also need help migrating from the `rails/webpacker`'s Webpack configuration to a better setup ready for Server Side Rendering.
|
7
|
-
|
8
|
-
## Upgrading to v13
|
9
|
-
|
10
|
-
### Breaking Change
|
11
|
-
Previously, the gem `webpacker` was a Gem dependency.
|
12
|
-
|
13
|
-
v13 has changed slightly to switch to `shakapacker`.
|
14
|
-
|
15
|
-
For details, see the Shakapacker guide to upgrading to [version 6](https://github.com/shakacode/shakapacker/blob/master/docs/v6_upgrade.md) and [version 7](https://github.com/shakacode/shakapacker/blob/master/docs/v7_upgrade.md)
|
16
|
-
|
17
|
-
In summary:
|
18
|
-
|
19
|
-
1. Change the gem reference from 'webpacker' to 'shakapacker'
|
20
|
-
2. Change the npm reference from '@rails/webpacker' to 'shakapacker'
|
21
|
-
3. Other updates, depending on what version of `rails/webpacker` that you had.
|
22
|
-
|
23
|
-
## Upgrading to v12
|
24
|
-
### Recent versions
|
25
|
-
Make sure that you are on a relatively more recent version of rails and webpacker. Yes, the [rails/webpacker](https://github.com/rails/webpacker) gem is required!
|
26
|
-
v12 is tested on Rails 6. It should work on Rails v5. If you're on any older version,
|
27
|
-
and v12 doesn't work, please file an issue.
|
28
|
-
|
29
|
-
### Removed Configuration config.symlink_non_digested_assets_regex
|
30
|
-
Remove `config.symlink_non_digested_assets_regex` from your `config/initializers/react_on_rails.rb`.
|
31
|
-
If you still need that feature, please file an issue.
|
32
|
-
|
33
|
-
### i18n default format changed to JSON
|
34
|
-
* If you're using the internalization helper, then set `config.i18n_output_format = 'js'`. You can
|
35
|
-
later update to the default JSON format as you will need to update your usage of that file. A JSON
|
36
|
-
format is more efficient.
|
37
|
-
|
38
|
-
### Updated API for `ReactOnRails.register()`
|
39
|
-
|
40
|
-
In order to solve the issues regarding React Hooks compatibility, the number of parameters
|
41
|
-
for functions is used to determine if you have a Render-Function that will get invoked to
|
42
|
-
return a React component, or you are registering a React component defined by a function.
|
43
|
-
Please see [Render-Functions and the Rails Context](https://www.shakacode.com/react-on-rails/docs/guides/render-functions-and-railscontext/) for
|
44
|
-
more information on what a Render-Function is.
|
45
|
-
|
46
|
-
##### Update required for registered functions taking exactly 2 params.
|
47
|
-
|
48
|
-
Registered Objects are of the following type:
|
49
|
-
1. **Function that takes only zero or one params and you return a React Element**, often JSX. If the function takes zero or one params, there is **no migration needed** for that function.
|
50
|
-
```js
|
51
|
-
export default (props) => <Component {...props} />;
|
52
|
-
```
|
53
|
-
|
54
|
-
2. **Function that takes only zero or one params and you return an Object (_not a React Element_)**. If the function takes zero or one params, **you need to add one or two unused params so you have exactly 2 params** and then that function will be treated as a render function and it can return an Object rather than a React element. If you don't do this, you'll see this obscure error message:
|
55
|
-
|
56
|
-
```
|
57
|
-
[SERVER] message: Objects are not valid as a React child (found: object with keys {renderedHtml}). If you meant to render a collection of children, use an array instead.
|
58
|
-
in YourComponentRenderFunction
|
59
|
-
```
|
60
|
-
|
61
|
-
So look in YourComponentRenderFunction and do this change
|
62
|
-
|
63
|
-
```js
|
64
|
-
export default (props) => { renderedHTML: getRenderedHTML };
|
65
|
-
```
|
66
|
-
|
67
|
-
To have exactly 2 arguments:
|
68
|
-
|
69
|
-
```js
|
70
|
-
export default (props, _railsContext) => { renderedHTML: getRenderedHTML };
|
71
|
-
```
|
72
|
-
|
73
|
-
3. Function that takes **2 params** and returns **a React function or class component**. _Migration is needed as the older syntax returned a React Element._
|
74
|
-
A function component is a function that takes zero or one params and returns a React Element, like JSX. The correct syntax
|
75
|
-
looks like:
|
76
|
-
```js
|
77
|
-
export default (props, railsContext) => () => <Component {{...props, railsContext}} />;
|
78
|
-
```
|
79
|
-
Note, you cannot return a React Element (JSX). See below for the migration steps. If your function that took **two params returned
|
80
|
-
an Object**, then no migration is required.
|
81
|
-
4. Function that takes **3 params** and uses the 3rd param, `domNodeId`, to call `ReactDOM.hydrate`. If the function takes 3 params, there is **no migration needed** for that function.
|
82
|
-
5. ES6 or ES5 class. There is **no migration needed**.
|
83
|
-
|
84
|
-
Previously, with case number 2, you could return a React Element.
|
85
|
-
|
86
|
-
The fix is simple. Here is an example of the change you'll do:
|
87
|
-
|
88
|
-
![2020-07-07_09-43-51 (1)](https://user-images.githubusercontent.com/1118459/86927351-eff79e80-c0ce-11ea-9172-d6855c45e2bb.png)
|
89
|
-
|
90
|
-
##### Broken, as this function takes two params and it returns a React Element from a JSX Literal
|
91
|
-
```js
|
92
|
-
export default (props, railsContext) => <Component {{...props, railsContext} />;
|
93
|
-
```
|
94
|
-
|
95
|
-
If you make this mistake, you'll get this warning
|
96
|
-
`Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <Fragment />. Did you accidentally export a JSX literal instead of a component?`
|
97
|
-
|
98
|
-
And this error:
|
99
|
-
`react-dom.development.js:23965 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.`
|
100
|
-
|
101
|
-
In this example, you need to wrap the `<Component {...props} />` in a function call like this which
|
102
|
-
results in the return value being a React function component.
|
103
|
-
|
104
|
-
```js
|
105
|
-
export default (props, _railsContext) => () => <Component {...props} />;
|
106
|
-
```
|
107
|
-
|
108
|
-
If you have a pure component, taking one or zero parameters, and you have an unnecessary function
|
109
|
-
wrapper such that you're returning a function rather than a React Element, then:
|
110
|
-
|
111
|
-
1. You won't see anything render.
|
112
|
-
2. You will see this warning in development mode: `Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.`
|
113
|
-
|
114
|
-
---------
|
115
|
-
|
116
|
-
## Upgrading rails/webpacker from v3 to v4
|
117
|
-
### Custom Webpack build file
|
118
|
-
The default value for `extract_css` is **false** in `config/webpack.yml`. Custom webpack builds should set this value to true or else no CSS link tags are generated. You have a custom webpack build if you are not using [rails/webpacker](https://github.com/rails/webpacker) to setup your Webpack configuration.
|
119
|
-
|
120
|
-
```yml
|
121
|
-
default: &default
|
122
|
-
# other stuff
|
123
|
-
extract_css: true
|
124
|
-
# by default, extract and emit a css file. The default is false
|
125
|
-
```
|
126
|
-
|
127
|
-
## Upgrading to version 11
|
128
|
-
* Remove `server_render_method` from config/initializers/react_on_rails.rb. Alternate server rendering methods are part of React on Rails Pro. If you want to use a custom renderer, contact justin@shakacode.com. We have a custom node rendering solution in production for egghead.io.
|
129
|
-
* Remove your usage of ENV["TRACE_REACT_ON_RAILS"] usage. You can get all tracing with either specifying **`trace`** at your component or in your config/initializers/react_on_rails.rb file.
|
130
|
-
* ReactOnRails::Utils.server_bundle_file_name and ReactOnRails::Utils.bundle_file_name were removed. React on Rails Pro contains upgrades to enable component and other types caching with React on Rails.
|
131
|
-
|
132
|
-
## Upgrading to version 10
|
133
|
-
|
134
|
-
Pretty simple:
|
135
|
-
* Follow the steps to migrate to version 9 (except installing 10.x instead of 9.x)
|
136
|
-
* If you have `react_component` returning hashes, then switch to `react_component_hash` instead
|
137
|
-
|
138
|
-
## Upgrading to version 9
|
139
|
-
|
140
|
-
### Why Webpacker?
|
141
|
-
Webpacker provides areas of value:
|
142
|
-
* View helpers that support bypassing the asset pipeline, which allows you to avoid double minification and enable source maps in production. This is 100% a best practice as source maps in production greatly increases the value of services such as HoneyBadger or Sentry.
|
143
|
-
* A default Webpack config so that you only need to do minimal modifications and customizations. However, if you're doing server rendering, you may not want to give up control. Since Webpacker's default webpack config is changing often, we at Shakacode can give you definitive advice on webpack configuration best practices. In general, if you're happy with doing your own Webpack configuration, then we suggest using the `client` strategy discussed below. Most corporate projects will prefer having more control than direct dependence on webpacker easily allows.
|
144
|
-
|
145
|
-
### Integrating Webpacker
|
146
|
-
Reason for doing this: This enables your webpack bundles to bypass the Rails asset pipeline and it's extra minification, enabling you to use source-maps in production, while still maintaining total control over everything in the client directory
|
147
|
-
|
148
|
-
#### From version 7 or lower
|
149
|
-
|
150
|
-
##### ...while keeping your `client` directory
|
151
|
-
* `.gitignore`: add `/public/webpack/*`
|
152
|
-
* `Gemfile`: bump `react_on_rails` and add `webpacker`
|
153
|
-
* layout views: anything bundled by webpack will need to be requested by a `javascript_pack_tag` or `stylesheet_pack_tag`.
|
154
|
-
* Search your codebase for javascript_include_tag. Use the
|
155
|
-
* `config/initializers/assets.rb`: we no longer need to modify `Rails.application.config.assets.paths` or append anything to `Rails.application.config.assets.precompile`.
|
156
|
-
* `config/initializers/react_on_rails.rb`:
|
157
|
-
* Delete `config.generated_assets_dir`. Webpacker's config now supplies this information
|
158
|
-
* Replace `config.npm_build_(test|production)_command` with `config.build_(test|production)_command`
|
159
|
-
* `config/webpacker.yml`: start with our [example config](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/config/webpacker.yml) (feel free to modify it as needed). I recommend setting dev_server.hmr to false however since HMR is currently broken.
|
160
|
-
* `client/package.json`: bump `react_on_rails` (I recommend bumping `webpack` as well). You'll also need `js-yaml` if you're not already using `eslint` and `webpack-manifest-plugin` regardless.
|
161
|
-
|
162
|
-
###### Client Webpack config:
|
163
|
-
* You'll need the following code to read data from the webpacker config:
|
164
|
-
|
165
|
-
```
|
166
|
-
const path = require('path');
|
167
|
-
const ManifestPlugin = require('webpack-manifest-plugin'); // we'll use this later
|
168
|
-
|
169
|
-
const webpackConfigLoader = require('react-on-rails/webpackConfigLoader');
|
170
|
-
const configPath = path.resolve('..', 'config');
|
171
|
-
const { output } = webpackConfigLoader(configPath);
|
172
|
-
```
|
173
|
-
|
174
|
-
* That output variable will be used for webpack's `output` rules:
|
175
|
-
|
176
|
-
```
|
177
|
-
output: {
|
178
|
-
filename: '[name]-[chunkhash].js', // [chunkhash] because we've got to do our own cache-busting now
|
179
|
-
path: output.path,
|
180
|
-
publicPath: output.publicPath,
|
181
|
-
},
|
182
|
-
```
|
183
|
-
|
184
|
-
* ...as well as for the output of plugins like `webpack-manifest-plugin`:
|
185
|
-
|
186
|
-
```
|
187
|
-
|
188
|
-
new ManifestPlugin({
|
189
|
-
publicPath: output.publicPath,
|
190
|
-
writeToFileEmit: true
|
191
|
-
}),
|
192
|
-
```
|
193
|
-
|
194
|
-
* If you're using referencing files or images with `url-loader` & `file-loader`, their publicpaths will have to change as well: `publicPath: '/webpack/',`
|
195
|
-
* If you're using `css-loader`, `webpack.optimize.CommonsChunkPlugin`, or `extract-text-webpack-plugin`, they will also need cache-busting!
|
196
|
-
|
197
|
-
...and you're finally done!
|
198
|
-
|
199
|
-
##### ...while replacing your `client` directory
|
200
|
-
* Make the same changes to `config/initializers/react_on_rails.rb as described above`
|
201
|
-
* Upgrade RoR & add Webpacker in the Gemfile
|
202
|
-
* Upgrade RoR in the `client/package.json`
|
203
|
-
* Run `bundle`
|
204
|
-
* Run `rails webpacker:install`
|
205
|
-
* Run `rails webpacker:install:react`
|
206
|
-
* Run `rails g react_on_rails:install`
|
207
|
-
* Move your entry point files to `app/javascript/packs`
|
208
|
-
* Either:
|
209
|
-
* Move all your source code to `app/javascript/bundles`, move your linter configs to the root directory, and then delete the `client` directory
|
210
|
-
* or just delete the webpack config and remove webpack, its loaders, and plugins from your `client/package.json`.
|
211
|
-
|
212
|
-
...and you're done.
|
213
|
-
|
214
|
-
#### From version 8
|
215
|
-
|
216
|
-
For an example of upgrading, see [react-webpack-rails-tutorial/pull/416](https://github.com/shakacode/react-webpack-rails-tutorial/pull/416).
|
217
|
-
|
218
|
-
- Breaking Configuration Changes
|
219
|
-
1. Added `config.node_modules_location` which defaults to `""` if Webpacker is installed. You may want to set this to 'client'` to `config/initializers/react_on_rails.rb` to keep your node_modules inside of `/client`
|
220
|
-
2. Renamed
|
221
|
-
* config.npm_build_test_command ==> config.build_test_command
|
222
|
-
* config.npm_build_production_command ==> config.build_production_command
|
223
|
-
|
224
|
-
- Update the gemfile. Switch over to using the webpacker gem.
|
225
|
-
|
226
|
-
```rb
|
227
|
-
gem "webpacker"
|
228
|
-
```
|
229
|
-
|
230
|
-
- Update for the renaming in the `WebpackConfigLoader` in your webpack configuration.
|
231
|
-
You will need to rename the following object properties:
|
232
|
-
- webpackOutputPath ==> output.path
|
233
|
-
- webpackPublicOutputDir ==> output.publicPath
|
234
|
-
- hotReloadingUrl ==> output.publicPathWithHost
|
235
|
-
- hotReloadingHostname ==> settings.dev_server.host
|
236
|
-
- hotReloadingPort ==> settings.dev_server.port
|
237
|
-
- hmr ==> settings.dev_server.hmr
|
238
|
-
- manifest ==> Remove this one. We use the default for Webpack of manifest.json
|
239
|
-
- env ==> Use `const { env } = require('process');`
|
240
|
-
- devBuild ==> Use `const devBuild = process.env.NODE_ENV !== 'production';`
|
241
|
-
|
242
|
-
- Edit your Webpack.config files:
|
243
|
-
- Change your Webpack output to be like this. **Be sure to have the hash or chunkhash in the filename,** unless the bundle is server side.:
|
244
|
-
```
|
245
|
-
const webpackConfigLoader = require('react-on-rails/webpackConfigLoader');
|
246
|
-
const configPath = resolve('..', 'config');
|
247
|
-
const { output, settings } = webpackConfigLoader(configPath);
|
248
|
-
const hmr = settings.dev_server.hmr;
|
249
|
-
const devBuild = process.env.NODE_ENV !== 'production';
|
250
|
-
|
251
|
-
output: {
|
252
|
-
filename: isHMR ? '[name]-[hash].js' : '[name]-[chunkhash].js',
|
253
|
-
chunkFilename: '[name]-[chunkhash].chunk.js',
|
254
|
-
|
255
|
-
publicPath: output.publicPath,
|
256
|
-
path: output.path,
|
257
|
-
},
|
258
|
-
```
|
259
|
-
- Change your ManifestPlugin definition to something like the following
|
260
|
-
```
|
261
|
-
new ManifestPlugin({
|
262
|
-
publicPath: output.publicPath,
|
263
|
-
writeToFileEmit: true
|
264
|
-
}),
|
265
|
-
|
266
|
-
```
|
267
|
-
|
268
|
-
- Find your `webpacker_lite.yml` and rename it to `webpacker.yml`
|
269
|
-
- Consider copying a default webpacker.yml setup such as https://github.com/shakacode/react-on-rails-v9-rc-generator/blob/master/config/webpacker.yml
|
270
|
-
- If you are not using the webpacker webpacker setup, be sure to put in `compile: false` in the `default` section.
|
271
|
-
- Alternately, if you are updating from webpacker_lite, you can manually change these:
|
272
|
-
- Add a default setting
|
273
|
-
```
|
274
|
-
cache_manifest: false
|
275
|
-
```
|
276
|
-
- For production, set:
|
277
|
-
```
|
278
|
-
cache_manifest: true
|
279
|
-
```
|
280
|
-
- Add a section like this under your development env:
|
281
|
-
```
|
282
|
-
dev_server:
|
283
|
-
host: localhost
|
284
|
-
port: 3035
|
285
|
-
hmr: false
|
286
|
-
```
|
287
|
-
Set hmr to your preference.
|
288
|
-
- See the example `spec/dummy/config/webpacker.yml`.
|
289
|
-
- Remove keys `hot_reloading_host` and `hot_reloading_enabled_by_default`. These are replaced by the `dev_server` key.
|
290
|
-
- Rename `webpack_public_output_dir` to `public_output_path`.
|
291
|
-
|
292
|
-
- Edit your Procfile.dev
|
293
|
-
- Remove the env value WEBPACKER_DEV_SERVER as it's not used
|
294
|
-
- For hot loading:
|
295
|
-
- Set the `hmr` key in your `webpacker.yml` to `true`.
|
296
|
-
|
297
|
-
### Without integrating webpacker
|
298
|
-
* Bump your ReactOnRails versions in `Gemfile` & `package.json`
|
299
|
-
* In `/config/initializers/react_on_rails.rb`:
|
300
|
-
* Rename `config.npm_build_test_command` ==> `config.build_test_command`
|
301
|
-
* Rename `config.npm_build_production_command` ==> `config.build_production_command`
|
302
|
-
* Add `config.node_modules_location = "client"`
|
303
|
-
|
304
|
-
...and you're done.
|