react_on_rails 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +320 -0
  3. data/.eslintignore +2 -1
  4. data/.eslintrc +30 -2
  5. data/.github/FUNDING.yml +1 -0
  6. data/.gitignore +3 -1
  7. data/.prettierignore +10 -0
  8. data/.prettierrc +23 -0
  9. data/.release-it.json +3 -0
  10. data/.rubocop.yml +39 -11
  11. data/.travis.yml +11 -22
  12. data/CHANGELOG.md +235 -6
  13. data/CONTRIBUTING.md +64 -84
  14. data/Gemfile +3 -5
  15. data/KUDOS.md +4 -1
  16. data/{docs/LICENSE.md → LICENSE.md} +1 -1
  17. data/PROJECTS.md +7 -1
  18. data/REACT-ON-RAILS-PRO-LICENSE +95 -0
  19. data/README.md +233 -630
  20. data/Rakefile +1 -5
  21. data/SUMMARY.md +42 -29
  22. data/book.json +5 -5
  23. data/docs/additional-reading/asset-pipeline.md +8 -16
  24. data/docs/additional-reading/convert-rails-5-api-only-app.md +19 -0
  25. data/docs/additional-reading/credits.md +10 -0
  26. data/docs/additional-reading/images.md +1 -1
  27. data/docs/additional-reading/rails-engine-integration.md +7 -0
  28. data/docs/additional-reading/rails_view_rendering_from_inline_javascript.md +2 -1
  29. data/docs/additional-reading/react-helmet.md +30 -10
  30. data/docs/additional-reading/react-router.md +52 -75
  31. data/docs/additional-reading/server-rendering-tips.md +14 -11
  32. data/docs/additional-reading/upgrade-webpacker-v3-to-v4.md +10 -0
  33. data/docs/additional-reading/webpack.md +2 -2
  34. data/docs/api/javascript-api.md +24 -4
  35. data/docs/api/redux-store-api.md +102 -0
  36. data/docs/api/view-helpers-api.md +133 -0
  37. data/docs/articles.md +20 -0
  38. data/docs/basics/client-vs-server-rendering.md +23 -0
  39. data/docs/basics/configuration.md +145 -61
  40. data/docs/basics/deployment.md +4 -0
  41. data/docs/basics/{generator.md → generator-details.md} +5 -8
  42. data/docs/basics/heroku-deployment.md +24 -0
  43. data/docs/basics/hmr-and-hot-reloading-with-the-webpack-dev-server.md +49 -0
  44. data/docs/basics/i18n.md +45 -23
  45. data/docs/basics/installation-into-an-existing-rails-app.md +59 -0
  46. data/docs/basics/minitest-configuration.md +31 -0
  47. data/docs/basics/react-server-rendering.md +29 -0
  48. data/docs/{additional-reading → basics}/recommended-project-structure.md +38 -10
  49. data/docs/basics/render-functions-and-railscontext.md +205 -0
  50. data/docs/basics/rspec-configuration.md +73 -0
  51. data/docs/basics/upgrading-react-on-rails.md +75 -4
  52. data/docs/basics/webpack-configuration.md +50 -0
  53. data/docs/contributor-info/errors-with-hooks.md +45 -0
  54. data/docs/contributor-info/pull-requests.md +44 -0
  55. data/docs/misc/doctrine.md +2 -2
  56. data/docs/{additional-reading → outdated}/code-splitting.md +19 -9
  57. data/docs/outdated/how-react-on-rails-works.md +44 -0
  58. data/docs/{basics/installation-overview.md → outdated/manual-installation-overview.md} +8 -13
  59. data/docs/{additional-reading → outdated}/rails-assets-relative-paths.md +3 -3
  60. data/docs/{additional-reading → outdated}/rails-assets.md +5 -13
  61. data/docs/testimonials/hvmn.md +25 -0
  62. data/docs/testimonials/resortpass.md +13 -0
  63. data/docs/testimonials/testimonials.md +28 -0
  64. data/docs/tutorial.md +182 -44
  65. data/jest.config.js +4 -0
  66. data/lib/generators/USAGE +1 -1
  67. data/lib/generators/react_on_rails/base_generator.rb +2 -2
  68. data/lib/generators/react_on_rails/dev_tests_generator.rb +3 -2
  69. data/lib/generators/react_on_rails/generator_helper.rb +4 -6
  70. data/lib/generators/react_on_rails/install_generator.rb +2 -0
  71. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +3 -1
  72. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-hmr +26 -0
  73. data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +20 -40
  74. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +4 -1
  75. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +4 -8
  76. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/store/helloWorldStore.js +1 -3
  77. data/lib/react_on_rails/configuration.rb +175 -102
  78. data/lib/react_on_rails/error.rb +2 -0
  79. data/lib/react_on_rails/git_utils.rb +2 -0
  80. data/lib/react_on_rails/{react_on_rails_helper.rb → helper.rb} +201 -225
  81. data/lib/react_on_rails/json_output.rb +1 -1
  82. data/lib/react_on_rails/json_parse_error.rb +28 -0
  83. data/lib/react_on_rails/locales/base.rb +150 -0
  84. data/lib/react_on_rails/locales/to_js.rb +37 -0
  85. data/lib/react_on_rails/locales/to_json.rb +27 -0
  86. data/lib/react_on_rails/prerender_error.rb +56 -18
  87. data/lib/react_on_rails/react_component/render_options.rb +98 -0
  88. data/lib/react_on_rails/server_rendering_js_code.rb +42 -0
  89. data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +139 -106
  90. data/lib/react_on_rails/server_rendering_pool.rb +4 -16
  91. data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +7 -8
  92. data/lib/react_on_rails/test_helper/webpack_assets_compiler.rb +17 -0
  93. data/lib/react_on_rails/test_helper/webpack_assets_status_checker.rb +10 -6
  94. data/lib/react_on_rails/test_helper.rb +18 -7
  95. data/lib/react_on_rails/utils.rb +66 -26
  96. data/lib/react_on_rails/version.rb +1 -1
  97. data/lib/react_on_rails/version_checker.rb +5 -1
  98. data/lib/react_on_rails/version_syntax_converter.rb +14 -12
  99. data/lib/react_on_rails/webpacker_utils.rb +44 -10
  100. data/lib/react_on_rails.rb +8 -3
  101. data/lib/tasks/assets.rake +33 -46
  102. data/lib/tasks/locale.rake +4 -2
  103. data/package-scripts.yml +49 -0
  104. data/package.json +49 -40
  105. data/rakelib/dummy_apps.rake +1 -9
  106. data/rakelib/example_type.rb +3 -1
  107. data/rakelib/examples.rake +3 -0
  108. data/rakelib/lint.rake +2 -7
  109. data/rakelib/node_package.rake +2 -2
  110. data/rakelib/release.rake +4 -8
  111. data/rakelib/run_rspec.rake +5 -18
  112. data/react_on_rails.gemspec +5 -6
  113. data/tsconfig.json +14 -0
  114. data/webpackConfigLoader.js +5 -4
  115. data/yarn.lock +7645 -1821
  116. metadata +71 -61
  117. data/Gemfile.rails32 +0 -74
  118. data/docs/additional-reading/babel.md +0 -5
  119. data/docs/additional-reading/caching-and-performance.md +0 -4
  120. data/docs/additional-reading/heroku-deployment.md +0 -92
  121. data/docs/additional-reading/hot-reloading-rails-development.md +0 -57
  122. data/docs/additional-reading/node-server-rendering.md +0 -5
  123. data/docs/additional-reading/rspec-configuration.md +0 -56
  124. data/docs/api/ruby-api-hot-reload-view-helpers.md +0 -44
  125. data/docs/api/ruby-api.md +0 -8
  126. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-server +0 -12
  127. data/lib/react_on_rails/assets_precompile.rb +0 -150
  128. data/lib/react_on_rails/locales_to_js.rb +0 -134
  129. data/lib/react_on_rails/react_component/options.rb +0 -64
  130. /data/docs/{misc → outdated}/rails3.md +0 -0
