react_on_rails 11.3.0 → 12.0.0.pre.beta.4

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +320 -0
  3. data/.eslintignore +2 -1
  4. data/.eslintrc +23 -1
  5. data/.github/FUNDING.yml +1 -0
  6. data/.gitignore +3 -1
  7. data/.prettierignore +10 -1
  8. data/.prettierrc +3 -0
  9. data/.rubocop.yml +37 -11
  10. data/.travis.yml +9 -22
  11. data/CHANGELOG.md +65 -6
  12. data/CONTRIBUTING.md +60 -71
  13. data/Gemfile +3 -4
  14. data/{COMM-LICENSE → REACT-ON-RAILS-PRO-LICENSE} +6 -9
  15. data/README.md +129 -92
  16. data/Rakefile +0 -7
  17. data/SUMMARY.md +7 -11
  18. data/book.json +5 -5
  19. data/docs/additional-reading/asset-pipeline.md +8 -16
  20. data/docs/additional-reading/react-helmet.md +30 -10
  21. data/docs/additional-reading/react-router.md +52 -75
  22. data/docs/additional-reading/server-rendering-tips.md +12 -7
  23. data/docs/api/javascript-api.md +3 -3
  24. data/docs/api/redux-store-api.md +4 -2
  25. data/docs/api/view-helpers-api.md +6 -7
  26. data/docs/basics/configuration.md +83 -69
  27. data/docs/basics/deployment.md +2 -4
  28. data/docs/basics/heroku-deployment.md +24 -0
  29. data/docs/basics/hmr-and-hot-reloading-with-the-webpack-dev-server.md +49 -0
  30. data/docs/basics/i18n.md +45 -23
  31. data/docs/basics/installation-into-an-existing-rails-app.md +4 -9
  32. data/docs/basics/react-server-rendering.md +1 -1
  33. data/docs/basics/recommended-project-structure.md +5 -22
  34. data/docs/basics/{generator-functions-and-railscontext.md → render-functions-and-railscontext.md} +59 -21
  35. data/docs/basics/rspec-configuration.md +27 -16
  36. data/docs/basics/upgrading-react-on-rails.md +58 -2
  37. data/docs/basics/webpack-configuration.md +18 -8
  38. data/docs/contributor-info/errors-with-hooks.md +45 -0
  39. data/docs/contributor-info/pull-requests.md +44 -0
  40. data/docs/misc/doctrine.md +1 -1
  41. data/docs/{misc-pending → outdated}/code-splitting.md +12 -8
  42. data/docs/{basics → outdated}/how-react-on-rails-works.md +8 -4
  43. data/docs/{misc-pending → outdated}/manual-installation-overview.md +5 -5
  44. data/docs/{additional-reading → outdated}/rails-assets-relative-paths.md +3 -3
  45. data/docs/{misc-pending → outdated}/rails-assets.md +2 -12
  46. data/docs/{misc → outdated}/rails3.md +0 -0
  47. data/docs/tutorial.md +94 -68
  48. data/jest.config.js +4 -0
  49. data/lib/generators/react_on_rails/base_generator.rb +2 -2
  50. data/lib/generators/react_on_rails/dev_tests_generator.rb +1 -1
  51. data/lib/generators/react_on_rails/generator_helper.rb +4 -6
  52. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +3 -1
  53. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-hmr +26 -0
  54. data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +20 -40
  55. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +4 -1
  56. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +4 -8
  57. data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/store/helloWorldStore.js +1 -3
  58. data/lib/react_on_rails.rb +3 -1
  59. data/lib/react_on_rails/configuration.rb +58 -28
  60. data/lib/react_on_rails/error.rb +2 -0
  61. data/lib/react_on_rails/helper.rb +41 -91
  62. data/lib/react_on_rails/json_parse_error.rb +2 -0
  63. data/lib/react_on_rails/locales/base.rb +150 -0
  64. data/lib/react_on_rails/locales/to_js.rb +37 -0
  65. data/lib/react_on_rails/locales/to_json.rb +27 -0
  66. data/lib/react_on_rails/prerender_error.rb +11 -15
  67. data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +41 -46
  68. data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +7 -8
  69. data/lib/react_on_rails/test_helper/webpack_assets_compiler.rb +17 -0
  70. data/lib/react_on_rails/utils.rb +14 -19
  71. data/lib/react_on_rails/version.rb +1 -1
  72. data/lib/react_on_rails/version_checker.rb +1 -0
  73. data/lib/react_on_rails/webpacker_utils.rb +19 -2
  74. data/lib/tasks/assets.rake +33 -46
  75. data/lib/tasks/locale.rake +4 -2
  76. data/package-scripts.yml +11 -8
  77. data/package.json +29 -28
  78. data/rakelib/dummy_apps.rake +1 -9
  79. data/rakelib/example_type.rb +3 -1
  80. data/rakelib/examples.rake +3 -0
  81. data/rakelib/lint.rake +2 -7
  82. data/rakelib/node_package.rake +2 -2
  83. data/rakelib/release.rake +0 -6
  84. data/rakelib/run_rspec.rake +5 -18
  85. data/react_on_rails.gemspec +4 -5
  86. data/tsconfig.json +14 -0
  87. data/webpackConfigLoader.js +3 -2
  88. data/yarn.lock +4333 -2209
  89. metadata +46 -57
  90. data/Gemfile.rails32 +0 -73
  91. data/docs/additional-reading/babel.md +0 -5
  92. data/docs/additional-reading/heroku-deployment.md +0 -92
  93. data/docs/additional-reading/hot-reloading-rails-development-asset-pipeline.md +0 -47
  94. data/docs/api/ruby-api-hot-reload-view-helpers.md +0 -44
  95. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-server +0 -12
  96. data/lib/react_on_rails/assets_precompile.rb +0 -153
  97. data/lib/react_on_rails/locales_to_js.rb +0 -138
