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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -5
  3. data/Gemfile.development_dependencies +1 -3
  4. data/NEWS.md +1 -1
  5. data/README.md +45 -22
  6. data/docs/additional-details/migrating-from-react-rails.md +1 -1
  7. data/docs/additional-details/recommended-project-structure.md +1 -1
  8. data/docs/api/view-helpers-api.md +2 -1
  9. data/docs/{guides/getting-started.md → getting-started.md} +4 -1
  10. data/docs/guides/client-vs-server-rendering.md +4 -2
  11. data/docs/guides/configuration.md +18 -4
  12. data/docs/guides/file-system-based-automated-bundle-generation.md +188 -0
  13. data/docs/guides/i18n.md +71 -83
  14. data/docs/guides/rails-webpacker-react-integration-options.md +4 -3
  15. data/docs/guides/react-server-rendering.md +1 -1
  16. data/docs/guides/tutorial.md +15 -8
  17. data/docs/guides/webpack-configuration.md +1 -1
  18. data/docs/home.md +2 -2
  19. data/docs/javascript/server-rendering-tips.md +0 -3
  20. data/lib/generators/react_on_rails/base_generator.rb +0 -1
  21. data/lib/generators/react_on_rails/templates/base/base/app/views/layouts/hello_world.html.erb +1 -1
  22. data/lib/generators/react_on_rails/templates/base/base/babel.config.js.tt +1 -1
  23. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +13 -0
  24. data/lib/generators/react_on_rails/templates/base/base/config/webpack/clientWebpackConfig.js.tt +1 -1
  25. data/lib/generators/react_on_rails/templates/base/base/config/webpack/commonWebpackConfig.js.tt +1 -1
  26. data/lib/generators/react_on_rails/templates/base/base/config/webpack/development.js.tt +1 -1
  27. data/lib/generators/react_on_rails/templates/base/base/config/webpack/production.js.tt +1 -1
  28. data/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt +1 -1
  29. data/lib/generators/react_on_rails/templates/base/base/config/webpack/test.js.tt +7 -4
  30. data/lib/generators/react_on_rails/templates/base/base/config/webpack/webpackConfig.js.tt +1 -1
  31. data/lib/react_on_rails/configuration.rb +11 -33
  32. data/lib/react_on_rails/helper.rb +40 -4
  33. data/lib/react_on_rails/locales/base.rb +24 -1
  34. data/lib/react_on_rails/packs_generator.rb +298 -0
  35. data/lib/react_on_rails/react_component/render_options.rb +4 -0
  36. data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +0 -6
  37. data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +2 -0
  38. data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +19 -3
  39. data/lib/react_on_rails/version.rb +1 -1
  40. data/lib/react_on_rails/webpacker_utils.rb +14 -0
  41. data/lib/react_on_rails.rb +1 -0
  42. data/lib/tasks/generate_packs.rake +11 -0
  43. data/package.json +2 -2
  44. data/yarn.lock +5 -5
  45. metadata +6 -3
data/docs/guides/i18n.md CHANGED
@@ -1,99 +1,87 @@
1
- # I18n
1
+ # Internationalization
2
2
 
3
- Here's a summary of adding the I18n functionality.
3
+ You can use [Rails internationalization (i18n)](https://guides.rubyonrails.org/i18n.html) in your client code.
4
4
 
5
- 1. Add `config.i18n_dir` in `config/initializers/react_on_rails.rb`
5
+ 1. Set `config.i18n_dir` in `config/initializers/react_on_rails.rb`:
6
6
 
7
- React on Rails will generate `translations.json` & `default.json` automatically (see #3) after you configured your `config.i18n_dir` in `config/initializers/react_on_rails.rb`.
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
- ```ruby
10
- # Replace the following line to the location where you keep translation.js & default.js.
11
- config.i18n_dir = Rails.root.join("PATH_TO", "YOUR_JS_I18N_FOLDER")
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
- Optionally you can also set `config.i18n_yml_dir` if you do not what to use all the locale files from rails.
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
- `translations.json`: All your locales in json format.
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
- 2. Add `translations.json` and `default.json` to your `.gitignore`.
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
- 3. Javascript locale files must be generated before `yarn build`.
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
- Once you setup `config.i18n_dir` as in the previous step, you will need to make sure `rake react_on_rails:locale` runs before webpack.
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
- # Generate locales with react-intl support
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 in json format. If you need to generate files in the prior way
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
- ```rb
47
- config.i18n_output_format = 'js'
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
- ```js
54
- "dependencies": {
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
- "intl": "^1.2.5",
57
- "react-intl": "^2.1.5",
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
- 3. Add `translations.js` and `default.js` to your `.gitignore` and `.eslintignore`.
63
-
64
- 4. In React, you need to initialize `react-intl`, and set parameters for it.
65
-
66
- ```js
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/commit/7e53803fce7034f5ecff335db1f400a5743a87e7).
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh).
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
 
@@ -1,10 +1,10 @@
1
1
  # React on Rails Basic Tutorial
2
2
 
3
- **November 11, 2020**: See the example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh) for a new way to setup the creation of your SSR bundle with `rails/webpacker`. This file will be update shortly. Most of it is still relevant.
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.1, Rails 6.0.3.1, React on Rails v12.5.0, and Shakapacker v6*
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 `rbevn` and `nvm` to install Ruby and Node. Rails can be installed as an ordinary gem.
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.0' # prefer exact gem version to match npm version
64
- gem 'shakapacker', '6.1.1' # prefer exact gem version to match npm version
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 webpacker (shakapacker) generator
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh),
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/guides/getting-started/)
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh) for a new way to setup the creation of your SSR bundle with `rails/webpacker`.
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`,
@@ -73,7 +73,6 @@ module ReactOnRails
73
73
  end
74
74
 
75
75
  def add_base_gems_to_gemfile
76
- gem "mini_racer", platforms: :ruby
77
76
  run "bundle"
78
77
  end
79
78
 
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title>ReactOnRailsWithWebpacker</title>
4
+ <title>ReactOnRailsWithShakapacker</title>
5
5
  <%= csrf_meta_tags %>
6
6
  <%= javascript_pack_tag 'hello-world-bundle' %>
7
7
  <%= stylesheet_pack_tag 'hello-world-bundle' %>
@@ -1,4 +1,4 @@
1
- <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/babel.config.js") %>
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')
@@ -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
@@ -1,4 +1,4 @@
1
- <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/clientWebpackConfig.js") %>
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
 
@@ -1,4 +1,4 @@
1
- <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/commonWebpackConfig.js") %>
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/development.js") %>
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/production.js") %>
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
 
@@ -1,4 +1,4 @@
1
- <%= add_documentation_reference(config[:message], "// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/serverWebpackConfig.js") %>
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/development.js") %>
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
- // Use dev
4
- const config = require('./development');
3
+ const webpackConfig = require('./webpackConfig')
5
4
 
6
- module.exports = config;
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/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/webpackConfig.js") %>
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: internal_result[: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: internal_result[: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.to_s == "ASCII-8BIT"
283
- original_url_normalized = original_url_normalized.force_encoding("ISO-8859-1").encode("UTF-8")
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