react_on_rails 13.0.0 → 13.1.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 +45 -5
- data/Gemfile.development_dependencies +1 -3
- data/NEWS.md +1 -1
- data/README.md +45 -22
- data/docs/additional-details/migrating-from-react-rails.md +1 -1
- data/docs/additional-details/recommended-project-structure.md +1 -1
- data/docs/api/view-helpers-api.md +2 -1
- data/docs/{guides/getting-started.md → getting-started.md} +4 -1
- data/docs/guides/client-vs-server-rendering.md +4 -2
- data/docs/guides/configuration.md +18 -4
- data/docs/guides/file-system-based-automated-bundle-generation.md +188 -0
- data/docs/guides/i18n.md +71 -83
- data/docs/guides/rails-webpacker-react-integration-options.md +4 -3
- data/docs/guides/react-server-rendering.md +1 -1
- data/docs/guides/tutorial.md +15 -8
- data/docs/guides/webpack-configuration.md +1 -1
- data/docs/home.md +2 -2
- data/docs/javascript/server-rendering-tips.md +0 -3
- data/lib/generators/react_on_rails/base_generator.rb +0 -1
- data/lib/generators/react_on_rails/templates/base/base/app/views/layouts/hello_world.html.erb +1 -1
- data/lib/generators/react_on_rails/templates/base/base/babel.config.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +13 -0
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/clientWebpackConfig.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/commonWebpackConfig.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/development.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/production.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt +1 -1
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/test.js.tt +7 -4
- data/lib/generators/react_on_rails/templates/base/base/config/webpack/webpackConfig.js.tt +1 -1
- data/lib/react_on_rails/configuration.rb +11 -33
- data/lib/react_on_rails/helper.rb +40 -4
- data/lib/react_on_rails/locales/base.rb +24 -1
- data/lib/react_on_rails/packs_generator.rb +298 -0
- data/lib/react_on_rails/react_component/render_options.rb +4 -0
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +0 -6
- data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +2 -0
- data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +19 -3
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/webpacker_utils.rb +14 -0
- data/lib/react_on_rails.rb +1 -0
- data/lib/tasks/generate_packs.rake +11 -0
- data/package.json +2 -2
- data/yarn.lock +5 -5
- metadata +6 -3
data/docs/guides/i18n.md
CHANGED
@@ -1,99 +1,87 @@
|
|
1
|
-
#
|
1
|
+
# Internationalization
|
2
2
|
|
3
|
-
|
3
|
+
You can use [Rails internationalization (i18n)](https://guides.rubyonrails.org/i18n.html) in your client code.
|
4
4
|
|
5
|
-
1.
|
5
|
+
1. Set `config.i18n_dir` in `config/initializers/react_on_rails.rb`:
|
6
6
|
|
7
|
-
|
7
|
+
```ruby
|
8
|
+
# Replace the following line by the directory containing your translation.js and default.js files.
|
9
|
+
config.i18n_dir = Rails.root.join("PATH_TO", "YOUR_JS_I18N_FOLDER")
|
10
|
+
```
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
If you do not want to use the YAML files from `Rails.root.join("config", "locales")` and installed gems, you can also set `config.i18n_yml_dir`:
|
13
|
+
```ruby
|
14
|
+
# Replace the following line by the location of your client i18n yml files
|
15
|
+
# Without this option, all YAML files from Rails.root.join("config", "locales") and installed gems are loaded
|
16
|
+
config.i18n_yml_dir = Rails.root.join("PATH_TO", "YOUR_YAML_I18N_FOLDER")
|
17
|
+
```
|
13
18
|
|
14
|
-
|
15
|
-
```ruby
|
16
|
-
# Replace the following line to the location where you keep your client i18n yml files
|
17
|
-
# By default(without this option), all yaml files from Rails.root.join("config", "locales") and installed gems are loaded
|
18
|
-
config.i18n_yml_dir = Rails.root.join("PATH_TO", "YOUR_YAML_I18N_FOLDER")
|
19
|
-
```
|
19
|
+
2. Add that directory (or just the generated files `translations.json` and `default.json`) to your `.gitignore`.
|
20
20
|
|
21
|
-
|
22
|
-
`default.json`: Default settings in json format.
|
21
|
+
3. The locale files must be generated before `yarn build` using `rake react_on_rails:locale`.
|
23
22
|
|
24
|
-
|
23
|
+
For development, you should adjust your startup scripts (`Procfile`s) so that they run `bundle exec rake react_on_rails:locale` before running any webpack watch process (`yarn run build:development`).
|
25
24
|
|
26
|
-
|
25
|
+
If you are not using the React on Rails test helper,
|
26
|
+
you may need to configure your CI to run `bundle exec rake react_on_rails:locale` before any webpack process as well.
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
For development, you should adjust your startup scripts (Procfiles) so that they run **`bundle exec rake react_on_rails:locale`** before running any webpack watch process (`yarn run build:development`).
|
31
|
-
|
32
|
-
You may need to configure your CI to run **`bundle exec rake react_on_rails:locale`** before any webpack process if you are not using the React on Rails test helper.
|
33
|
-
|
34
|
-
Note, if you are try to lint before running tests, and you are depending on the test helper to build your locales, your linting will fail because the translations won't be built yet.
|
35
|
-
|
36
|
-
The fix is either to
|
37
|
-
1) run the rake task to build the translations before running the lint command or
|
38
|
-
2) to run the tests first.
|
28
|
+
Note: if you try to lint before running tests, and you depend on the test helper to build your locales, linting will fail because the translations won't be built yet.
|
39
29
|
|
40
|
-
|
30
|
+
The fix is either to
|
31
|
+
1) run the rake task to build the translations before running the lint command or
|
32
|
+
2) to run the tests first.
|
41
33
|
|
42
|
-
By default the locales generated
|
43
|
-
with `react-intl` supported via js files:
|
34
|
+
By default, the locales are generated as JSON, but you can also generate them as JavaScript with [`react-intl`](https://formatjs.io/docs/getting-started/installation/) support:
|
44
35
|
|
45
|
-
1. Specify i18n output format in `react_on_rails.rb`:
|
46
|
-
|
47
|
-
config.i18n_output_format =
|
48
|
-
|
36
|
+
1. Specify the i18n output format in `config/initializers/react_on_rails.rb`:
|
37
|
+
```rb
|
38
|
+
config.i18n_output_format = "js"
|
39
|
+
```
|
49
40
|
|
50
|
-
2. Add `react-intl` & `intl` to `client/package.json`, and remember to `bundle && yarn install`.
|
51
|
-
Versions should be newer than these:
|
41
|
+
2. Add `react-intl` & `intl` to `client/package.json`, and remember to `bundle install && yarn install`. The minimum supported versions are:
|
52
42
|
|
53
|
-
|
54
|
-
|
43
|
+
```js
|
44
|
+
"dependencies": {
|
45
|
+
...
|
46
|
+
"intl": "^1.2.5",
|
47
|
+
"react-intl": "^2.1.5",
|
48
|
+
...
|
49
|
+
}
|
50
|
+
```
|
51
|
+
|
52
|
+
3. In React, you need to initialize `react-intl`, and set its parameters:
|
53
|
+
|
54
|
+
```js
|
55
|
+
...
|
56
|
+
import { addLocaleData } from 'react-intl';
|
57
|
+
import en from 'react-intl/locale-data/en';
|
58
|
+
import de from 'react-intl/locale-data/de';
|
59
|
+
import { translations } from 'path_to/i18n/translations';
|
60
|
+
import { defaultLocale } from 'path_to/i18n/default';
|
61
|
+
...
|
62
|
+
// Initizalize all locales for react-intl.
|
63
|
+
addLocaleData([...en, ...de]);
|
64
|
+
...
|
65
|
+
// set locale and messages for IntlProvider.
|
66
|
+
const locale = method_to_get_current_locale() || defaultLocale;
|
67
|
+
const messages = translations[locale];
|
55
68
|
...
|
56
|
-
|
57
|
-
|
69
|
+
return (
|
70
|
+
<IntlProvider locale={locale} key={locale} messages={messages}>
|
71
|
+
<CommentScreen {...{ actions, data }} />
|
72
|
+
</IntlProvider>
|
73
|
+
)
|
74
|
+
```
|
75
|
+
```js
|
76
|
+
// In your component.
|
77
|
+
import { defaultMessages } from 'path_to/i18n/default';
|
58
78
|
...
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
import { addLocaleData } from 'react-intl';
|
69
|
-
import en from 'react-intl/locale-data/en';
|
70
|
-
import de from 'react-intl/locale-data/de';
|
71
|
-
import { translations } from 'path_to/i18n/translations';
|
72
|
-
import { defaultLocale } from 'path_to/i18n/default';
|
73
|
-
...
|
74
|
-
// Initizalize all locales for react-intl.
|
75
|
-
addLocaleData([...en, ...de]);
|
76
|
-
...
|
77
|
-
// set locale and messages for IntlProvider.
|
78
|
-
const locale = method_to_get_current_locale() || defaultLocale;
|
79
|
-
const messages = translations[locale];
|
80
|
-
...
|
81
|
-
return (
|
82
|
-
<IntlProvider locale={locale} key={locale} messages={messages}>
|
83
|
-
<CommentScreen {...{ actions, data }} />
|
84
|
-
</IntlProvider>
|
85
|
-
)
|
86
|
-
```
|
87
|
-
```js
|
88
|
-
// In your component.
|
89
|
-
import { defaultMessages } from 'path_to/i18n/default';
|
90
|
-
...
|
91
|
-
return (
|
92
|
-
{ formatMessage(defaultMessages.yourLocaleKeyInCamelCase) }
|
93
|
-
)
|
94
|
-
```
|
95
|
-
|
96
|
-
# Notes
|
97
|
-
* See why using JSON could be better compare to JS if amount of data is hure [ https://v8.dev/blog/cost-of-javascript-2019#json]( https://v8.dev/blog/cost-of-javascript-2019#json).
|
98
|
-
* See [Support for Rails' i18n pluralization #1000](https://github.com/shakacode/react_on_rails/issues/1000) for a discussion of issues around pluralization.
|
99
|
-
* *Outdated:* You can refer to [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) and [PR #340](https://github.com/shakacode/react-webpack-rails-tutorial/pull/340), [commmited](https://github.com/shakacode/react-webpack-rails-tutorial/commit/ef369ed9d922aea5116ca7e50208169fd7831389) for a complete example.
|
79
|
+
return (
|
80
|
+
{ formatMessage(defaultMessages.yourLocaleKeyInCamelCase) }
|
81
|
+
)
|
82
|
+
```
|
83
|
+
|
84
|
+
# Notes
|
85
|
+
* See why using JSON can perform better compared to JS for large amounts of data [https://v8.dev/blog/cost-of-javascript-2019#json](https://v8.dev/blog/cost-of-javascript-2019#json).
|
86
|
+
* See [Support for Rails' i18n pluralization #1000](https://github.com/shakacode/react_on_rails/issues/1000) for a discussion of issues around pluralization.
|
87
|
+
* *Outdated:* You can refer to [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) and [PR #340](https://github.com/shakacode/react-webpack-rails-tutorial/pull/340), [commmited](https://github.com/shakacode/react-webpack-rails-tutorial/commit/ef369ed9d922aea5116ca7e50208169fd7831389) for a complete example.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Rails/Webpacker React Integration Options
|
1
|
+
# Shakapacker (Rails/Webpacker) React Integration Options
|
2
2
|
|
3
3
|
You only _need_ props hydration if you need SSR. However, there's no good reason to
|
4
4
|
have your app make a second round trip to the Rails server to get initialization props.
|
@@ -81,7 +81,7 @@ Webpack's HMR allows the replacement of modules for React in-place without reloa
|
|
81
81
|
### React Refresh Webpack Plugin
|
82
82
|
[github.com/pmmmwh/react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin)
|
83
83
|
|
84
|
-
You can see an example commit of adding this [here](https://github.com/shakacode/
|
84
|
+
You can see an example commit of adding this [here](https://github.com/shakacode/react_on_rails_demo_ssr_hmr/commit/7e53803fce7034f5ecff335db1f400a5743a87e7).
|
85
85
|
|
86
86
|
1. Add react refresh packages:
|
87
87
|
`yarn add @pmmmwh/react-refresh-webpack-plugin react-refresh -D`
|
@@ -111,6 +111,8 @@ You can see an example commit of adding this [here](https://github.com/shakacode
|
|
111
111
|
}
|
112
112
|
```
|
113
113
|
|
114
|
+
---
|
115
|
+
|
114
116
|
### React Hot Loader (Deprecated)
|
115
117
|
|
116
118
|
1. Add the `react-hot-loader` and ` @hot-loader/react-dom` npm packages.
|
@@ -179,4 +181,3 @@ module.exports = environment.toWebpackConfig()
|
|
179
181
|
|
180
182
|
module.exports = environment;
|
181
183
|
```
|
182
|
-
|
@@ -3,7 +3,7 @@
|
|
3
3
|
See also [Client vs. Server Rendering](https://www.shakacode.com/react-on-rails/docs/guides/client-vs-server-rendering/).
|
4
4
|
|
5
5
|
## What is the easiest way to setup a webpack configuration for server-side-rendering?
|
6
|
-
See the example webpack setup here: [github.com/shakacode/
|
6
|
+
See the example webpack setup here: [github.com/shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr).
|
7
7
|
|
8
8
|
## What is Server Rendering?
|
9
9
|
|
data/docs/guides/tutorial.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# React on Rails Basic Tutorial
|
2
2
|
|
3
|
-
|
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
4
|
|
5
5
|
-----
|
6
6
|
|
7
|
-
*Updated for Ruby 2.7
|
7
|
+
*Updated for Ruby 2.7, Rails 7, React on Rails v13, and Shakapacker v6*
|
8
8
|
|
9
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
10
|
|
@@ -23,7 +23,7 @@ By the time you read this, the latest may have changed. Be sure to check the ver
|
|
23
23
|
|
24
24
|
## Setting up your environment
|
25
25
|
|
26
|
-
Trying out **React on Rails** is super easy, so long as you have the basic prerequisites. This includes the basics for Rails 6.x and node version 14+. I recommend `rvm` or `
|
26
|
+
Trying out **React on Rails** is super easy, so long as you have the basic prerequisites. This includes the basics for Rails 6.x and node version 14+. I recommend `rvm` or `rbenv` and `nvm` to install Ruby and Node. Rails can be installed as an ordinary gem.
|
27
27
|
|
28
28
|
```
|
29
29
|
nvm install node # download and install latest stable Node
|
@@ -49,6 +49,7 @@ cd <directory where you want to create your new Rails app>
|
|
49
49
|
|
50
50
|
# Any name you like for the rails app
|
51
51
|
# Skip javascript so will add that next and get the current version
|
52
|
+
# This is for Rails 7
|
52
53
|
rails new --skip-turbolinks --skip-javascript test-react-on-rails
|
53
54
|
|
54
55
|
cd test-react-on-rails
|
@@ -60,15 +61,15 @@ of both the gem and npm package. In other words, don't use the `^` or `~` in the
|
|
60
61
|
_Use the latest version for `react_on_rails` and `shakapacker`._
|
61
62
|
|
62
63
|
```
|
63
|
-
gem 'react_on_rails', '13.0.
|
64
|
-
gem 'shakapacker', '6.
|
64
|
+
gem 'react_on_rails', '13.0.1' # prefer exact gem version to match npm version
|
65
|
+
gem 'shakapacker', '6.4.0' # prefer exact gem version to match npm version
|
65
66
|
|
66
67
|
```
|
67
68
|
|
68
69
|
Note: The latest released React On Rails version is considered stable. Please use the latest
|
69
70
|
version to ensure you get all the security patches and the best support.
|
70
71
|
|
71
|
-
## Run the
|
72
|
+
## Run the shakapacker (webpacker) generator
|
72
73
|
|
73
74
|
```terminal
|
74
75
|
bundle exec rails webpacker:install
|
@@ -90,8 +91,6 @@ Install React on Rails: `rails generate react_on_rails:install`. You need to fir
|
|
90
91
|
Note, using `redux` is no longer recommended as the basic installer uses React Hooks.
|
91
92
|
If you want the redux install: `rails generate react_on_rails:install --redux`
|
92
93
|
|
93
|
-
The generator will add `mini_racer`'s latest version. If you're using linux & encounter issues installing `libv8`, here's [a common solution](https://github.com/rubyjs/mini_racer/issues/218).
|
94
|
-
|
95
94
|
```
|
96
95
|
bundle exec rails generate react_on_rails:install
|
97
96
|
```
|
@@ -99,6 +98,14 @@ bundle exec rails generate react_on_rails:install
|
|
99
98
|
Enter `a` to replace all configuration files required by the project. You can check the diffs
|
100
99
|
before you commit to see what changed.
|
101
100
|
|
101
|
+
## Setting up your environment variables
|
102
|
+
|
103
|
+
Add the following variable to your environment:
|
104
|
+
|
105
|
+
```
|
106
|
+
EXECJS_RUNTIME=Node
|
107
|
+
```
|
108
|
+
|
102
109
|
Then run the server with one of the following options:
|
103
110
|
|
104
111
|
## Running with HMR
|
@@ -11,7 +11,7 @@
|
|
11
11
|
|
12
12
|
To get a deeper understanding of `rails/webpacker`, watch [RailsConf 2020 CE - Webpacker, It-Just-Works, But How? by Justin Gordon](https://youtu.be/sJLoOpc5LD8)
|
13
13
|
|
14
|
-
Per the example repo [shakacode/
|
14
|
+
Per the example repo [shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr),
|
15
15
|
you should consider keeping your codebase mostly consistent with the defaults for [rails/webpacker](https://github.com/rails/webpacker).
|
16
16
|
|
17
17
|
# React on Rails
|
data/docs/home.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## Details
|
4
4
|
1. [Overview](https://www.shakacode.com/react-on-rails/docs/guides/react-on-rails-overview/)
|
5
|
-
1. [Getting Started](https://www.shakacode.com/react-on-rails/docs/
|
5
|
+
1. [Getting Started](https://www.shakacode.com/react-on-rails/docs/getting-started/)
|
6
6
|
1. [How React on Rails Works](https://www.shakacode.com/react-on-rails/docs/guides/how-react-on-rails-works/)
|
7
7
|
1. [Webpack Configuration](https://www.shakacode.com/react-on-rails/docs/guides/webpack-configuration/)
|
8
8
|
1. [View Helpers API](https://www.shakacode.com/react-on-rails/docs/api/view-helpers-api/)
|
@@ -16,7 +16,7 @@
|
|
16
16
|
## Example Apps
|
17
17
|
1. [spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy) example repo for a simple configuration of webpack via the rails/webpacker gem
|
18
18
|
that supports SSR.
|
19
|
-
2. Example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/
|
19
|
+
2. Example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_demo_ssr_hmr) for a new way to setup the creation of your SSR bundle with `rails/webpacker`.
|
20
20
|
3. Live, [open source](https://github.com/shakacode/react-webpack-rails-tutorial), example of this gem, see [reactrails.com](http://reactrails.com).
|
21
21
|
|
22
22
|
# Other Resources
|
@@ -2,9 +2,6 @@
|
|
2
2
|
|
3
3
|
For the best performance with Server Rendering, consider using [React on Rails Pro]
|
4
4
|
|
5
|
-
Be sure to use mini_racer. See [issues/428](https://github.com/shakacode/react_on_rails/issues/428).
|
6
|
-
|
7
|
-
|
8
5
|
|
9
6
|
## General Tips
|
10
7
|
- Your code can't reference `document`. Server side JS execution does not have access to `document`,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/babel.config.js") %>
|
2
2
|
|
3
3
|
module.exports = function (api) {
|
4
4
|
const defaultConfigFunc = require('shakapacker/package/babel/preset.js')
|
data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb
CHANGED
@@ -42,4 +42,17 @@ ReactOnRails.configure do |config|
|
|
42
42
|
# React components.
|
43
43
|
#
|
44
44
|
config.server_bundle_js_file = "server-bundle.js"
|
45
|
+
|
46
|
+
################################################################################
|
47
|
+
################################################################################
|
48
|
+
# FILE SYSTEM BASED COMPONENT REGISTRY
|
49
|
+
################################################################################
|
50
|
+
# `components_subdirectory` is the name of the matching directories that contain automatically registered components
|
51
|
+
# for use in the Rails views. The default is nil, you can enable the feature by updating it in the next line.
|
52
|
+
# config.components_subdirectory = "ror_components"
|
53
|
+
#
|
54
|
+
# For automated component registry, `render_component` view helper method tries to load bundle for component from
|
55
|
+
# generated directory. default is false, you can pass option at the time of individual usage or update the default
|
56
|
+
# in the following line
|
57
|
+
config.auto_load_bundle = false
|
45
58
|
end
|
data/lib/generators/react_on_rails/templates/base/base/config/webpack/clientWebpackConfig.js.tt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/clientWebpackConfig.js") %>
|
2
2
|
|
3
3
|
const commonWebpackConfig = require('./commonWebpackConfig');
|
4
4
|
|
data/lib/generators/react_on_rails/templates/base/base/config/webpack/commonWebpackConfig.js.tt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/commonWebpackConfig.js") %>
|
2
2
|
|
3
3
|
// Common configuration applying to client and server configuration
|
4
4
|
const { webpackConfig: baseClientWebpackConfig, merge } = require('shakapacker');
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/development.js") %>
|
2
2
|
|
3
3
|
const { devServer, inliningCss } = require('shakapacker');
|
4
4
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/production.js") %>
|
2
2
|
|
3
3
|
const webpackConfig = require('./webpackConfig');
|
4
4
|
|
data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/serverWebpackConfig.js") %>
|
2
2
|
|
3
3
|
const { merge, config } = require('shakapacker');
|
4
4
|
const commonWebpackConfig = require('./commonWebpackConfig');
|
@@ -1,6 +1,9 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/test.js") %>
|
2
2
|
|
3
|
-
|
4
|
-
const config = require('./development');
|
3
|
+
const webpackConfig = require('./webpackConfig')
|
5
4
|
|
6
|
-
|
5
|
+
const testOnly = (_clientWebpackConfig, _serverWebpackConfig) => {
|
6
|
+
// place any code here that is for test only
|
7
|
+
}
|
8
|
+
|
9
|
+
module.exports = webpackConfig(testOnly)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/
|
1
|
+
<%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_demo_ssr_hmr/blob/master/config/webpack/webpackConfig.js") %>
|
2
2
|
|
3
3
|
const clientWebpackConfig = require('./clientWebpackConfig');
|
4
4
|
const serverWebpackConfig = require('./serverWebpackConfig');
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# rubocop:disable Metrics/ClassLength
|
4
|
-
|
5
3
|
module ReactOnRails
|
6
4
|
def self.configure
|
7
5
|
yield(configuration)
|
@@ -9,6 +7,7 @@ module ReactOnRails
|
|
9
7
|
end
|
10
8
|
|
11
9
|
DEFAULT_GENERATED_ASSETS_DIR = File.join(%w[public webpack], Rails.env).freeze
|
10
|
+
DEFAULT_COMPONENTS_SUBDIRECTORY = nil
|
12
11
|
DEFAULT_SERVER_RENDER_TIMEOUT = 20
|
13
12
|
DEFAULT_POOL_SIZE = 1
|
14
13
|
DEFAULT_RANDOM_DOM_ID = true # for backwards compatability
|
@@ -21,6 +20,7 @@ module ReactOnRails
|
|
21
20
|
generated_assets_dir: "",
|
22
21
|
server_bundle_js_file: "",
|
23
22
|
prerender: false,
|
23
|
+
auto_load_bundle: false,
|
24
24
|
replay_console: true,
|
25
25
|
logging_on_server: true,
|
26
26
|
raise_on_prerender_error: Rails.env.development?,
|
@@ -38,7 +38,8 @@ module ReactOnRails
|
|
38
38
|
build_production_command: "",
|
39
39
|
random_dom_id: DEFAULT_RANDOM_DOM_ID,
|
40
40
|
same_bundle_for_client_and_server: false,
|
41
|
-
i18n_output_format: nil
|
41
|
+
i18n_output_format: nil,
|
42
|
+
components_subdirectory: DEFAULT_COMPONENTS_SUBDIRECTORY
|
42
43
|
)
|
43
44
|
end
|
44
45
|
|
@@ -51,8 +52,8 @@ module ReactOnRails
|
|
51
52
|
:webpack_generated_files, :rendering_extension, :build_test_command,
|
52
53
|
:build_production_command,
|
53
54
|
:i18n_dir, :i18n_yml_dir, :i18n_output_format,
|
54
|
-
:server_render_method, :random_dom_id,
|
55
|
-
:same_bundle_for_client_and_server, :rendering_props_extension
|
55
|
+
:server_render_method, :random_dom_id, :auto_load_bundle,
|
56
|
+
:same_bundle_for_client_and_server, :rendering_props_extension, :components_subdirectory
|
56
57
|
|
57
58
|
# rubocop:disable Metrics/AbcSize
|
58
59
|
def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil,
|
@@ -66,7 +67,8 @@ module ReactOnRails
|
|
66
67
|
build_production_command: nil,
|
67
68
|
same_bundle_for_client_and_server: nil,
|
68
69
|
i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil,
|
69
|
-
random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil
|
70
|
+
random_dom_id: nil, server_render_method: nil, rendering_props_extension: nil,
|
71
|
+
components_subdirectory: nil, auto_load_bundle: nil)
|
70
72
|
self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root
|
71
73
|
self.generated_assets_dirs = generated_assets_dirs
|
72
74
|
self.generated_assets_dir = generated_assets_dir
|
@@ -100,6 +102,8 @@ module ReactOnRails
|
|
100
102
|
self.rendering_extension = rendering_extension
|
101
103
|
|
102
104
|
self.server_render_method = server_render_method
|
105
|
+
self.components_subdirectory = components_subdirectory
|
106
|
+
self.auto_load_bundle = auto_load_bundle
|
103
107
|
end
|
104
108
|
# rubocop:enable Metrics/AbcSize
|
105
109
|
|
@@ -109,8 +113,6 @@ module ReactOnRails
|
|
109
113
|
configure_generated_assets_dirs_deprecation
|
110
114
|
configure_skip_display_none_deprecation
|
111
115
|
ensure_generated_assets_dir_present
|
112
|
-
check_i18n_directory_exists
|
113
|
-
check_i18n_yml_directory_exists
|
114
116
|
check_server_render_method_is_only_execjs
|
115
117
|
error_if_using_webpacker_and_generated_assets_dir_not_match_public_output_path
|
116
118
|
# check_deprecated_settings
|
@@ -129,6 +131,7 @@ module ReactOnRails
|
|
129
131
|
ENV["WEBPACKER_PRECOMPILE"] = "false"
|
130
132
|
|
131
133
|
precompile_tasks = lambda {
|
134
|
+
Rake::Task["react_on_rails:generate_packs"].invoke
|
132
135
|
Rake::Task["react_on_rails:assets:webpack"].invoke
|
133
136
|
puts "Invoking task webpacker:clean from React on Rails"
|
134
137
|
|
@@ -184,30 +187,6 @@ module ReactOnRails
|
|
184
187
|
raise ReactOnRails::Error, msg
|
185
188
|
end
|
186
189
|
|
187
|
-
def check_i18n_directory_exists
|
188
|
-
return if i18n_dir.nil?
|
189
|
-
return if Dir.exist?(i18n_dir)
|
190
|
-
|
191
|
-
msg = <<-MSG.strip_heredoc
|
192
|
-
Error configuring /config/initializers/react_on_rails.rb: invalid value for `config.i18n_dir`.
|
193
|
-
Directory does not exist: #{i18n_dir}. Set to value to nil or comment it
|
194
|
-
out if not using the React on Rails i18n feature.
|
195
|
-
MSG
|
196
|
-
raise ReactOnRails::Error, msg
|
197
|
-
end
|
198
|
-
|
199
|
-
def check_i18n_yml_directory_exists
|
200
|
-
return if i18n_yml_dir.nil?
|
201
|
-
return if Dir.exist?(i18n_yml_dir)
|
202
|
-
|
203
|
-
msg = <<-MSG.strip_heredoc
|
204
|
-
Error configuring /config/initializers/react_on_rails.rb: invalid value for `config.i18n_yml_dir`.
|
205
|
-
Directory does not exist: #{i18n_yml_dir}. Set to value to nil or comment it
|
206
|
-
out if not using this i18n with React on Rails, or if you want to use all translation files.
|
207
|
-
MSG
|
208
|
-
raise ReactOnRails::Error, msg
|
209
|
-
end
|
210
|
-
|
211
190
|
def ensure_generated_assets_dir_present
|
212
191
|
return if generated_assets_dir.present? || ReactOnRails::WebpackerUtils.using_webpacker?
|
213
192
|
|
@@ -253,4 +232,3 @@ module ReactOnRails
|
|
253
232
|
end
|
254
233
|
end
|
255
234
|
end
|
256
|
-
# rubocop:enable Metrics/ClassLength
|
@@ -57,6 +57,7 @@ module ReactOnRails
|
|
57
57
|
internal_result = internal_react_component(component_name, options)
|
58
58
|
server_rendered_html = internal_result[:result]["html"]
|
59
59
|
console_script = internal_result[:result]["consoleReplayScript"]
|
60
|
+
render_options = internal_result[:render_options]
|
60
61
|
|
61
62
|
case server_rendered_html
|
62
63
|
when String
|
@@ -64,7 +65,7 @@ module ReactOnRails
|
|
64
65
|
server_rendered_html: server_rendered_html,
|
65
66
|
component_specification_tag: internal_result[:tag],
|
66
67
|
console_script: console_script,
|
67
|
-
render_options:
|
68
|
+
render_options: render_options
|
68
69
|
)
|
69
70
|
when Hash
|
70
71
|
msg = <<~MSG
|
@@ -90,6 +91,26 @@ module ReactOnRails
|
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
94
|
+
def load_pack_for_component(component_name)
|
95
|
+
component_pack_file = generated_components_pack(component_name)
|
96
|
+
is_component_pack_present = File.exist?("#{component_pack_file}.jsx")
|
97
|
+
is_development = ENV["RAILS_ENV"] == "development"
|
98
|
+
|
99
|
+
if is_development && !is_component_pack_present
|
100
|
+
ReactOnRails::PacksGenerator.generate
|
101
|
+
raise_generated_missing_pack_warning(component_name)
|
102
|
+
end
|
103
|
+
|
104
|
+
ReactOnRails::PacksGenerator.raise_nested_enteries_disabled unless ReactOnRails::WebpackerUtils.nested_entries?
|
105
|
+
|
106
|
+
append_javascript_pack_tag "generated/#{component_name}"
|
107
|
+
append_stylesheet_pack_tag "generated/#{component_name}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def generated_components_pack(component_name)
|
111
|
+
"#{ReactOnRails::WebpackerUtils.webpacker_source_entry_path}/generated/#{component_name}"
|
112
|
+
end
|
113
|
+
|
93
114
|
# react_component_hash is used to return multiple HTML strings for server rendering, such as for
|
94
115
|
# adding meta-tags to a page.
|
95
116
|
# It is exactly like react_component except for the following:
|
@@ -112,6 +133,7 @@ module ReactOnRails
|
|
112
133
|
internal_result = internal_react_component(component_name, options)
|
113
134
|
server_rendered_html = internal_result[:result]["html"]
|
114
135
|
console_script = internal_result[:result]["consoleReplayScript"]
|
136
|
+
render_options = internal_result[:render_options]
|
115
137
|
|
116
138
|
if server_rendered_html.is_a?(String) && internal_result[:result]["hasErrors"]
|
117
139
|
server_rendered_html = { COMPONENT_HTML_KEY => internal_result[:result]["html"] }
|
@@ -122,7 +144,7 @@ module ReactOnRails
|
|
122
144
|
server_rendered_html: server_rendered_html,
|
123
145
|
component_specification_tag: internal_result[:tag],
|
124
146
|
console_script: console_script,
|
125
|
-
render_options:
|
147
|
+
render_options: render_options
|
126
148
|
)
|
127
149
|
else
|
128
150
|
msg = <<~MSG
|
@@ -279,8 +301,9 @@ module ReactOnRails
|
|
279
301
|
# URLs as UTF-8. This situation can occur in browsers that do not encode the
|
280
302
|
# entire URL as UTF-8 already, mostly on the Windows platform (IE11 and lower).
|
281
303
|
original_url_normalized = request.original_url
|
282
|
-
if original_url_normalized.encoding
|
283
|
-
original_url_normalized = original_url_normalized.force_encoding(
|
304
|
+
if original_url_normalized.encoding == Encoding::BINARY
|
305
|
+
original_url_normalized = original_url_normalized.force_encoding(Encoding::ISO_8859_1)
|
306
|
+
.encode(Encoding::UTF_8)
|
284
307
|
end
|
285
308
|
|
286
309
|
# Using Addressable instead of standard URI to better deal with
|
@@ -424,6 +447,8 @@ module ReactOnRails
|
|
424
447
|
# Create the HTML rendering part
|
425
448
|
result = server_rendered_react_component(render_options)
|
426
449
|
|
450
|
+
load_pack_for_component react_component_name if render_options.auto_load_bundle
|
451
|
+
|
427
452
|
{
|
428
453
|
render_options: render_options,
|
429
454
|
tag: component_specification_tag,
|
@@ -527,6 +552,17 @@ module ReactOnRails
|
|
527
552
|
result
|
528
553
|
end
|
529
554
|
|
555
|
+
def raise_generated_missing_pack_warning(component_name)
|
556
|
+
msg = <<~MSG
|
557
|
+
**ERROR** ReactOnRails: Generated missing pack for Component: #{component_name}. Please refresh the webpage \
|
558
|
+
once webpack has finished generating the bundles. If the problem persists
|
559
|
+
1. Verify `components_subdirectory` is configured in `config/initializers/react_on_rails`.
|
560
|
+
2. Component: #{component_name} is placed inside the configured `components_subdirectory`.
|
561
|
+
MSG
|
562
|
+
|
563
|
+
raise ReactOnRails::Error, msg
|
564
|
+
end
|
565
|
+
|
530
566
|
def replay_console_option(val)
|
531
567
|
val.nil? ? ReactOnRails.configuration.replay_console : val
|
532
568
|
end
|