react_on_rails 13.1.0 → 13.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +5 -2
- data/.github/workflows/lint-js-and-ruby.yml +3 -3
- data/.github/workflows/main.yml +19 -13
- data/.github/workflows/package-js-tests.yml +2 -2
- data/.github/workflows/rspec-package-specs.yml +2 -2
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +21 -1
- data/Gemfile.development_dependencies +2 -2
- data/README.md +7 -5
- data/docs/api/javascript-api.md +9 -0
- data/docs/getting-started.md +15 -6
- data/docs/guides/configuration.md +25 -20
- data/docs/guides/file-system-based-automated-bundle-generation.md +16 -13
- data/docs/guides/installation-into-an-existing-rails-app.md +18 -20
- data/docs/guides/rails-webpacker-react-integration-options.md +8 -8
- data/docs/guides/react-server-rendering.md +1 -1
- data/docs/guides/tutorial.md +36 -32
- data/lib/generators/react_on_rails/base_generator.rb +15 -10
- data/lib/generators/react_on_rails/bin/dev +33 -0
- data/lib/generators/react_on_rails/bin/dev-static +33 -0
- data/lib/generators/react_on_rails/install_generator.rb +5 -0
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +1 -1
- data/lib/react_on_rails/configuration.rb +40 -3
- data/lib/react_on_rails/helper.rb +21 -23
- data/lib/react_on_rails/packs_generator.rb +30 -101
- data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +1 -1
- data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +1 -20
- data/lib/react_on_rails/utils.rb +26 -0
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/webpacker_utils.rb +54 -3
- data/lib/tasks/generate_packs.rake +1 -1
- data/package.json +29 -28
- data/yarn.lock +2856 -3277
- metadata +4 -2
@@ -3,9 +3,9 @@
|
|
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.
|
5
5
|
|
6
|
-
**Server-Side Rendering (SSR)** results in Rails rendering HTML for your React components. The main reasons to use SSR are better SEO and pages display more quickly.
|
6
|
+
**Server-Side Rendering (SSR)** results in Rails rendering HTML for your React components. The main reasons to use SSR are better SEO and pages display more quickly.
|
7
7
|
|
8
|
-
These gems provide advanced integration of React with [rails/webpacker](https://github.com/rails/webpacker):
|
8
|
+
These gems provide advanced integration of React with [rails/webpacker](https://github.com/rails/webpacker):
|
9
9
|
|
10
10
|
| Gem | Props Hydration | Server-Side-Rendering (SSR) | SSR with HMR | SSR with React-Router | SSR with Code Splitting | Node SSR |
|
11
11
|
| --- | --------------- | --- | --------------------- | ----------------------| ------------------------|----|
|
@@ -19,7 +19,7 @@ Note, Node SSR for React on Rails requires [React on Rails Pro](https://www.shak
|
|
19
19
|
|
20
20
|
As mentioned, you don't _need_ to use a gem to integrate Rails with React.
|
21
21
|
|
22
|
-
If you're not concerned with view helpers to pass props or server rendering, can do it yourself:
|
22
|
+
If you're not concerned with view helpers to pass props or server rendering, you can do it yourself:
|
23
23
|
|
24
24
|
```erb
|
25
25
|
<%# views/layouts/application.html.erb %>
|
@@ -71,7 +71,7 @@ development:
|
|
71
71
|
inline: true
|
72
72
|
```
|
73
73
|
|
74
|
-
This basic configuration alone will have HMR working with the default webpacker setup. However,
|
74
|
+
This basic configuration alone will have HMR working with the default webpacker setup. However, a code save will trigger a full page refresh each time you save a file.
|
75
75
|
|
76
76
|
Webpack's HMR allows the replacement of modules for React in-place without reloading the browser. To do this, you have two options:
|
77
77
|
|
@@ -95,9 +95,9 @@ You can see an example commit of adding this [here](https://github.com/shakacode
|
|
95
95
|
```js
|
96
96
|
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
97
97
|
const environment = require('./environment')
|
98
|
-
|
98
|
+
|
99
99
|
const isWebpackDevServer = process.env.WEBPACK_DEV_SERVER;
|
100
|
-
|
100
|
+
|
101
101
|
//plugins
|
102
102
|
if (isWebpackDevServer) {
|
103
103
|
environment.plugins.append(
|
@@ -164,11 +164,11 @@ const environment = require('./environment')
|
|
164
164
|
+ if (!module.hot) {
|
165
165
|
+ environment.loaders.get('sass').use.find(item => item.loader === 'sass-loader').options.sourceMapContents = false
|
166
166
|
+ }
|
167
|
-
+
|
167
|
+
+
|
168
168
|
module.exports = environment.toWebpackConfig()
|
169
169
|
```
|
170
170
|
|
171
|
-
5. Adjust your `config/webpack/environment.js` for a
|
171
|
+
5. Adjust your `config/webpack/environment.js` for a
|
172
172
|
|
173
173
|
```diff
|
174
174
|
// config/webpack/environment.js
|
@@ -17,7 +17,7 @@ See [this note](https://www.shakacode.com/react-on-rails/docs/guides/client-vs-s
|
|
17
17
|
|
18
18
|
## How do you do Server Rendering with React on Rails?
|
19
19
|
1. The `react_component` view helper method provides the `prerender:` option to switch on or off server rendering.
|
20
|
-
1. Configure your Webpack setup to create a different server bundle per your needs. While you may reuse the same bundle as for client rendering, this is not common in larger apps for many reasons, such as
|
20
|
+
1. Configure your Webpack setup to create a different server bundle per your needs. While you may reuse the same bundle as for client rendering, this is not common in larger apps for many reasons, such as code splitting, handling CSS and images, different code paths for React Router on the server vs. client, etc.
|
21
21
|
1. You need to configure `config.server_bundle_js_file = "server-bundle.js"` in your `config/initializers/react_on_rails.rb`
|
22
22
|
1. You should ***not*** put a hash on the server-bundle so that you can easily use the webpack-dev-server for client bundles and have the server bundle generated by a watch process.
|
23
23
|
|
data/docs/guides/tutorial.md
CHANGED
@@ -45,25 +45,23 @@ Then we need to create a fresh Rails application as following.
|
|
45
45
|
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).
|
46
46
|
|
47
47
|
```bash
|
48
|
-
|
48
|
+
# For Rails 6.x
|
49
|
+
rails new test-react-on-rails --skip-javascript
|
49
50
|
|
50
|
-
#
|
51
|
-
|
52
|
-
# This is for Rails 7
|
53
|
-
rails new --skip-turbolinks --skip-javascript test-react-on-rails
|
51
|
+
# For Rails 7.x
|
52
|
+
rails new test-react-on-rails --skip-turbolinks --skip-javascript
|
54
53
|
|
55
54
|
cd test-react-on-rails
|
56
55
|
```
|
57
56
|
|
58
57
|
## Add the shakapacker and react_on_rails gems
|
59
|
-
|
60
|
-
of both the gem and npm package. In other words, don't use
|
61
|
-
|
62
|
-
|
63
|
-
```
|
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
|
58
|
+
We recommend using the latest version of these gems. Otherwise, specify the
|
59
|
+
exact versions of both the gem and npm package. In other words, don't use
|
60
|
+
the `^` or `~` in the version specifications.
|
66
61
|
|
62
|
+
```bash
|
63
|
+
bundle add react_on_rails --strict
|
64
|
+
bundle add shakapacker --strict
|
67
65
|
```
|
68
66
|
|
69
67
|
Note: The latest released React On Rails version is considered stable. Please use the latest
|
@@ -71,32 +69,34 @@ version to ensure you get all the security patches and the best support.
|
|
71
69
|
|
72
70
|
## Run the shakapacker (webpacker) generator
|
73
71
|
|
74
|
-
```
|
72
|
+
```bash
|
75
73
|
bundle exec rails webpacker:install
|
76
74
|
```
|
77
75
|
|
78
|
-
|
76
|
+
Commit all the changes so far to avoid getting errors in the next step.
|
79
77
|
|
78
|
+
```bash
|
79
|
+
git commit -am "Initial commit"
|
80
80
|
```
|
81
|
-
|
82
|
-
|
83
|
-
git add -A
|
84
|
-
git commit -m "Initial commit"
|
85
|
-
```
|
81
|
+
|
82
|
+
Alternatively you can use `--ignore-warnings` in the next step.
|
86
83
|
|
87
84
|
## Run the React on Rails Generator
|
88
85
|
|
89
|
-
|
86
|
+
```bash
|
87
|
+
rails generate react_on_rails:install
|
88
|
+
```
|
89
|
+
|
90
|
+
You will be prompted to approve changes in certain files. Press `enter` to proceed
|
91
|
+
one by one or enter `a` to replace all configuration files required by the project.
|
92
|
+
You can check the diffs before you commit to see what changed.
|
90
93
|
|
91
94
|
Note, using `redux` is no longer recommended as the basic installer uses React Hooks.
|
92
|
-
If you want the redux install
|
95
|
+
If you want the redux install, run:
|
93
96
|
|
97
|
+
```bash
|
98
|
+
rails generate react_on_rails:install --redux
|
94
99
|
```
|
95
|
-
bundle exec rails generate react_on_rails:install
|
96
|
-
```
|
97
|
-
|
98
|
-
Enter `a` to replace all configuration files required by the project. You can check the diffs
|
99
|
-
before you commit to see what changed.
|
100
100
|
|
101
101
|
## Setting up your environment variables
|
102
102
|
|
@@ -108,14 +108,18 @@ EXECJS_RUNTIME=Node
|
|
108
108
|
|
109
109
|
Then run the server with one of the following options:
|
110
110
|
|
111
|
-
## Running
|
112
|
-
```
|
113
|
-
foreman start -f Procfile.dev
|
114
|
-
```
|
111
|
+
## Running the app
|
115
112
|
|
116
|
-
|
113
|
+
### For HMR:
|
114
|
+
|
115
|
+
```bash
|
116
|
+
./bin/dev
|
117
117
|
```
|
118
|
-
|
118
|
+
|
119
|
+
### Without HMR, statically creating the bundles
|
120
|
+
|
121
|
+
```bash
|
122
|
+
./bin/dev-static
|
119
123
|
```
|
120
124
|
|
121
125
|
Visit [http://localhost:3000/hello_world](http://localhost:3000/hello_world) and see your **React On Rails** app running!
|
@@ -144,6 +144,21 @@ module ReactOnRails
|
|
144
144
|
|
145
145
|
<%= javascript_pack_tag 'hello-world-bundle' %>
|
146
146
|
|
147
|
+
- To start Rails server run:
|
148
|
+
|
149
|
+
./bin/dev # Running with HMR
|
150
|
+
|
151
|
+
or
|
152
|
+
|
153
|
+
./bin/dev # Running with statically created bundles, without HMR
|
154
|
+
|
155
|
+
- To server render, change this line app/views/hello_world/index.html.erb to
|
156
|
+
`prerender: true` to see server rendering (right click on page and select "view source").
|
157
|
+
|
158
|
+
<%= react_component("HelloWorldApp", props: @hello_world_props, prerender: true) %>
|
159
|
+
|
160
|
+
Alternative steps to run the app:
|
161
|
+
|
147
162
|
- Run `rails s` to start the Rails server.
|
148
163
|
|
149
164
|
- Run bin/webpacker-dev-server to start the Webpack dev server for compilation of Webpack
|
@@ -152,18 +167,8 @@ module ReactOnRails
|
|
152
167
|
|
153
168
|
- Visit http://localhost:3000/hello_world and see your React On Rails app running!
|
154
169
|
|
155
|
-
- Alternately, run the foreman command to start the rails server and run webpack#{' '}
|
156
|
-
in watch mode.
|
157
|
-
|
158
|
-
foreman start -f Procfile.dev-static
|
159
|
-
|
160
170
|
- To turn on HMR, edit config/webpacker.yml and set HMR to true. Restart the rails server
|
161
171
|
and bin/webpacker-dev-server. Or use Procfile.dev.
|
162
|
-
|
163
|
-
- To server render, change this line app/views/hello_world/index.html.erb to
|
164
|
-
`prerender: true` to see server rendering (right click on page and select "view source").
|
165
|
-
|
166
|
-
<%= react_component("HelloWorldApp", props: @hello_world_props, prerender: true) %>
|
167
172
|
MSG
|
168
173
|
end
|
169
174
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
def installed?(process)
|
5
|
+
IO.popen "#{process} -v"
|
6
|
+
rescue Errno::ENOENT
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(process)
|
11
|
+
args = [*ARGV]
|
12
|
+
args.shift
|
13
|
+
puts "Using #{process}"
|
14
|
+
exec "#{process} start -f Procfile.dev", args.join(" ")
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
warn <<~MSG
|
17
|
+
ERROR:
|
18
|
+
Please ensure `Procfile.dev` exist in your project!
|
19
|
+
MSG
|
20
|
+
exit!
|
21
|
+
end
|
22
|
+
|
23
|
+
if installed? "overmind"
|
24
|
+
run "overmind"
|
25
|
+
elsif installed? "foreman"
|
26
|
+
run "foreman"
|
27
|
+
else
|
28
|
+
warn <<~MSG
|
29
|
+
NOTICE:
|
30
|
+
For this script to run, you need either 'overmind' or 'foreman' installed on your machine. Please try this script after installing one of them.
|
31
|
+
MSG
|
32
|
+
exit!
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
def installed?(process)
|
5
|
+
IO.popen "#{process} -v"
|
6
|
+
rescue Errno::ENOENT
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(process)
|
11
|
+
args = [*ARGV]
|
12
|
+
args.shift
|
13
|
+
puts "Using #{process}"
|
14
|
+
exec "#{process} start -f Procfile.dev-static", args.join(" ")
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
warn <<~MSG
|
17
|
+
ERROR:
|
18
|
+
Please ensure `Procfile.dev-static` exist in your project!
|
19
|
+
MSG
|
20
|
+
exit!
|
21
|
+
end
|
22
|
+
|
23
|
+
if installed? "overmind"
|
24
|
+
run "overmind"
|
25
|
+
elsif installed? "foreman"
|
26
|
+
run "foreman"
|
27
|
+
else
|
28
|
+
warn <<~MSG
|
29
|
+
NOTICE:
|
30
|
+
For this script to run, you need either 'overmind' or 'foreman' installed on your machine. Please try this script after installing one of them.
|
31
|
+
MSG
|
32
|
+
exit!
|
33
|
+
end
|
@@ -28,6 +28,7 @@ module ReactOnRails
|
|
28
28
|
def run_generators
|
29
29
|
if installation_prerequisites_met? || options.ignore_warnings?
|
30
30
|
invoke_generators
|
31
|
+
add_bin_scripts
|
31
32
|
else
|
32
33
|
error = "react_on_rails generator prerequisites not met!"
|
33
34
|
GeneratorMessages.add_error(error)
|
@@ -75,6 +76,10 @@ module ReactOnRails
|
|
75
76
|
GeneratorMessages.add_error(error)
|
76
77
|
true
|
77
78
|
end
|
79
|
+
|
80
|
+
def add_bin_scripts
|
81
|
+
directory "#{__dir__}/bin", "bin"
|
82
|
+
end
|
78
83
|
end
|
79
84
|
end
|
80
85
|
end
|
data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# See https://github.com/shakacode/react_on_rails/blob/master/docs/
|
3
|
+
# See https://github.com/shakacode/react_on_rails/blob/master/docs/guides/configuration.md
|
4
4
|
# for many more options.
|
5
5
|
|
6
6
|
ReactOnRails.configure do |config|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
4
|
+
|
3
5
|
module ReactOnRails
|
4
6
|
def self.configure
|
5
7
|
yield(configuration)
|
@@ -109,6 +111,7 @@ module ReactOnRails
|
|
109
111
|
|
110
112
|
# on ReactOnRails
|
111
113
|
def setup_config_values
|
114
|
+
check_autobundling_requirements_if_configured
|
112
115
|
ensure_webpack_generated_files_exists
|
113
116
|
configure_generated_assets_dirs_deprecation
|
114
117
|
configure_skip_display_none_deprecation
|
@@ -121,14 +124,37 @@ module ReactOnRails
|
|
121
124
|
|
122
125
|
private
|
123
126
|
|
127
|
+
def check_autobundling_requirements_if_configured
|
128
|
+
raise_missing_components_subdirectory if auto_load_bundle && !components_subdirectory.present?
|
129
|
+
return unless components_subdirectory.present?
|
130
|
+
|
131
|
+
ReactOnRails::WebpackerUtils.raise_shakapacker_not_installed unless ReactOnRails::WebpackerUtils.using_webpacker?
|
132
|
+
ReactOnRails::WebpackerUtils.raise_shakapacker_version_incompatible_for_autobundling unless
|
133
|
+
ReactOnRails::WebpackerUtils.shackapacker_version_requirement_met?(
|
134
|
+
ReactOnRails::PacksGenerator::MINIMUM_SHAKAPACKER_VERSION
|
135
|
+
)
|
136
|
+
ReactOnRails::WebpackerUtils.raise_nested_entries_disabled unless ReactOnRails::WebpackerUtils.nested_entries?
|
137
|
+
end
|
138
|
+
|
124
139
|
def adjust_precompile_task
|
125
140
|
skip_react_on_rails_precompile = %w[no false n f].include?(ENV["REACT_ON_RAILS_PRECOMPILE"])
|
126
141
|
|
127
142
|
return if skip_react_on_rails_precompile || build_production_command.blank?
|
128
143
|
|
129
|
-
|
130
|
-
|
131
|
-
|
144
|
+
if Webpacker.config.webpacker_precompile?
|
145
|
+
msg = <<~MSG
|
146
|
+
|
147
|
+
React on Rails and Shakapacker error in configuration!
|
148
|
+
In order to use config/react_on_rails.rb config.build_production_command,
|
149
|
+
you must edit config/webpacker.yml to include this value in the default configuration:
|
150
|
+
'webpacker_precompile: false'
|
151
|
+
|
152
|
+
Alternatively, remove the config/react_on_rails.rb config.build_production_command and the
|
153
|
+
default bin/webpacker script will be used for assets:precompile.
|
154
|
+
|
155
|
+
MSG
|
156
|
+
raise ReactOnRails::Error, msg
|
157
|
+
end
|
132
158
|
|
133
159
|
precompile_tasks = lambda {
|
134
160
|
Rake::Task["react_on_rails:generate_packs"].invoke
|
@@ -230,5 +256,16 @@ module ReactOnRails
|
|
230
256
|
|
231
257
|
Rails.logger.warn "[DEPRECATION] ReactOnRails: remove skip_display_none from configuration."
|
232
258
|
end
|
259
|
+
|
260
|
+
def raise_missing_components_subdirectory
|
261
|
+
msg = <<~MSG
|
262
|
+
**ERROR** ReactOnRails: auto_load_bundle is set to true, yet components_subdirectory is unconfigured.\
|
263
|
+
Please set components_subdirectory to the desired directory. For more information, please see \
|
264
|
+
https://www.shakacode.com/react-on-rails/docs/guides/file-system-based-automated-bundle-generation.md
|
265
|
+
MSG
|
266
|
+
|
267
|
+
raise ReactOnRails::Error, msg
|
268
|
+
end
|
233
269
|
end
|
234
270
|
end
|
271
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -91,26 +91,6 @@ module ReactOnRails
|
|
91
91
|
end
|
92
92
|
end
|
93
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
|
-
|
114
94
|
# react_component_hash is used to return multiple HTML strings for server rendering, such as for
|
115
95
|
# adding meta-tags to a page.
|
116
96
|
# It is exactly like react_component except for the following:
|
@@ -337,6 +317,25 @@ module ReactOnRails
|
|
337
317
|
|
338
318
|
private
|
339
319
|
|
320
|
+
def load_pack_for_component(component_name)
|
321
|
+
is_component_pack_present = File.exist?(generated_components_pack_path(component_name))
|
322
|
+
is_development = ENV["RAILS_ENV"] == "development"
|
323
|
+
|
324
|
+
if is_development && !is_component_pack_present
|
325
|
+
ReactOnRails::PacksGenerator.instance.generate_packs_if_stale
|
326
|
+
raise_missing_pack_error(component_name)
|
327
|
+
end
|
328
|
+
|
329
|
+
ReactOnRails::WebpackerUtils.raise_nested_entries_disabled unless ReactOnRails::WebpackerUtils.nested_entries?
|
330
|
+
|
331
|
+
ApplicationController.helpers.append_javascript_pack_tag "generated/#{component_name}"
|
332
|
+
ApplicationController.helpers.append_stylesheet_pack_tag "generated/#{component_name}"
|
333
|
+
end
|
334
|
+
|
335
|
+
def generated_components_pack_path(component_name)
|
336
|
+
"#{ReactOnRails::WebpackerUtils.webpacker_source_entry_path}/generated/#{component_name}.js"
|
337
|
+
end
|
338
|
+
|
340
339
|
def build_react_component_result_for_server_rendered_string(
|
341
340
|
server_rendered_html: required("server_rendered_html"),
|
342
341
|
component_specification_tag: required("component_specification_tag"),
|
@@ -552,10 +551,9 @@ module ReactOnRails
|
|
552
551
|
result
|
553
552
|
end
|
554
553
|
|
555
|
-
def
|
554
|
+
def raise_missing_pack_error(component_name)
|
556
555
|
msg = <<~MSG
|
557
|
-
**ERROR** ReactOnRails: Generated missing pack for Component: #{component_name}. Please
|
558
|
-
once webpack has finished generating the bundles. If the problem persists
|
556
|
+
**ERROR** ReactOnRails: Generated missing pack for Component: #{component_name}. Please restart the webpack dev server or webpack in watch mode, to ensure webpack generates the chunks corresponding to #{component_name} component. If the problem persists
|
559
557
|
1. Verify `components_subdirectory` is configured in `config/initializers/react_on_rails`.
|
560
558
|
2. Component: #{component_name} is placed inside the configured `components_subdirectory`.
|
561
559
|
MSG
|
@@ -6,45 +6,23 @@ module ReactOnRails
|
|
6
6
|
# rubocop:disable Metrics/ClassLength
|
7
7
|
class PacksGenerator
|
8
8
|
CONTAINS_CLIENT_OR_SERVER_REGEX = /\.(server|client)($|\.)/.freeze
|
9
|
-
|
10
|
-
MINIMUM_SHAKAPACKER_MINOR_VERSION = 5
|
11
|
-
MINIMUM_SHAKAPACKER_PATCH_VERSION = 1
|
9
|
+
MINIMUM_SHAKAPACKER_VERSION = [6, 5, 1].freeze
|
12
10
|
|
13
|
-
def self.
|
14
|
-
|
15
|
-
packs_generator.verify_setup_and_generate_packs
|
11
|
+
def self.instance
|
12
|
+
@instance ||= PacksGenerator.new
|
16
13
|
end
|
17
14
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def verify_setup_and_generate_packs
|
24
|
-
return unless components_subdirectory.present?
|
25
|
-
|
26
|
-
raise_webpacker_not_installed unless ReactOnRails::WebpackerUtils.using_webpacker?
|
27
|
-
raise_shakapacker_version_incompatible unless shackapacker_version_requirement_met?
|
28
|
-
raise_nested_enteries_disabled unless ReactOnRails::WebpackerUtils.nested_entries?
|
15
|
+
def generate_packs_if_stale
|
16
|
+
are_generated_files_present_and_up_to_date = Dir.exist?(generated_packs_directory_path) &&
|
17
|
+
File.exist?(generated_server_bundle_file_path) &&
|
18
|
+
!stale_or_missing_packs?
|
29
19
|
|
30
|
-
|
31
|
-
|
32
|
-
return if is_generated_directory_present && webpack_assets_status_checker.stale_generated_component_packs.empty?
|
20
|
+
return if are_generated_files_present_and_up_to_date
|
33
21
|
|
34
22
|
clean_generated_packs_directory
|
35
23
|
generate_packs
|
36
24
|
end
|
37
25
|
|
38
|
-
def raise_nested_enteries_disabled
|
39
|
-
msg = <<~MSG
|
40
|
-
**ERROR** ReactOnRails: `nested_entries` is configured to be disabled in shakapacker. Please update \
|
41
|
-
webpacker.yml to enable nested enteries. for more information read
|
42
|
-
https://www.shakacode.com/react-on-rails/docs/guides/file-system-based-automated-bundle-generation.md#enable-nested_entries-for-shakapacker
|
43
|
-
MSG
|
44
|
-
|
45
|
-
raise ReactOnRails::Error, msg
|
46
|
-
end
|
47
|
-
|
48
26
|
private
|
49
27
|
|
50
28
|
def generate_packs
|
@@ -100,22 +78,26 @@ module ReactOnRails
|
|
100
78
|
end
|
101
79
|
|
102
80
|
def add_generated_pack_to_server_bundle
|
103
|
-
relative_path_to_generated_server_bundle = relative_path(
|
81
|
+
relative_path_to_generated_server_bundle = relative_path(server_bundle_entrypoint,
|
104
82
|
generated_server_bundle_file_path)
|
105
83
|
content = <<~FILE_CONTENT
|
106
|
-
import
|
84
|
+
// import statement added by react_on_rails:generate_packs rake task
|
85
|
+
import "./#{relative_path_to_generated_server_bundle}"
|
107
86
|
FILE_CONTENT
|
108
87
|
|
109
|
-
|
88
|
+
ReactOnRails::Utils.prepend_to_file_if_text_not_present(
|
89
|
+
file: server_bundle_entrypoint,
|
90
|
+
text_to_prepend: content,
|
91
|
+
regex: %r{import ['"]\./#{relative_path_to_generated_server_bundle}['"]}
|
92
|
+
)
|
110
93
|
end
|
111
94
|
|
112
95
|
def generated_server_bundle_file_path
|
113
|
-
|
114
|
-
generated_server_bundle_file_path = defined_server_bundle_file_path.sub(file_ext, "-generated#{file_ext}")
|
96
|
+
generated_server_bundle_file_path = server_bundle_entrypoint.sub(".js", "-generated.js")
|
115
97
|
generated_server_bundle_file_name = component_name(generated_server_bundle_file_path)
|
116
98
|
source_entry_path = ReactOnRails::WebpackerUtils.webpacker_source_entry_path
|
117
99
|
|
118
|
-
"#{source_entry_path}/#{generated_server_bundle_file_name}
|
100
|
+
"#{source_entry_path}/#{generated_server_bundle_file_name}.js"
|
119
101
|
end
|
120
102
|
|
121
103
|
def clean_generated_packs_directory
|
@@ -123,8 +105,9 @@ module ReactOnRails
|
|
123
105
|
FileUtils.mkdir_p(generated_packs_directory_path)
|
124
106
|
end
|
125
107
|
|
126
|
-
def
|
127
|
-
ReactOnRails::
|
108
|
+
def server_bundle_entrypoint
|
109
|
+
Rails.root.join(ReactOnRails::WebpackerUtils.webpacker_source_entry_path,
|
110
|
+
ReactOnRails.configuration.server_bundle_js_file)
|
128
111
|
end
|
129
112
|
|
130
113
|
def generated_packs_directory_path
|
@@ -150,7 +133,7 @@ module ReactOnRails
|
|
150
133
|
end
|
151
134
|
|
152
135
|
def generated_pack_path(file_path)
|
153
|
-
"#{generated_packs_directory_path}/#{component_name(file_path)}.
|
136
|
+
"#{generated_packs_directory_path}/#{component_name(file_path)}.js"
|
154
137
|
end
|
155
138
|
|
156
139
|
def component_name(file_path)
|
@@ -197,23 +180,7 @@ module ReactOnRails
|
|
197
180
|
def components_search_path
|
198
181
|
source_path = ReactOnRails::WebpackerUtils.webpacker_source_path
|
199
182
|
|
200
|
-
"#{source_path}/**/#{components_subdirectory}"
|
201
|
-
end
|
202
|
-
|
203
|
-
def components_subdirectory
|
204
|
-
ReactOnRails.configuration.components_subdirectory
|
205
|
-
end
|
206
|
-
|
207
|
-
def webpack_assets_status_checker
|
208
|
-
source_path = ReactOnRails::Utils.source_path
|
209
|
-
generated_assets_full_path = ReactOnRails::Utils.generated_assets_full_path
|
210
|
-
webpack_generated_files = ReactOnRails.configuration.webpack_generated_files
|
211
|
-
|
212
|
-
@webpack_assets_status_checker ||= ReactOnRails::TestHelper::WebpackAssetsStatusChecker.new(
|
213
|
-
source_path: source_path,
|
214
|
-
generated_assets_full_path: generated_assets_full_path,
|
215
|
-
webpack_generated_files: webpack_generated_files
|
216
|
-
)
|
183
|
+
"#{source_path}/**/#{ReactOnRails.configuration.components_subdirectory}"
|
217
184
|
end
|
218
185
|
|
219
186
|
def raise_client_component_overrides_common(component_name)
|
@@ -245,53 +212,15 @@ module ReactOnRails
|
|
245
212
|
raise ReactOnRails::Error, msg
|
246
213
|
end
|
247
214
|
|
248
|
-
def
|
249
|
-
|
250
|
-
|
251
|
-
above to use the automated bundle generation feature. The currently installed version is \
|
252
|
-
#{ReactOnRails::WebpackerUtils.shakapacker_version}.
|
253
|
-
MSG
|
254
|
-
|
255
|
-
raise ReactOnRails::Error, msg
|
256
|
-
end
|
257
|
-
|
258
|
-
def raise_webpacker_not_installed
|
259
|
-
msg = <<~MSG
|
260
|
-
**ERROR** ReactOnRails: Missing Shakapacker gem. Please upgrade to use Shakapacker \
|
261
|
-
#{minimum_required_shakapacker_version} or above to use the \
|
262
|
-
automated bundle generation feature.
|
263
|
-
MSG
|
264
|
-
|
265
|
-
raise ReactOnRails::Error, msg
|
266
|
-
end
|
215
|
+
def stale_or_missing_packs?
|
216
|
+
component_files = common_component_to_path.values + client_component_to_path.values
|
217
|
+
most_recent_mtime = Utils.find_most_recent_mtime(component_files)
|
267
218
|
|
268
|
-
|
269
|
-
|
270
|
-
match = shakapacker_version.match(ReactOnRails::VersionChecker::MAJOR_MINOR_PATCH_VERSION_REGEX)
|
219
|
+
component_files.each_with_object([]).any? do |file|
|
220
|
+
path = generated_pack_path(file)
|
271
221
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
def shackapacker_version_requirement_met?
|
276
|
-
major = shakapacker_major_minor_version[0]
|
277
|
-
minor = shakapacker_major_minor_version[1]
|
278
|
-
patch = shakapacker_major_minor_version[2]
|
279
|
-
|
280
|
-
major >= MINIMUM_SHAKAPACKER_MAJOR_VERSION && minor >= MINIMUM_SHAKAPACKER_MINOR_VERSION &&
|
281
|
-
patch >= MINIMUM_SHAKAPACKER_PATCH_VERSION
|
282
|
-
end
|
283
|
-
|
284
|
-
def minimum_required_shakapacker_version
|
285
|
-
"#{MINIMUM_SHAKAPACKER_MAJOR_VERSION}.#{MINIMUM_SHAKAPACKER_MINOR_VERSION}.#{MINIMUM_SHAKAPACKER_PATCH_VERSION}"
|
286
|
-
end
|
287
|
-
|
288
|
-
def prepend_to_file_if_not_present(file, text_to_prepend)
|
289
|
-
file_content = File.read(file)
|
290
|
-
|
291
|
-
return if file_content.include?(text_to_prepend)
|
292
|
-
|
293
|
-
content_with_prepended_text = text_to_prepend + file_content
|
294
|
-
File.write(file, content_with_prepended_text)
|
222
|
+
!File.exist?(path) || File.mtime(path) < most_recent_mtime
|
223
|
+
end
|
295
224
|
end
|
296
225
|
end
|
297
226
|
# rubocop:enable Metrics/ClassLength
|
@@ -37,7 +37,7 @@ module ReactOnRails
|
|
37
37
|
# All done if no stale files!
|
38
38
|
return if stale_gen_files.empty?
|
39
39
|
|
40
|
-
ReactOnRails::PacksGenerator.
|
40
|
+
ReactOnRails::PacksGenerator.instance.generate_packs_if_stale
|
41
41
|
|
42
42
|
# Inform the developer that we're ensuring gen assets are ready.
|
43
43
|
puts_start_compile_check_message(stale_gen_files)
|