@@ -1,44 +0,0 @@
1
- ## NOTE: These helpers are NOT needed if using webpacker
2
-
3
- ## Hot Reloading View Helpers
4
- The `env_javascript_include_tag` and `env_stylesheet_link_tag` support the usage of a webpack dev server for providing the JS and CSS assets during development mode. See the [shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/) for a working example.
5
-
6
- The key options are `static` and `hot` which specify what you want for static vs. hot. Both of these params are optional, and support either a single value, or an array.
7
-
8
- static vs. hot is picked based on whether `ENV["REACT_ON_RAILS_ENV"] == "HOT"`
9
-
10
- ```erb
11
- <%= env_stylesheet_link_tag(static: 'application_static',
12
- hot: 'application_non_webpack',
13
- media: 'all',
14
- 'data-turbolinks-track' => true) %>
15
-
16
- <!-- These do not use turbolinks, so no data-turbolinks-track -->
17
- <!-- This is to load the hot assets. -->
18
-
19
- <!-- Note, you can have multiple files here. It's an array. -->
20
- <%= env_javascript_include_tag(hot: ['http://localhost:3500/hello-world-bundle.js]') %>
21
-
22
- <!-- These do use turbolinks -->
23
- <%= env_javascript_include_tag(static: 'application_static',
24
- hot: 'application_non_webpack',
25
- 'data-turbolinks-track' => true) %>
26
- ```
27
-
28
- See application.html.erb for usage example and [application.html.erb](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/app%2Fviews%2Flayouts%2Fapplication.html.erb)
29
-
30
- Helper to set CSS and JS assets depending on if we want static or "hot", which means from the Webpack dev server.
31
-
32
- In this example, `application_non_webpack` is simply a CSS asset pipeline file which includes styles not placed in the webpack build. The same can be said for `application_non_webpack` for JS files. Note, the suffix is not used in the helper calls.
33
-
34
- We don't need styles from the webpack build, as those will come via the JavaScript include tags.
35
-
36
- The key options are `static` and `hot` which specify what you want for static vs. hot. Both of
37
- these params are optional, and support either a single value, or an array.
38
-
39
- ```erb
40
- <%= env_stylesheet_link_tag(static: 'application_static',
41
- hot: 'application_non_webpack',
42
- media: 'all',
43
- 'data-turbolinks-track' => true) %>
44
- ```
@@ -1,12 +0,0 @@
1
- # You can run these commands in separate shells instead of using foreman
2
- web: rails s -p 3000
3
-
4
- # Next line runs the webpack-dev-server
5
- # You can edit config/webpacker.yml to set HMR to true to see hot reloading.
6
- # Note, hot and live reloading don't work with the default generator setup on top of
7
- # the rails/webpacker Webpack config with server rendering.
8
- # If you have server rendering enabled, modify the call to bin/webpack-dev-server line
9
- # so you add `--inline=false` and then CSS is not inlined.
10
- # Otherwise, you will have an error. If you want HMR and Server Rendering, see
11
- # the example in the https://github.com/shakacode/react-webpack-rails-tutorial
12
- client: sh -c 'rm -rf public/packs/* || true && bundle exec rake react_on_rails:locale && bin/webpack-dev-server'
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ReactOnRails
4
- class AssetsPrecompile
5
- class SymlinkTargetDoesNotExistException < StandardError
6
- end
7
-
8
- # Used by the rake task
9
- def default_asset_path
10
- dir = File.join(Rails.configuration.paths["public"].first,
11
- Rails.configuration.assets.prefix)
12
- Pathname.new(dir)
13
- end
14
-
15
- # assets_path should be a Pathname object
16
- def initialize(assets_path: nil,
17
- symlink_non_digested_assets_regex: nil,
18
- generated_assets_dir: nil)
19
- @assets_path = ReactOnRails::Utils.truthy_presence(assets_path) || default_asset_path
20
- @symlink_non_digested_assets_regex =
21
- ReactOnRails::Utils.truthy_presence(symlink_non_digested_assets_regex) ||
22
- ReactOnRails.configuration.symlink_non_digested_assets_regex
23
- @generated_assets_dir = ReactOnRails::Utils.truthy_presence(generated_assets_dir) ||
24
- ReactOnRails.configuration.generated_assets_dir
25
- end
26
-
27
- # target and symlink are relative to the assets directory
28
- def symlink_file(target, symlink)
29
- target_path = @assets_path.join(target)
30
- symlink_path = @assets_path.join(symlink)
31
-
32
- target_exists = File.exist?(target_path)
33
- raise SymlinkTargetDoesNotExistException, "Target Path was: #{target_path}" unless target_exists
34
-
35
- if symlink_and_points_to_existing_file?(symlink_path)
36
- puts "React On Rails: Digested version of #{symlink} already exists indicating #{target} did not change."
37
- return
38
- end
39
-
40
- if file_or_symlink_exists_at_path?(symlink_path)
41
- puts "React On Rails: Removing existing invalid symlink or file #{symlink_path}"
42
- FileUtils.remove_file(symlink_path, true)
43
- end
44
-
45
- # Might be like:
46
- # "images/5cf5db49df178f9357603f945752a1ef.png":
47
- # "images/5cf5db49df178f9357603f945752a1ef-033650e1d6193b70d59bb60e773f47b6d9aefdd56abc7cc.png"
48
- # need to cd to directory and then symlink
49
- target_sub_path, _divider, target_filename = target.rpartition("/")
50
- _symlink_sub_path, _divider, symlink_filename = symlink.rpartition("/")
51
- dest_path = File.join(@assets_path, target_sub_path)
52
-
53
- puts "React On Rails: Symlinking \"#{target}\" to \"#{symlink}\""
54
- FileUtils.chdir(dest_path) do
55
- File.symlink(target_filename, symlink_filename)
56
- end
57
- end
58
-
59
- def symlink_non_digested_assets
60
- # digest ==> means that the file has a unique sha so the browser will load a new copy.
61
- # Webpack's CSS extract-text-plugin copies digested asset files over to directory where we put
62
- # we deploy the webpack compiled JS file. Since Rails will deploy the image files in this
63
- # directory with a digest, then the files are essentially "double-digested" and the CSS
64
- # references from webpack's CSS would be invalid. The fix is to symlink the double-digested
65
- # file back to the original digested name, and make a similar symlink for the gz version.
66
- return unless @symlink_non_digested_assets_regex
67
-
68
- manifest_glob = Dir.glob(@assets_path.join(".sprockets-manifest-*.json")) +
69
- Dir.glob(@assets_path.join("manifest-*.json")) +
70
- Dir.glob(@assets_path.join("manifest.yml"))
71
- if manifest_glob.empty?
72
- puts "Warning: React On Rails: expected to find .sprockets-manifest-*.json, manifest-*.json "\
73
- "or manifest.yml at #{@assets_path}, but found none. Canceling symlinking tasks."
74
- return -1
75
- end
76
- manifest_path = take_most_recent_manifest_path(manifest_glob)
77
- manifest_file = File.new(manifest_path)
78
- manifest_data = if File.extname(manifest_file) == ".json"
79
- manifest_file_data = File.read(manifest_path)
80
- JSON.parse(manifest_file_data)["assets"]
81
- else
82
- YAML.safe_load(manifest_file)
83
- end
84
-
85
- # We realize that we're copying other Rails assets that match the regexp, but this just
86
- # means that we'd be exposing the original, undigested names.
87
- manifest_data.each do |original_filename, rails_digested_filename|
88
- # TODO: we should remove any original_filename that is NOT in the webpack deploy folder.
89
- next unless original_filename =~ @symlink_non_digested_assets_regex
90
-
91
- # We're symlinking from the digested filename back to the original filename which has
92
- # already been symlinked by Webpack
93
- symlink_file(rails_digested_filename, original_filename)
94
-
95
- # We want the gz ones as well if they exist
96
- if File.exist?(@assets_path.join("#{rails_digested_filename}.gz"))
97
- symlink_file("#{rails_digested_filename}.gz", "#{original_filename}.gz")
98
- end
99
- end
100
- end
101
-
102
- def delete_broken_symlinks
103
- Dir.glob(@assets_path.join("*")).each do |filename|
104
- next unless File.lstat(filename).symlink?
105
-
106
- begin
107
- target = File.readlink(filename)
108
- rescue StandardError
109
- puts "React on Rails: Warning: your platform doesn't support File::readlink method." \
110
- "Skipping broken link check."
111
- break
112
- end
113
- path = Pathname.new(File.dirname(filename))
114
- target_path = path.join(target)
115
- unless File.exist?(target_path)
116
- puts "React on Rails: Deleting broken link: #{filename}"
117
- File.delete(filename)
118
- end
119
- end
120
- end
121
-
122
- def clobber
123
- dir = Rails.root.join(@generated_assets_dir)
124
- if dir.present? && File.directory?(dir)
125
- puts "Deleting files in directory #{dir}"
126
- FileUtils.rm_r(Dir.glob(Rails.root.join("#{@generated_assets_dir}/*")))
127
- else
128
- puts "Could not find generated_assets_dir #{dir} defined in react_on_rails initializer: "
129
- end
130
- end
131
-
132
- private
133
-
134
- def take_most_recent_manifest_path(manifest_glob)
135
- manifest_glob.max_by { |name| File.mtime(name) }
136
- end
137
-
138
- def symlink_and_points_to_existing_file?(symlink_path)
139
- # File.exist?(symlink_path) will check the file the sym is pointing to is existing
140
- # File.lstat(symlink_path).symlink? confirms that this is a symlink
141
- File.exist?(symlink_path) && File.lstat(symlink_path).symlink?
142
- end
143
-
144
- def file_or_symlink_exists_at_path?(path)
145
- # We use lstat and not stat, we we don't want to visit the file that the symlink maybe
146
- # pointing to. We can't use File.exist?, as that would check the file pointed at by the symlink.
147
- File.lstat(path)
148
- true
149
- rescue StandardError
150
- false
151
- end
152
- end
153
- end
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "erb"
4
-
5
- module ReactOnRails
6
- class LocalesToJs
7
- def initialize
8
- return if i18n_dir.nil?
9
- return unless obsolete?
10
-
11
- @translations, @defaults = generate_translations
12
- convert
13
- end
14
-
15
- private
16
-
17
- def obsolete?
18
- return true if exist_js_files.empty?
19
-
20
- js_files_are_outdated
21
- end
22
-
23
- def exist_js_files
24
- @exist_js_files ||= js_files.select(&File.method(:exist?))
25
- end
26
-
27
- def js_files_are_outdated
28
- latest_yml = locale_files.map(&File.method(:mtime)).max
29
- earliest_js = exist_js_files.map(&File.method(:mtime)).min
30
- latest_yml > earliest_js
31
- end
32
-
33
- def js_file_names
34
- %w[translations default]
35
- end
36
-
37
- def js_files
38
- @js_files ||= js_file_names.map { |n| js_file(n) }
39
- end
40
-
41
- def js_file(name)
42
- "#{i18n_dir}/#{name}.js"
43
- end
44
-
45
- def locale_files
46
- @locale_files ||= begin
47
- if i18n_yml_dir.present?
48
- Dir["#{i18n_yml_dir}/**/*.yml"]
49
- else
50
- ReactOnRails::Utils.truthy_presence(
51
- Rails.application && Rails.application.config.i18n.load_path
52
- ).presence
53
- end
54
- end
55
- end
56
-
57
- def i18n_dir
58
- @i18n_dir ||= ReactOnRails.configuration.i18n_dir
59
- end
60
-
61
- def i18n_yml_dir
62
- @i18n_yml_dir ||= ReactOnRails.configuration.i18n_yml_dir
63
- end
64
-
65
- def default_locale
66
- @default_locale ||= I18n.default_locale.to_s || "en"
67
- end
68
-
69
- def convert
70
- js_file_names.each do |name|
71
- template = send("template_#{name}")
72
- path = js_file(name)
73
- generate_js_file(template, path)
74
- end
75
- end
76
-
77
- def generate_js_file(template, path)
78
- result = ERB.new(template).result()
79
- File.open(path, "w") do |f|
80
- f.write(result)
81
- end
82
- end
83
-
84
- def generate_translations
85
- translations = {}
86
- defaults = {}
87
- locale_files.each do |f|
88
- translation = YAML.safe_load(File.open(f))
89
- key = translation.keys[0]
90
- val = flatten(translation[key])
91
- translations = translations.deep_merge(key => val)
92
- defaults = defaults.deep_merge(flatten_defaults(val)) if key == default_locale
93
- end
94
- [translations.to_json, defaults.to_json]
95
- end
96
-
97
- def format(input)
98
- input.to_s.tr(".", "_").camelize(:lower).to_sym
99
- end
100
-
101
- def flatten_defaults(val)
102
- flatten(val).each_with_object({}) do |(k, v), h|
103
- key = format(k)
104
- h[key] = { id: k, defaultMessage: v }
105
- end
106
- end
107
-
108
- def flatten(translations)
109
- translations.each_with_object({}) do |(k, v), h|
110
- if v.is_a? Hash
111
- flatten(v).map { |hk, hv| h["#{k}.#{hk}".to_sym] = hv }
112
- elsif v.is_a?(String)
113
- h[k] = v.gsub("%{", "{")
114
- elsif !v.is_a?(Array)
115
- h[k] = v
116
- end
117
- end
118
- end
119
-
120
- def template_translations
121
- <<-JS.strip_heredoc
122
- export const translations = #{@translations};
123
- JS
124
- end
125
-
126
- def template_default
127
- <<-JS.strip_heredoc
128
- import { defineMessages } from 'react-intl';
129
-
130
- const defaultLocale = \'#{default_locale}\';
131
-
132
- const defaultMessages = defineMessages(#{@defaults});
133
-
134
- export { defaultMessages, defaultLocale };
135
- JS
136
- end
137
- end
138
- end