react_on_rails 12.0.5.beta.0 → 12.4.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +23 -11
  3. data/.eslintrc +2 -0
  4. data/.prettierrc +0 -3
  5. data/.rubocop.yml +40 -2
  6. data/CHANGELOG.md +56 -26
  7. data/CONTRIBUTING.md +3 -2
  8. data/Gemfile.development_dependencies +4 -3
  9. data/NEWS.md +9 -4
  10. data/README.md +28 -323
  11. data/Rakefile +1 -1
  12. data/SUMMARY.md +12 -12
  13. data/docs/{basics → additional-details}/generator-details.md +1 -6
  14. data/docs/{outdated → additional-details}/manual-installation-overview.md +6 -6
  15. data/docs/{basics → additional-details}/migrating-from-react-rails.md +0 -0
  16. data/docs/{additional-reading → additional-details}/recommended-project-structure.md +0 -0
  17. data/docs/{additional-reading → additional-details}/updating-dependencies.md +0 -0
  18. data/docs/additional-details/upgrade-webpacker-v3-to-v4.md +10 -0
  19. data/docs/api/javascript-api.md +2 -2
  20. data/docs/api/redux-store-api.md +3 -3
  21. data/docs/api/view-helpers-api.md +7 -8
  22. data/docs/contributor-info/linters.md +5 -6
  23. data/docs/contributor-info/pull-requests.md +2 -4
  24. data/docs/contributor-info/releasing.md +1 -1
  25. data/docs/{additional-reading → deployment}/elastic-beanstalk.md +0 -0
  26. data/docs/{basics → deployment}/heroku-deployment.md +0 -0
  27. data/docs/{basics → guides}/client-vs-server-rendering.md +3 -3
  28. data/docs/{basics → guides}/configuration.md +45 -25
  29. data/docs/guides/deployment.md +4 -0
  30. data/docs/guides/getting-started.md +183 -0
  31. data/docs/{basics → guides}/hmr-and-hot-reloading-with-the-webpack-dev-server.md +0 -0
  32. data/docs/{outdated → guides}/how-react-on-rails-works.md +9 -8
  33. data/docs/guides/how-to-conditionally-server-render-based-on-device-type.md +39 -0
  34. data/docs/guides/how-to-use-different-files-for-client-and-server-rendering.md +98 -0
  35. data/docs/{basics → guides}/i18n.md +0 -0
  36. data/docs/{basics → guides}/installation-into-an-existing-rails-app.md +3 -3
  37. data/docs/{basics → guides}/minitest-configuration.md +0 -0
  38. data/docs/guides/rails-webpacker-react-integration-options.md +182 -0
  39. data/docs/guides/react-on-rails-overview.md +30 -0
  40. data/docs/{basics → guides}/react-server-rendering.md +3 -3
  41. data/docs/{basics → guides}/render-functions-and-railscontext.md +0 -0
  42. data/docs/{basics → guides}/rspec-configuration.md +10 -10
  43. data/docs/{tutorial.md → guides/tutorial.md} +9 -11
  44. data/docs/{basics → guides}/upgrading-react-on-rails.md +7 -7
  45. data/docs/{basics → guides}/webpack-configuration.md +4 -6
  46. data/docs/home.md +23 -0
  47. data/docs/{additional-reading → javascript}/angular-js-integration-migration.md +0 -0
  48. data/docs/{additional-reading → javascript}/asset-pipeline.md +0 -0
  49. data/docs/{additional-reading → javascript}/capistrano-deployment.md +0 -0
  50. data/docs/{outdated → javascript}/code-splitting.md +3 -3
  51. data/docs/{additional-reading → javascript}/converting-from-custom-webpack-config-to-rails-webpacker-config.md +3 -3
  52. data/docs/{additional-reading → javascript}/credits.md +0 -0
  53. data/docs/{additional-reading → javascript}/foreman-issues.md +0 -0
  54. data/docs/{additional-reading → javascript}/images.md +5 -6
  55. data/docs/{additional-reading → javascript}/node-dependencies-and-npm.md +0 -0
  56. data/docs/{additional-reading → javascript}/react-and-redux.md +0 -0
  57. data/docs/{additional-reading → javascript}/react-helmet.md +0 -0
  58. data/docs/{additional-reading → javascript}/react-router.md +0 -0
  59. data/docs/{additional-reading → javascript}/server-rendering-tips.md +0 -0
  60. data/docs/{additional-reading → javascript}/troubleshooting-when-using-webpacker.md +0 -0
  61. data/docs/{additional-reading → javascript}/webpack-v1-notes.md +0 -0
  62. data/docs/{additional-reading → javascript}/webpack.md +0 -0
  63. data/docs/{articles.md → misc/articles.md} +1 -1
  64. data/docs/misc/doctrine.md +5 -5
  65. data/docs/{coding-style → misc}/style.md +0 -0
  66. data/docs/{additional-reading → misc}/tips.md +0 -0
  67. data/docs/outdated/deferred-rendering.md +39 -0
  68. data/docs/outdated/rails-assets-relative-paths.md +3 -3
  69. data/docs/outdated/rails-assets.md +8 -8
  70. data/docs/outdated/rails3.md +2 -2
  71. data/docs/{additional-reading → rails}/convert-rails-5-api-only-app.md +1 -1
  72. data/docs/{additional-reading → rails}/rails-engine-integration.md +3 -12
  73. data/docs/{additional-reading → rails}/rails_view_rendering_from_inline_javascript.md +0 -0
  74. data/docs/{additional-reading → rails}/turbolinks.md +13 -1
  75. data/docs/react-on-rails-pro/react-on-rails-pro.md +43 -0
  76. data/docs/testimonials/testimonials.md +6 -6
  77. data/lib/generators/react_on_rails/base_generator.rb +1 -1
  78. data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -1
  79. data/lib/generators/react_on_rails/templates/dev_tests/spec/rails_helper.rb +4 -1
  80. data/lib/generators/react_on_rails/templates/dev_tests/spec/{features → system}/hello_world_spec.rb +2 -2
  81. data/lib/react_on_rails/helper.rb +26 -2
  82. data/lib/react_on_rails/locales/base.rb +7 -9
  83. data/lib/react_on_rails/react_component/render_options.rb +16 -7
  84. data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +11 -0
  85. data/lib/react_on_rails/utils.rb +16 -2
  86. data/lib/react_on_rails/version.rb +1 -1
  87. data/lib/react_on_rails/webpacker_utils.rb +5 -1
  88. data/lib/tasks/assets.rake +17 -6
  89. data/package.json +24 -29
  90. data/rakelib/release.rake +22 -6
  91. data/rakelib/task_helpers.rb +15 -2
  92. data/yarn.lock +2549 -5169
  93. metadata +56 -49
  94. data/.release-it.json +0 -3
  95. data/docs/additional-reading/upgrade-webpacker-v3-to-v4.md +0 -10
  96. data/docs/basics/deployment.md +0 -4