@@ -1,68 +1,86 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "open-uri"
4
+ require "execjs"
4
5
 
5
6
  module ReactOnRails
6
7
  module ServerRenderingPool
8
+ # rubocop:disable Metrics/ClassLength
7
9
  class RubyEmbeddedJavaScript
8
- def self.reset_pool
9
- options = {
10
- size: ReactOnRails.configuration.server_renderer_pool_size,
11
- timeout: ReactOnRails.configuration.server_renderer_timeout
12
- }
13
- @js_context_pool = ConnectionPool.new(options) { create_js_context }
14
- end
15
-
16
- def self.reset_pool_if_server_bundle_was_modified
17
- return unless ReactOnRails.configuration.development_mode
10
+ # rubocop:enable Metrics/ClassLength
11
+ class << self
12
+ def reset_pool
13
+ options = {
14
+ size: ReactOnRails.configuration.server_renderer_pool_size,
15
+ timeout: ReactOnRails.configuration.server_renderer_timeout
16
+ }
17
+ @js_context_pool = ConnectionPool.new(options) { create_js_context }
18
+ end
18
19
 
19
- file_mtime = File.mtime(ReactOnRails::Utils.server_bundle_js_file_path)
20
- @server_bundle_timestamp ||= file_mtime
21
- return if @server_bundle_timestamp == file_mtime
20
+ def reset_pool_if_server_bundle_was_modified
21
+ return unless ReactOnRails.configuration.development_mode
22
22
 
