react_on_rails 11.1.8 → 12.0.0.pre.beta.1
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +320 -0
- data/.eslintignore +2 -1
- data/.eslintrc +30 -2
- data/.github/FUNDING.yml +1 -0
- data/.gitignore +3 -1
- data/.prettierignore +10 -0
- data/.prettierrc +23 -0
- data/.release-it.json +3 -0
- data/.rubocop.yml +37 -11
- data/.travis.yml +10 -20
- data/CHANGELOG.md +89 -3
- data/CONTRIBUTING.md +61 -80
- data/Gemfile +3 -5
- data/{COMM-LICENSE → REACT-ON-RAILS-PRO-LICENSE} +6 -9
- data/README.md +121 -71
- data/Rakefile +0 -7
- data/SUMMARY.md +10 -12
- data/book.json +5 -5
- data/docs/additional-reading/asset-pipeline.md +8 -16
- data/docs/additional-reading/images.md +1 -1
- data/docs/additional-reading/rails_view_rendering_from_inline_javascript.md +2 -1
- data/docs/additional-reading/react-helmet.md +30 -10
- data/docs/additional-reading/react-router.md +52 -75
- data/docs/additional-reading/server-rendering-tips.md +12 -7
- data/docs/additional-reading/upgrade-webpacker-v3-to-v4.md +10 -0
- data/docs/api/javascript-api.md +3 -3
- data/docs/api/redux-store-api.md +4 -2
- data/docs/api/view-helpers-api.md +17 -14
- data/docs/basics/configuration.md +64 -61
- data/docs/basics/deployment.md +1 -2
- data/docs/basics/i18n.md +44 -22
- data/docs/basics/installation-into-an-existing-rails-app.md +2 -2
- data/docs/basics/minitest-configuration.md +31 -0
- data/docs/basics/react-server-rendering.md +1 -1
- data/docs/basics/recommended-project-structure.md +1 -1
- data/docs/basics/{generator-functions-and-railscontext.md → render-functions-and-railscontext.md} +59 -21
- data/docs/basics/rspec-configuration.md +2 -2
- data/docs/basics/upgrading-react-on-rails.md +61 -3
- data/docs/basics/webpack-configuration.md +15 -1
- data/docs/contributor-info/errors-with-hooks.md +45 -0
- data/docs/contributor-info/pull-requests.md +44 -0
- data/docs/misc/doctrine.md +1 -1
- data/docs/{misc-pending → outdated}/code-splitting.md +13 -9
- data/docs/{additional-reading → outdated}/heroku-deployment.md +0 -6
- data/docs/{basics → outdated}/how-react-on-rails-works.md +3 -3
- data/docs/{misc-pending → outdated}/manual-installation-overview.md +5 -5
- data/docs/{additional-reading → outdated}/rails-assets-relative-paths.md +3 -3
- data/docs/{misc-pending → outdated}/rails-assets.md +4 -7
- data/docs/{misc → outdated}/rails3.md +0 -0
- data/docs/testimonials/hvmn.md +3 -3
- data/docs/testimonials/resortpass.md +13 -0
- data/docs/testimonials/testimonials.md +11 -1
- data/docs/tutorial.md +69 -28
- data/jest.config.js +4 -0
- data/lib/generators/react_on_rails/base_generator.rb +2 -2
- data/lib/generators/react_on_rails/dev_tests_generator.rb +2 -1
- data/lib/generators/react_on_rails/generator_helper.rb +4 -6
- data/lib/generators/react_on_rails/install_generator.rb +2 -0
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev +3 -1
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-hmr +18 -0
- data/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +20 -40
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/components/HelloWorld.jsx +4 -8
- data/lib/generators/react_on_rails/templates/redux/base/app/javascript/bundles/HelloWorld/store/helloWorldStore.js +1 -3
- data/lib/react_on_rails.rb +4 -1
- data/lib/react_on_rails/configuration.rb +15 -23
- data/lib/react_on_rails/error.rb +2 -0
- data/lib/react_on_rails/git_utils.rb +2 -0
- data/lib/react_on_rails/helper.rb +111 -162
- data/lib/react_on_rails/json_output.rb +1 -1
- data/lib/react_on_rails/json_parse_error.rb +2 -0
- data/lib/react_on_rails/locales/base.rb +142 -0
- data/lib/react_on_rails/locales/to_js.rb +37 -0
- data/lib/react_on_rails/locales/to_json.rb +27 -0
- data/lib/react_on_rails/prerender_error.rb +11 -15
- data/lib/react_on_rails/react_component/render_options.rb +4 -0
- data/lib/react_on_rails/server_rendering_js_code.rb +42 -0
- data/lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb +71 -51
- data/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +7 -8
- data/lib/react_on_rails/utils.rb +15 -20
- data/lib/react_on_rails/version.rb +1 -1
- data/lib/react_on_rails/version_checker.rb +5 -1
- data/lib/react_on_rails/webpacker_utils.rb +16 -2
- data/lib/tasks/assets.rake +5 -45
- data/lib/tasks/locale.rake +8 -2
- data/package-scripts.yml +49 -0
- data/package.json +41 -31
- data/rakelib/dummy_apps.rake +1 -9
- data/rakelib/example_type.rb +3 -1
- data/rakelib/examples.rake +3 -0
- data/rakelib/lint.rake +2 -7
- data/rakelib/node_package.rake +2 -2
- data/rakelib/release.rake +3 -8
- data/rakelib/run_rspec.rake +5 -18
- data/react_on_rails.gemspec +3 -5
- data/tsconfig.json +14 -0
- data/webpackConfigLoader.js +5 -4
- data/yarn.lock +7042 -2327
- metadata +39 -57
- data/Gemfile.rails32 +0 -74
- data/docs/additional-reading/babel.md +0 -5
- data/docs/additional-reading/hot-reloading-rails-development-asset-pipeline.md +0 -47
- data/docs/api/ruby-api-hot-reload-view-helpers.md +0 -44
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-server +0 -12
- data/lib/react_on_rails/assets_precompile.rb +0 -150
- data/lib/react_on_rails/locales_to_js.rb +0 -136
|
@@ -1,150 +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
|
-
manifest_glob = Dir.glob(@assets_path.join(".sprockets-manifest-*.json")) +
|
|
68
|
-
Dir.glob(@assets_path.join("manifest-*.json")) +
|
|
69
|
-
Dir.glob(@assets_path.join("manifest.yml"))
|
|
70
|
-
if manifest_glob.empty?
|
|
71
|
-
puts "Warning: React On Rails: expected to find .sprockets-manifest-*.json, manifest-*.json "\
|
|
72
|
-
"or manifest.yml at #{@assets_path}, but found none. Canceling symlinking tasks."
|
|
73
|
-
return -1
|
|
74
|
-
end
|
|
75
|
-
manifest_path = take_most_recent_manifest_path(manifest_glob)
|
|
76
|
-
manifest_file = File.new(manifest_path)
|
|
77
|
-
manifest_data = if File.extname(manifest_file) == ".json"
|
|
78
|
-
manifest_file_data = File.read(manifest_path)
|
|
79
|
-
JSON.parse(manifest_file_data)["assets"]
|
|
80
|
-
else
|
|
81
|
-
YAML.safe_load(manifest_file)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# We realize that we're copying other Rails assets that match the regexp, but this just
|
|
85
|
-
# means that we'd be exposing the original, undigested names.
|
|
86
|
-
manifest_data.each do |original_filename, rails_digested_filename|
|
|
87
|
-
# TODO: we should remove any original_filename that is NOT in the webpack deploy folder.
|
|
88
|
-
next unless original_filename =~ @symlink_non_digested_assets_regex
|
|
89
|
-
# We're symlinking from the digested filename back to the original filename which has
|
|
90
|
-
# already been symlinked by Webpack
|
|
91
|
-
symlink_file(rails_digested_filename, original_filename)
|
|
92
|
-
|
|
93
|
-
# We want the gz ones as well if they exist
|
|
94
|
-
if File.exist?(@assets_path.join("#{rails_digested_filename}.gz"))
|
|
95
|
-
symlink_file("#{rails_digested_filename}.gz", "#{original_filename}.gz")
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def delete_broken_symlinks
|
|
101
|
-
Dir.glob(@assets_path.join("*")).each do |filename|
|
|
102
|
-
next unless File.lstat(filename).symlink?
|
|
103
|
-
begin
|
|
104
|
-
target = File.readlink(filename)
|
|
105
|
-
rescue StandardError
|
|
106
|
-
puts "React on Rails: Warning: your platform doesn't support File::readlink method." \
|
|
107
|
-
"Skipping broken link check."
|
|
108
|
-
break
|
|
109
|
-
end
|
|
110
|
-
path = Pathname.new(File.dirname(filename))
|
|
111
|
-
target_path = path.join(target)
|
|
112
|
-
unless File.exist?(target_path)
|
|
113
|
-
puts "React on Rails: Deleting broken link: #{filename}"
|
|
114
|
-
File.delete(filename)
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def clobber
|
|
120
|
-
dir = Rails.root.join(@generated_assets_dir)
|
|
121
|
-
if dir.present? && File.directory?(dir)
|
|
122
|
-
puts "Deleting files in directory #{dir}"
|
|
123
|
-
FileUtils.rm_r(Dir.glob(Rails.root.join("#{@generated_assets_dir}/*")))
|
|
124
|
-
else
|
|
125
|
-
puts "Could not find generated_assets_dir #{dir} defined in react_on_rails initializer: "
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
private
|
|
130
|
-
|
|
131
|
-
def take_most_recent_manifest_path(manifest_glob)
|
|
132
|
-
manifest_glob.max_by { |name| File.mtime(name) }
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def symlink_and_points_to_existing_file?(symlink_path)
|
|
136
|
-
# File.exist?(symlink_path) will check the file the sym is pointing to is existing
|
|
137
|
-
# File.lstat(symlink_path).symlink? confirms that this is a symlink
|
|
138
|
-
File.exist?(symlink_path) && File.lstat(symlink_path).symlink?
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def file_or_symlink_exists_at_path?(path)
|
|
142
|
-
# We use lstat and not stat, we we don't want to visit the file that the symlink maybe
|
|
143
|
-
# pointing to. We can't use File.exist?, as that would check the file pointed at by the symlink.
|
|
144
|
-
File.lstat(path)
|
|
145
|
-
true
|
|
146
|
-
rescue StandardError
|
|
147
|
-
false
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
@@ -1,136 +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
|
-
@translations, @defaults = generate_translations
|
|
11
|
-
convert
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def obsolete?
|
|
17
|
-
return true if exist_js_files.empty?
|
|
18
|
-
js_files_are_outdated
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def exist_js_files
|
|
22
|
-
@exist_js_files ||= js_files.select(&File.method(:exist?))
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def js_files_are_outdated
|
|
26
|
-
latest_yml = locale_files.map(&File.method(:mtime)).max
|
|
27
|
-
earliest_js = exist_js_files.map(&File.method(:mtime)).min
|
|
28
|
-
latest_yml > earliest_js
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def js_file_names
|
|
32
|
-
%w[translations default]
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def js_files
|
|
36
|
-
@js_files ||= js_file_names.map { |n| js_file(n) }
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def js_file(name)
|
|
40
|
-
"#{i18n_dir}/#{name}.js"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def locale_files
|
|
44
|
-
@locale_files ||= begin
|
|
45
|
-
if i18n_yml_dir.present?
|
|
46
|
-
Dir["#{i18n_yml_dir}/**/*.yml"]
|
|
47
|
-
else
|
|
48
|
-
ReactOnRails::Utils.truthy_presence(
|
|
49
|
-
Rails.application && Rails.application.config.i18n.load_path
|
|
50
|
-
).presence
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def i18n_dir
|
|
56
|
-
@i18n_dir ||= ReactOnRails.configuration.i18n_dir
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def i18n_yml_dir
|
|
60
|
-
@i18n_yml_dir ||= ReactOnRails.configuration.i18n_yml_dir
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def default_locale
|
|
64
|
-
@default_locale ||= I18n.default_locale.to_s || "en"
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def convert
|
|
68
|
-
js_file_names.each do |name|
|
|
69
|
-
template = send("template_#{name}")
|
|
70
|
-
path = js_file(name)
|
|
71
|
-
generate_js_file(template, path)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def generate_js_file(template, path)
|
|
76
|
-
result = ERB.new(template).result()
|
|
77
|
-
File.open(path, "w") do |f|
|
|
78
|
-
f.write(result)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def generate_translations
|
|
83
|
-
translations = {}
|
|
84
|
-
defaults = {}
|
|
85
|
-
locale_files.each do |f|
|
|
86
|
-
translation = YAML.safe_load(File.open(f))
|
|
87
|
-
key = translation.keys[0]
|
|
88
|
-
val = flatten(translation[key])
|
|
89
|
-
translations = translations.deep_merge(key => val)
|
|
90
|
-
defaults = defaults.deep_merge(flatten_defaults(val)) if key == default_locale
|
|
91
|
-
end
|
|
92
|
-
[translations.to_json, defaults.to_json]
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def format(input)
|
|
96
|
-
input.to_s.tr(".", "_").camelize(:lower).to_sym
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def flatten_defaults(val)
|
|
100
|
-
flatten(val).each_with_object({}) do |(k, v), h|
|
|
101
|
-
key = format(k)
|
|
102
|
-
h[key] = { id: k, defaultMessage: v }
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def flatten(translations)
|
|
107
|
-
translations.each_with_object({}) do |(k, v), h|
|
|
108
|
-
if v.is_a? Hash
|
|
109
|
-
flatten(v).map { |hk, hv| h["#{k}.#{hk}".to_sym] = hv }
|
|
110
|
-
elsif v.is_a?(String)
|
|
111
|
-
h[k] = v.gsub("%{", "{")
|
|
112
|
-
elsif !v.is_a?(Array)
|
|
113
|
-
h[k] = v
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def template_translations
|
|
119
|
-
<<-JS.strip_heredoc
|
|
120
|
-
export const translations = #{@translations};
|
|
121
|
-
JS
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def template_default
|
|
125
|
-
<<-JS.strip_heredoc
|
|
126
|
-
import { defineMessages } from 'react-intl';
|
|
127
|
-
|
|
128
|
-
const defaultLocale = \'#{default_locale}\';
|
|
129
|
-
|
|
130
|
-
const defaultMessages = defineMessages(#{@defaults});
|
|
131
|
-
|
|
132
|
-
export { defaultMessages, defaultLocale };
|
|
133
|
-
JS
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|