@@ -11,6 +11,7 @@ module ReactOnRails
11
11
 
12
12
  NO_PROPS = {}.freeze
13
13
 
14
+ # TODO: remove the required for named params
14
15
  def initialize(react_component_name: required("react_component_name"), options: required("options"))
15
16
  @react_component_name = react_component_name.camelize
16
17
  @options = options
@@ -18,12 +19,16 @@ module ReactOnRails
18
19
 
19
20
  attr_reader :react_component_name
20
21
 
22
+ def throw_js_errors
23
+ options.fetch(:throw_js_errors, false)
24
+ end
25
+
21
26
  def props
22
27
  options.fetch(:props) { NO_PROPS }
23
28
  end
24
29
 
25
30
  def random_dom_id
26
- retrieve_key(:random_dom_id)
31
+ retrieve_configuration_value_for(:random_dom_id)
27
32
  end
28
33
 
29
34
  def dom_id
@@ -49,23 +54,23 @@ module ReactOnRails
49
54
  end
50
55
 
51
56
  def prerender
52
- retrieve_key(:prerender)
57
+ retrieve_configuration_value_for(:prerender)
53
58
  end
54
59
 
55
60
  def trace
56
- retrieve_key(:trace)
61
+ retrieve_configuration_value_for(:trace)
57
62
  end
58
63
 
59
64
  def replay_console
60
- retrieve_key(:replay_console)
65
+ retrieve_configuration_value_for(:replay_console)
61
66
  end
62
67
 
63
68
  def raise_on_prerender_error
64
- retrieve_key(:raise_on_prerender_error)
69
+ retrieve_configuration_value_for(:raise_on_prerender_error)
65
70
  end
66
71
 
67
72
  def logging_on_server
68
- retrieve_key(:logging_on_server)
73
+ retrieve_configuration_value_for(:logging_on_server)
69
74
  end
70
75
 
71
76
  def to_s
@@ -76,6 +81,10 @@ module ReactOnRails
76
81
  options[key]
77
82
  end
78
83
 
84
+ def set_option(key, value)
85
+ options[key] = value
86
+ end
87
+
79
88
  private
80
89
 
81
90
  attr_reader :options
@@ -88,7 +97,7 @@ module ReactOnRails
88
97
  "#{base_dom_id}-#{SecureRandom.uuid}"