23
- @server_bundle_timestamp = file_mtime
23
+ if ReactOnRails::Utils.server_bundle_path_is_http?
24
+ return if @server_bundle_url == ReactOnRails::Utils.server_bundle_js_file_path
24
25
 
25
- ReactOnRails::ServerRenderingPool.reset_pool
26
- end
26
+ @server_bundle_url = ReactOnRails::Utils.server_bundle_js_file_path
27
+ else
28
+ file_mtime = File.mtime(ReactOnRails::Utils.server_bundle_js_file_path)
29
+ @server_bundle_timestamp ||= file_mtime
30
+ return if @server_bundle_timestamp == file_mtime
27
31
 
28
- # js_code: JavaScript expression that returns a string.
29
- # Returns a Hash:
30
- # html: string of HTML for direct insertion on the page by evaluating js_code
31
- # consoleReplayScript: script for replaying console
32
- # hasErrors: true if server rendering errors
33
- # Note, js_code does not have to be based on React.
34
- # js_code MUST RETURN json stringify Object
35
- # Calling code will probably call 'html_safe' on return value before rendering to the view.
36
- def self.server_render_js_with_console_logging(js_code)
37
- if ReactOnRails.configuration.trace
38
- @file_index ||= 1
39
- trace_js_code_used("Evaluating code to server render.", js_code,
40
- "tmp/server-generated-#{@file_index % 10}.js")
41
- @file_index += 1
32
+ @server_bundle_timestamp = file_mtime
33
+ end
34
+ ReactOnRails::ServerRenderingPool.reset_pool
42
35
  end
43
- json_string = eval_js(js_code)
44
- result = JSON.parse(json_string)
45
-
46
- if ReactOnRails.configuration.logging_on_server
47
- console_script = result["consoleReplayScript"]
48
- console_script_lines = console_script.split("\n")
49
- console_script_lines = console_script_lines[2..-2]
50
- re = /console\.(log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
51
- if console_script_lines
52
- console_script_lines.each do |line|
53
- match = re.match(line)
54
- Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
36
+
37
+ # js_code: JavaScript expression that returns a string.
38
+ # render_options: lib/react_on_rails/react_component/render_options.rb
39
+ # Using these options:
40
+ # trace: saves the executed JS to a file, used in development
41
+ # logging_on_server: put on server logs, not just in browser console
42
+ #
43
+ # Returns a Hash:
44
+ # html: string of HTML for direct insertion on the page by evaluating js_code
45
+ # consoleReplayScript: script for replaying console
46
+ # hasErrors: true if server rendering errors
47
+ # Note, js_code does not have to be based on React.
48
+ # js_code MUST RETURN json stringify Object
49
+ # Calling code will probably call 'html_safe' on return value before rendering to the view.
50
+ def exec_server_render_js(js_code, render_options, js_evaluator = nil)
51
+ js_evaluator ||= self
52
+ if render_options.trace
53
+ @file_index ||= 1
54
+ trace_js_code_used("Evaluating code to server render.", js_code,
55
+ "tmp/server-generated-#{@file_index % 10}.js")
56
+ @file_index += 1
57
+ end
58
+ json_string = js_evaluator.eval_js(js_code, render_options)
59
+ result = nil
60
+ begin
61
+ result = JSON.parse(json_string)
62
+ rescue JSON::ParserError => e
63
+ raise ReactOnRails::JsonParseError.new(e, json_string)
64
+ end
65
+
66
+ if render_options.logging_on_server
67
+ console_script = result["consoleReplayScript"]
68
+ console_script_lines = console_script.split("\n")
69
+ console_script_lines = console_script_lines[2..-2]
70
+ re = /console\.(log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
71
+ if console_script_lines
72
+ console_script_lines.each do |line|
73
+ match = re.match(line)
74
+ Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
75
+ end
55
76
  end
56
77
  end
78
+ result
57
79
  end
58
- result
59
- end
60
-
61
- class << self
62
- private
63
80
 
64
81
  def trace_js_code_used(msg, js_code, file_name = "tmp/server-generated.js", force: false)
65
82
  return unless ReactOnRails.configuration.trace || force
83
+
66
84
  # Set to anything to print generated code.
67
85
  File.write(file_name, js_code)
68
86
  msg = <<-MSG.strip_heredoc
@@ -78,7 +96,7 @@ module ReactOnRails
78
96
  end
79
97
  end
80
98
 
81
- def eval_js(js_code)
99
+ def eval_js(js_code, _render_options)
82
100
  @js_context_pool.with do |js_context|
83
101
  result = js_context.eval(js_code)
84
102
  js_context.eval("console.history = []")
@@ -86,30 +104,37 @@ module ReactOnRails
86
104
  end
87
105
  end
88
106
 
89
- def create_js_context
90
- return if ReactOnRails.configuration.server_bundle_js_file.blank?
91
-
107
+ def read_bundle_js_code
92
108
  server_js_file = ReactOnRails::Utils.server_bundle_js_file_path
93
-
94
- begin
95
- bundle_js_code = File.read(server_js_file)
96
- rescue StandardError => e
97
- msg = "You specified server rendering JS file: #{server_js_file}, but it cannot be "\
109
+ if ReactOnRails::Utils.server_bundle_path_is_http?
110
+ file_url_to_string(server_js_file)
111
+ else
112
+ File.read(server_js_file)
113
+ end
114
+ rescue StandardError => e
115
+ msg = "You specified server rendering JS file: #{server_js_file}, but it cannot be "\
98
116
  "read. You may set the server_bundle_js_file in your configuration to be \"\" to "\
99
117
  "avoid this warning.\nError is: #{e}"
100
- raise ReactOnRails::Error, msg
101
- end
102
- # rubocop:disable Layout/IndentHeredoc
103
- base_js_code = <<-JS
104
- #{console_polyfill}
105
- #{execjs_timer_polyfills}
106
- #{bundle_js_code};
118
+ raise ReactOnRails::Error, msg
119
+ end
120
+
121
+ def create_js_context
122
+ return if ReactOnRails.configuration.server_bundle_js_file.blank?
123
+
124
+ bundle_js_code = read_bundle_js_code
125
+ base_js_code = <<~JS
126
+ #{console_polyfill}
127
+ #{execjs_timer_polyfills}
128
+ #{bundle_js_code};
107
129
  JS
108
- # rubocop:enable Layout/IndentHeredoc
130
+
109
131
  file_name = "tmp/base_js_code.js"
110
132
  begin
111
133
  if ReactOnRails.configuration.trace
112
- Rails.logger.info { "[react_on_rails] Created JavaScript context with file #{server_js_file}" }
134
+ Rails.logger.info do
135
+ "[react_on_rails] Created JavaScript context with file "\
136
+ "#{ReactOnRails::Utils.server_bundle_js_file_path}"
137
+ end
113
138
  end
114
139
  ExecJS.compile(base_js_code)
115
140
  rescue StandardError => e
@@ -125,39 +150,36 @@ module ReactOnRails
125
150
  end
126
151
 
127
152
  def execjs_timer_polyfills
128
- # rubocop:disable Layout/IndentHeredoc
129
- <<-JS
130
- function getStackTrace () {
131
- var stack;
132
- try {
133
- throw new Error('');
134
- }
135
- catch (error) {
136
- stack = error.stack || '';
137
- }
138
- stack = stack.split('\\n').map(function (line) { return line.trim(); });
139
- return stack.splice(stack[0] == 'Error' ? 2 : 1);
140
- }
141
-
142
- function setInterval() {
143
- #{undefined_for_exec_js_logging('setInterval')}
144
- }
145
-
146
- function setTimeout() {
147
- #{undefined_for_exec_js_logging('setTimeout')}
148
- }
149
-
150
- function clearTimeout() {
151
- #{undefined_for_exec_js_logging('clearTimeout')}
152
- }
153
+ <<~JS
154
+ function getStackTrace () {
155
+ var stack;
156
+ try {
157
+ throw new Error('');
158
+ }
159
+ catch (error) {
160
+ stack = error.stack || '';
161
+ }
162
+ stack = stack.split('\\n').map(function (line) { return line.trim(); });
163
+ return stack.splice(stack[0] == 'Error' ? 2 : 1);
164
+ }
165
+
166
+ function setInterval() {
167
+ #{undefined_for_exec_js_logging('setInterval')}
168
+ }
169
+
170
+ function setTimeout() {
171
+ #{undefined_for_exec_js_logging('setTimeout')}
172
+ }
173
+
174
+ function clearTimeout() {
175
+ #{undefined_for_exec_js_logging('clearTimeout')}
176
+ }
153
177
  JS
154
- # rubocop:enable Layout/IndentHeredoc
155
178
  end
156
179
 
157
180
  def undefined_for_exec_js_logging(function_name)
158
181
  if ReactOnRails.configuration.trace
159
- "console.error('[React on Rails Rendering] #{function_name} is not defined for execJS. See "\
160
- "https://github.com/sstephenson/execjs#faq. Note babel-polyfill may call this.');\n"\
182
+ "console.error('[React on Rails Rendering] #{function_name} is not defined for server rendering.');\n"\
161
183
  " console.error(getStackTrace().join('\\n'));"
162
184
  else
163
185
  ""
@@ -166,20 +188,31 @@ function clearTimeout() {
166
188
 
167
189
  # Reimplement console methods for replaying on the client
168
190
  def console_polyfill
169
- # rubocop:disable Layout/IndentHeredoc
170
- <<-JS
171
- var console = { history: [] };
172
- ['error', 'log', 'info', 'warn'].forEach(function (level) {
173
- console[level] = function () {
174
- var argArray = Array.prototype.slice.call(arguments);
175
- if (argArray.length > 0) {
176
- argArray[0] = '[SERVER] ' + argArray[0];
177
- }
178
- console.history.push({level: level, arguments: argArray});
179
- };
180
- });
191
+ <<~JS
192
+ var console = { history: [] };
193
+ ['error', 'log', 'info', 'warn'].forEach(function (level) {
194
+ console[level] = function () {
195
+ var argArray = Array.prototype.slice.call(arguments);
196
+ if (argArray.length > 0) {
197
+ argArray[0] = '[SERVER] ' + argArray[0];
198
+ }
199
+ console.history.push({level: level, arguments: argArray});
200
+ };
201
+ });
181
202
  JS
182
- # rubocop:enable Layout/IndentHeredoc
203
+ end
204
+
205
+ private
206
+
207
+ def file_url_to_string(url)
208
+ response = Net::HTTP.get_response(URI.parse(url))
209
+ content_type_header = response["content-type"]
210
+ match = content_type_header.match(/\A.*; charset=(?<encoding>.*)\z/)
211
+ encoding_type = match[:encoding]
212
+ response.body.force_encoding(encoding_type)
213
+ rescue StandardError => e
214
+ msg = "file_url_to_string #{url} failed\nError is: #{e}"
215
+ raise ReactOnRails::Error, msg
183
216
  end
184
217
  end
185
218
  end
@@ -5,33 +5,21 @@ require_relative "server_rendering_pool/ruby_embedded_java_script"
5
5
 
6
6
  # Based on the react-rails gem.
7
7
  # None of these methods should be called directly.
8
- # See app/helpers/react_on_rails_helper.rb
9
8
  module ReactOnRails
10
9
  module ServerRenderingPool
11
10
  class << self
12
- def react_on_rails_pro?
13
- @react_on_rails_pro ||= gem_available?("react_on_rails_pro")
14
- end
15
-
16
11
  def pool
17
- @pool ||= if react_on_rails_pro?
12
+ @pool ||= if ReactOnRails::Utils.react_on_rails_pro?
18
13
  ReactOnRailsPro::ServerRenderingPool::ProRendering
19
14
  else
20
15
  ReactOnRails::ServerRenderingPool::RubyEmbeddedJavaScript
21
16
  end
22
17
  end
23
18
 
24
- delegate :server_render_js_with_console_logging, :reset_pool_if_server_bundle_was_modified,
25
- :reset_pool, to: :pool
26
-
27
- private
19
+ delegate :reset_pool_if_server_bundle_was_modified, :reset_pool, to: :pool
28
20
 
29
- def gem_available?(name)
30
- Gem::Specification.find_by_name(name)
31
- rescue Gem::LoadError
32
- false
33
- rescue StandardError
34
- Gem.available?(name)
21
+ def server_render_js_with_console_logging(js_code, render_options)
22
+ pool.exec_server_render_js(js_code, render_options)
35
23
  end
36
24
  end
37
25
  end
@@ -5,6 +5,7 @@ module ReactOnRails
5
5
  class EnsureAssetsCompiled
6
6
  class << self
7
7
  attr_accessor :has_been_run
8
+
8
9
  @has_been_run = false
9
10
  end
10
11
 
@@ -29,7 +30,7 @@ module ReactOnRails
29
30
  # Be sure we don't do this again.
30
31
  self.class.has_been_run = true
31
32
 
32
- ReactOnRails::LocalesToJs.new
33
+ ReactOnRails::Locales.compile
33
34
 
34
35
  stale_gen_files = webpack_assets_status_checker.stale_generated_webpack_files
35
36
 
@@ -43,17 +44,15 @@ module ReactOnRails
43
44
  end
44
45
 
45
46
  def puts_start_compile_check_message(stale_files)
46
- # rubocop:disable Layout/IndentHeredoc
47
- puts <<-MSG
47
+ puts <<~MSG
48
48
 
49
- Detected the following stale generated files:
50
- #{stale_files.join("\n ")}
49
+ Detected the following stale generated files:
50
+ #{stale_files.join("\n ")}
51
51
 
52
- React on Rails will ensure your JavaScript generated files are up to date, using your
53
- `#{ReactOnRails::Utils.prepend_cd_node_modules_directory(ReactOnRails.configuration.build_test_command)}` command.
52
+ React on Rails will ensure your JavaScript generated files are up to date, using your
53
+ `#{ReactOnRails::Utils.prepend_cd_node_modules_directory(ReactOnRails.configuration.build_test_command)}` command.
54
54
 
55
55
  MSG
56
- # rubocop:enable Layout/IndentHeredoc
57
56
  end
58
57
  end
59
58
  end
@@ -6,6 +6,23 @@ module ReactOnRails
6
6
  module TestHelper
7
7
  class WebpackAssetsCompiler
8
8
  def compile_assets
9
+ if ReactOnRails.configuration.build_test_command.blank?
10
+ msg = <<~MSG
11
+ You are using the React on Rails test helper.
12
+ Either you used:
13
+ ReactOnRails::TestHelper.configure_rspec_to_compile_assets or
14
+ ReactOnRails::TestHelper.ensure_assets_compiled
15
+ but you did not specify the config.build_test_command
16
+
17
+ React on Rails is aborting your test run
18
+
19
+ If you wish to use the config/webpacker.yml compile option for tests
20
+ them remove your call to the ReactOnRails test helper.
21
+ MSG
22
+ puts Rainbow(msg).red
23
+ exit!(1)
24
+ end
25
+
9
26
  puts "\nBuilding Webpack assets..."
10
27
 
11
28
  cmd = ReactOnRails::Utils.prepend_cd_node_modules_directory(
@@ -13,14 +13,14 @@ module ReactOnRails
13
13
  # source_path is typically configured in the webpacker.yml file
14
14
  # for `source_path`
15
15
  # or for legacy React on Rails, it's /client, where all client files go
16
- attr_reader :source_path, :generated_assets_dir
16
+ attr_reader :source_path, :generated_assets_full_path
17
17
 
18
18
  def initialize(
19
- generated_assets_dir: required("generated_assets_dir"),
19
+ generated_assets_full_path: required("generated_assets_full_path"),
20
20
  source_path: required("source_path"),
21
21
  webpack_generated_files: required("webpack_generated_files")
22
22
  )
23
- @generated_assets_dir = generated_assets_dir
23
+ @generated_assets_full_path = generated_assets_full_path
24
24
  @source_path = source_path
25
25
  @webpack_generated_files = webpack_generated_files
26
26
  end
@@ -53,19 +53,23 @@ module ReactOnRails
53
53
  def all_compiled_assets
54
54
  @all_compiled_assets ||= begin
55
55
  webpack_generated_files = @webpack_generated_files.map do |bundle_name|
56
- ReactOnRails::Utils.bundle_js_file_path(bundle_name)
56
+ if bundle_name == ReactOnRails.configuration.server_bundle_js_file
57
+ ReactOnRails::Utils.server_bundle_js_file_path
58
+ else
59
+ ReactOnRails::Utils.bundle_js_file_path(bundle_name)
60
+ end
57
61
  end
58
62
 
59
63
  if webpack_generated_files.present?
60
64
  webpack_generated_files
61
65
  else
62
- file_list = make_file_list(make_globs(generated_assets_dir)).to_ary
66
+ file_list = make_file_list(make_globs(generated_assets_full_path)).to_ary
63
67
  puts "V" * 80
64
68
  puts "Please define config.webpack_generated_files (array) so the test helper knows "\
65
69
  "which files are required. If you are using webpacker, you typically need to only "\
66
70
  "include 'manifest.json'."
67
71
  puts "Detected the possible following files to check for webpack compilation in "\
68
- "#{generated_assets_dir}"
72
+ "#{generated_assets_full_path}"
69
73
  puts file_list.join("\n")
70
74
  puts "^" * 80
71
75
  file_list
@@ -31,7 +31,7 @@ module ReactOnRails
31
31
  # Params:
32
32
  # config - config for rspec
33
33
  # metatags - metatags to add the ensure_assets_compiled check.
34
- # Default is :js, :server_rendering
34
+ # Default is :js, :server_rendering, :controller
35
35
  def self.configure_rspec_to_compile_assets(config, *metatags)
36
36
  metatags = %i[js server_rendering controller] if metatags.empty?
37
37
 
@@ -48,32 +48,43 @@ module ReactOnRails
48
48
  # defaults to ReactOnRails::TestHelper::WebpackAssetsStatusChecker
49
49
  # webpack_assets_compiler: provide one method: `def compile`
50
50
  # defaults to ReactOnRails::TestHelper::WebpackAssetsCompiler
51
- # source_path and generated_assets_dir are passed into the default webpack_assets_status_checker if you
51
+ # source_path and generated_assets_full_path are passed into the default webpack_assets_status_checker if you
52
52
  # don't provide one.
53
53
  # webpack_generated_files List of files to check for up-to-date-status, defaulting to
54
54
  # webpack_generated_files in your configuration
55
55
  def self.ensure_assets_compiled(webpack_assets_status_checker: nil,
56
56
  webpack_assets_compiler: nil,
57
57
  source_path: nil,
58
- generated_assets_dir: nil,
58
+ generated_assets_full_path: nil,
59
59
  webpack_generated_files: nil)
60
60
  ReactOnRails::WebpackerUtils.check_manifest_not_cached
61
61
  if webpack_assets_status_checker.nil?
62
62
  source_path ||= ReactOnRails::Utils.source_path
63
- generated_assets_dir ||= ReactOnRails::Utils.generated_assets_dir
63
+ generated_assets_full_path ||= ReactOnRails::Utils.generated_assets_full_path
64
64
  webpack_generated_files ||= ReactOnRails.configuration.webpack_generated_files
65
65
 
66
66
  webpack_assets_status_checker ||=
67
67
  WebpackAssetsStatusChecker.new(source_path: source_path,
68
- generated_assets_dir: generated_assets_dir,
68
+ generated_assets_full_path: generated_assets_full_path,
69
69
  webpack_generated_files: webpack_generated_files)
70
70
 
71
71
  unless @printed_once
72
72
  puts
73
- puts "====> React On Rails: Checking #{webpack_assets_status_checker.generated_assets_dir} for "\
74
- "outdated/missing bundles"
73
+ puts "====> React On Rails: Checking files in "\
74
+ "#{webpack_assets_status_checker.generated_assets_full_path} for "\
75
+ "outdated/missing bundles based on source_path #{source_path}"
75
76
  puts
76
77
  @printed_once = true
78
+
79
+ if ReactOnRails::WebpackerUtils.using_webpacker? &&
80
+ ReactOnRails::Utils.using_webpacker_source_path_is_not_defined_and_custom_node_modules?
81
+ msg = <<-MSG.strip_heredoc
82
+ WARNING: Define config.webpacker.yml to include sourcePath to configure
83
+ the location of your JavaScript source for React on Rails.
84
+ Default location of #{source_path} is used.
85
+ MSG
86
+ puts ReactOnRails::Utils.wrap_message(msg, :orange)
87
+ end
77
88
  end
78
89
  end
79
90