89
98
  end
90
99
 
91
- def retrieve_key(key)
100
+ def retrieve_configuration_value_for(key)
92
101
  options.fetch(key) do
93
102
  ReactOnRails.configuration.public_send(key)
94
103
  end
@@ -150,6 +150,10 @@ module ReactOnRails
150
150
  end
151
151
 
152
152
  def execjs_timer_polyfills
153
+ if ReactOnRails::Utils.react_on_rails_pro? && ReactOnRailsPro.configuration.execjs_polyfills == false
154
+ return ""
155
+ end
156
+
153
157
  <<~JS
154
158
  function getStackTrace () {
155
159
  var stack;
@@ -187,8 +191,10 @@ module ReactOnRails
187
191
  end
188
192
 
189
193
  # Reimplement console methods for replaying on the client
194
+ # Save a handle to the original console if needed.
190
195
  def console_polyfill
191
196
  <<~JS
197
+ var debugConsole = console;
192
198
  var console = { history: [] };
193
199
  ['error', 'log', 'info', 'warn'].forEach(function (level) {
194
200
  console[level] = function () {
@@ -202,6 +208,11 @@ module ReactOnRails
202
208
  JS
203
209
  end
204
210
 
211
+ if defined?(ScoutApm)
212
+ include ScoutApm::Tracer
213
+ instrument_method :exec_server_render_js, type: "ReactOnRails", name: "ExecJs React Server Rendering"
214
+ end
215
+
205
216
  private
206
217
 
207
218
  def file_url_to_string(url)
@@ -158,15 +158,29 @@ module ReactOnRails
158
158
  end
159
159
 
160
160
  def self.gem_available?(name)
161
- Gem::Specification.find_all_by_name(name).present?
161
+ Gem.loaded_specs[name].present?
162
162
  rescue Gem::LoadError
163
163
  false
164
164
  rescue StandardError
165
165
  Gem.available?(name).present?
166
166
  end
167
167
 
168
+ # Todo -- remove this for v13, as we don't need both boolean and number
168
169
  def self.react_on_rails_pro?
169
- @react_on_rails_pro ||= gem_available?("react_on_rails_pro")
170
+ return @react_on_rails_pro if defined?(@react_on_rails_pro)
171
+
172
+ @react_on_rails_pro = gem_available?("react_on_rails_pro")
173
+ end
174
+
175
+ # Return an empty string if React on Rails Pro is not installed
176
+ def self.react_on_rails_pro_version
177
+ return @react_on_rails_pro_version if defined?(@react_on_rails_pro_version)
178
+
179
+ @react_on_rails_pro_version = if react_on_rails_pro?
180
+ Gem.loaded_specs["react_on_rails_pro"].version.to_s
181
+ else
182
+ ""
183
+ end
170
184
  end
171
185
 
172
186
  def self.smart_trim(str, max_length = 1000)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReactOnRails
4
- VERSION = "12.0.5.beta.0"
4
+ VERSION = "12.4.0.rc.0"
5
5
  end
@@ -2,8 +2,12 @@
2
2
 
3
3
  module ReactOnRails
4
4
  module WebpackerUtils
5
+ # TODO: V13 code should be cleaned up so that the webpacker gem is required.
6
+ # This check should only be done at startup.
5
7
  def self.using_webpacker?
6
- ReactOnRails::Utils.gem_available?("webpacker")
8
+ return @using_webpacker if defined?(@using_webpacker)
9
+
10
+ @using_webpacker = ReactOnRails::Utils.gem_available?("webpacker")
7
11
  end
8
12
 
9
13
  def self.webpacker_webpack_production_config_exists?
@@ -6,9 +6,10 @@
6
6
  require "active_support"
7
7
 
8
8
  ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
9
- ENV["NODE_ENV"] ||= "development"
10
9
 
11
- unless ReactOnRails::WebpackerUtils.webpacker_webpack_production_config_exists?
10
+ skip_react_on_rails_precompile = %w[no false n f].include?(ENV["REACT_ON_RAILS_PRECOMPILE"])
11
+
12
+ if !skip_react_on_rails_precompile && !ReactOnRails::WebpackerUtils.webpacker_webpack_production_config_exists?
12
13
  # Ensure that rails/webpacker does not call bin/webpack if we're providing
13
14
  # the build command.
14
15
  ENV["WEBPACKER_PRECOMPILE"] = "false"
@@ -47,10 +48,20 @@ namespace :react_on_rails do
47
48
  configuration file config/webpack/production.js exists.
48
49
  DESC
49
50
  task webpack: :locale do
50
- if ReactOnRails.configuration.build_production_command.present?
51
- sh ReactOnRails::Utils.prepend_cd_node_modules_directory(
52
- ReactOnRails.configuration.build_production_command
53
- ).to_s
51
+ build_production_command = ReactOnRails.configuration.build_production_command
52
+ if build_production_command.present?
53
+ if build_production_command.is_a?(String)
54
+ sh ReactOnRails::Utils.prepend_cd_node_modules_directory(
55
+ build_production_command
56
+ ).to_s
57
+ elsif build_production_command.methods.include?(:call)
58
+ build_production_command.call
59
+ else
60
+ msg = "ReactonRails.configuration.build_production_command is improperly configured. "\
61
+ "Value = #{build_production_command} with class #{build_production_command.class}"
62
+ puts Rainbow(msg).red
63
+ exit!(1)
64
+ end
54
65
  else
55
66
  msg = <<~MSG
56
67
  React on Rails is aborting webpack compilation from task react_on_rails:assets:webpack
data/package.json CHANGED
@@ -1,56 +1,51 @@
1
1
  {
2
2
  "name": "react-on-rails",
3
- "version": "12.0.5-beta.0",
3
+ "version": "12.4.0-rc.0",
4
4
  "description": "react-on-rails JavaScript for react_on_rails Ruby gem",
5
5
  "main": "node_package/lib/ReactOnRails.js",
6
6
  "directories": {
7
7
  "doc": "docs"
8
8
  },
9
9
  "devDependencies": {
10
- "@babel/cli": "^7.0.0",
11
- "@babel/core": "^7.0.0",
12
- "@babel/plugin-transform-runtime": "^7.0.0",
13
- "@babel/plugin-transform-typescript": "^7.8.7",
14
- "@babel/preset-env": "^7.0.0",
15
- "@babel/preset-react": "^7.0.0",
16
- "@babel/types": "^7.0.0",
17
- "@types/jest": "^25.1.4",
18
- "@types/node": "^13.9.0",
10
+ "@babel/cli": "^7.12.10",
11
+ "@babel/core": "^7.12.10",
12
+ "@babel/plugin-transform-runtime": "^7.12.10",
13
+ "@babel/plugin-transform-typescript": "^7.12.1",
14
+ "@babel/preset-env": "^7.12.10",
15
+ "@babel/preset-react": "^7.12.10",
16
+ "@babel/types": "^7.12.10",
17
+ "@types/jest": "^26.0.18",
18
+ "@types/node": "^14.14.11",
19
19
  "@types/react": "^16.9.23",
20
20
  "@types/react-dom": "^16.9.5",
21
21
  "@types/turbolinks": "^5.2.0",
22
- "@typescript-eslint/eslint-plugin": "^2.23.0",
23
- "@typescript-eslint/parser": "^2.23.0",
24
- "babel-loader": "^8.0.2",
22
+ "@typescript-eslint/eslint-plugin": "^4.10.0",
23
+ "@typescript-eslint/parser": "^4.10.0",
25
24
  "babelify": "^10.0.0",
26
25
  "blue-tape": "^1.0.0",
27
26
  "create-react-class": "^15.6.0",
28
- "eslint": "^6.8.0",
29
- "eslint-config-prettier": "^6.10.1",
27
+ "eslint": "^7.15.0",
28
+ "eslint-config-prettier": "^7.0.0",
30
29
  "eslint-config-shakacode": "^16.0.1",
31
- "eslint-plugin-import": "^2.6.1",
32
- "eslint-plugin-jsx-a11y": "^6.1.2",
33
- "eslint-plugin-prettier": "^3.0.0",
34
- "eslint-plugin-react": "^7.1.0",
35
- "jest": "^25.1.0",
36
- "jsdom": "^11.1.0",
30
+ "eslint-plugin-import": "^2.22.1",
31
+ "eslint-plugin-jsx-a11y": "^6.4.1",
32
+ "eslint-plugin-prettier": "^3.3.0",
33
+ "eslint-plugin-react": "^7.21.5",
34
+ "jest": "^26.6.3",
35
+ "jsdom": "^16.4.0",
37
36
  "nps": "^5.9.3",
38
- "prettier": "^2.0.1",
37
+ "prettier": "^2.2.1",
39
38
  "prettier-eslint-cli": "^5.0.0",
40
39
  "prop-types": "^15.5.10",
41
40
  "react": "^16.5.2",
42
41
  "react-dom": "^16.5.2",
43
42
  "react-transform-hmr": "^1.0.4",
44
43
  "redux": "^4.0.1",
45
- "release-it": "^8.2.0",
46
- "ts-jest": "^25.2.1",
47
- "tslint-config-prettier": "^1.18.0",
48
- "typescript": "^3.8.3",
49
- "webpack": "^3.4.1",
50
- "webpack-manifest-plugin": "^1.2.1"
44
+ "ts-jest": "^26.4.4",
45
+ "typescript": "^4.1.2"
51
46
  },
52
47
  "dependencies": {
53
- "@babel/runtime-corejs3": "^7.9.6",
48
+ "@babel/runtime-corejs3": "^7.12.5",
54
49
  "concurrently": "^5.1.0"
55
50
  },
56
51
  "peerDependencies": {
data/rakelib/release.rake CHANGED
@@ -11,6 +11,8 @@ class RaisingMessageHandler
11
11
  end
12
12
  end
13
13
 
14
+ # rubocop:disable Metrics/BlockLength
15
+
14
16
  desc("Releases both the gem and node package using the given version.
15
17
 
16
18
  IMPORTANT: the gem version must be in valid rubygem format (no dashes).
@@ -19,7 +21,7 @@ for the node package version. This only makes a difference for pre-release
19
21
  versions such as `3.0.0.beta.1` (yarn version would be `3.0.0-beta.1`).
20
22
 
21
23
  This task depends on the gem-release (ruby gem) and release-it (node package)
22
- which are installed via `bundle install` and `yarn`
24
+ which are installed via `bundle install` and `yarn global add release-it`
23
25
 
24
26
  1st argument: The new version in rubygem format (no dashes). Pass no argument to
25
27
  automatically perform a patch version bump.
@@ -55,16 +57,30 @@ task :release, %i[gem_version dry_run tools_install] do |_t, args|
55
57
  # Update dummy app's Gemfile.lock
56
58
  bundle_install_in(dummy_app_dir)
57
59
 
58
- # Stage changes so far
59
- sh_in_dir(gem_root, "git add .")
60
-
61
60
  # Will bump the yarn version, commit, tag the commit, push to repo, and release on yarn
62
- release_it_command = +"$(yarn bin)/release-it"
61
+ release_it_command = +"release-it"
63
62
  release_it_command << " #{npm_version}" unless npm_version.strip.empty?
64
- release_it_command << " --non-interactive --npm.publish"
63
+ release_it_command << " --ci --npm.publish --no-git.requireCleanWorkingDir"
65
64
  release_it_command << " --dry-run --verbose" if is_dry_run
66
65
  sh_in_dir(gem_root, release_it_command)
67
66
 
68
67
  # Release the new gem version
69
68
  sh_in_dir(gem_root, "gem release") unless is_dry_run
69
+
70
+ msg = <<~MSG
71
+ Once you have successfully published, run these commands to update the spec apps:
72
+
73
+ cd #{dummy_app_dir}; bundle update react_on_rails
74
+ cd #{gem_root}#{' '}
75
+ git commit -a -m 'Update Gemfile.lock for spec app'
76
+ git push
77
+ MSG
78
+ puts msg
79
+ end
80
+ # rubocop:enable Metrics/BlockLength
81
+
82
+ task :test do
83
+ unbundled_sh_in_dir(gem_root, "cd #{dummy_app_dir}; bundle update react_on_rails")
84
+ sh_in_dir(gem_root, "git commit -a -m 'Update Gemfile.lock for spec app'")
85
+ sh_in_dir(gem_root, "git push")
70
86
  end
@@ -16,13 +16,26 @@ module ReactOnRails
16
16
  File.join(gem_root, "spec/dummy")
17
17
  end
18
18
 
19
- # Executes a string or an array of strings in a shell in the given directory
19
+ # Executes a string or an array of strings in a shell in the given directory in an unbundled environment
20
20
  def sh_in_dir(dir, *shell_commands)
21
21
  shell_commands.flatten.each { |shell_command| sh %(cd #{dir} && #{shell_command.strip}) }
22
22
  end
23
23
 
24
+ # Executes a string or an array of strings in a shell in the given directory
25
+ def unbundled_sh_in_dir(dir, *shell_commands)
26
+ Dir.chdir(dir) do
27
+ # Without `with_unbundled_env`, running bundle in the child directories won't correctly
28
+ # update the Gemfile.lock
29
+ Bundler.with_unbundled_env do
30
+ shell_commands.flatten.each do |shell_command|
31
+ sh(shell_command.strip)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
24
37
  def bundle_install_in(dir)
25
- sh_in_dir(dir, "bundle install")
38
+ unbundled_sh_in_dir(dir, "bundle install")
26
39
  end
27
40
 
28
41
  def bundle_install_in_no_turbolinks(dir)