react-rails 2.7.0 → 3.0.0.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -18
- data/README.md +97 -49
- data/lib/assets/javascripts/react_ujs.js +1 -1
- data/lib/assets/react-source/development/react-server.js +333 -10
- data/lib/assets/react-source/development/react.js +19 -28
- data/lib/assets/react-source/production/react-server.js +1 -1
- data/lib/assets/react-source/production/react.js +1 -1
- data/lib/generators/react/component_generator.rb +126 -121
- data/lib/generators/react/install_generator.rb +50 -72
- data/lib/generators/templates/component.es6.jsx +8 -8
- data/lib/generators/templates/component.js.jsx +14 -14
- data/lib/generators/templates/react_server_rendering.rb +3 -1
- data/lib/react/jsx/babel_transformer.rb +12 -6
- data/lib/react/jsx/jsx_transformer.rb +7 -5
- data/lib/react/jsx/processor.rb +3 -1
- data/lib/react/jsx/sprockets_strategy.rb +17 -11
- data/lib/react/jsx/template.rb +7 -6
- data/lib/react/jsx.rb +9 -7
- data/lib/react/rails/asset_variant.rb +7 -6
- data/lib/react/rails/component_mount.rb +37 -29
- data/lib/react/rails/controller_lifecycle.rb +2 -0
- data/lib/react/rails/controller_renderer.rb +3 -1
- data/lib/react/rails/railtie.rb +19 -22
- data/lib/react/rails/test_helper.rb +3 -1
- data/lib/react/rails/version.rb +3 -1
- data/lib/react/rails/view_helper.rb +3 -1
- data/lib/react/rails.rb +9 -7
- data/lib/react/server_rendering/bundle_renderer.rb +34 -39
- data/lib/react/server_rendering/environment_container.rb +2 -0
- data/lib/react/server_rendering/exec_js_renderer.rb +15 -6
- data/lib/react/server_rendering/manifest_container.rb +6 -2
- data/lib/react/server_rendering/separate_server_bundle_container.rb +19 -0
- data/lib/react/server_rendering/yaml_manifest_container.rb +4 -2
- data/lib/react/server_rendering.rb +11 -9
- data/lib/react-rails.rb +8 -6
- data/lib/react.rb +2 -0
- metadata +11 -53
- data/lib/react/server_rendering/webpacker_manifest_container.rb +0 -96
@@ -1,26 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module JSX
|
3
5
|
# A {React::JSX}-compliant transformer which uses the deprecated `JSXTransformer.js` to transform JSX.
|
4
6
|
class JSXTransformer
|
5
|
-
DEFAULT_ASSET_PATH =
|
7
|
+
DEFAULT_ASSET_PATH = "JSXTransformer.js"
|
6
8
|
|
7
9
|
def initialize(options)
|
8
10
|
@transform_options = {
|
9
11
|
stripTypes: options.fetch(:strip_types, false),
|
10
|
-
harmony:
|
12
|
+
harmony: options.fetch(:harmony, false)
|
11
13
|
}
|
12
14
|
|
13
15
|
@asset_path = options.fetch(:asset_path, DEFAULT_ASSET_PATH)
|
14
16
|
|
15
17
|
# If execjs uses therubyracer, there is no 'global'. Make sure
|
16
18
|
# we have it so JSX script can work properly.
|
17
|
-
js_code =
|
19
|
+
js_code = "var global = global || this;#{jsx_transform_code}"
|
18
20
|
@context = ExecJS.compile(js_code)
|
19
21
|
end
|
20
22
|
|
21
23
|
def transform(code)
|
22
|
-
result = @context.call(
|
23
|
-
result[
|
24
|
+
result = @context.call("JSXTransformer.transform", code, @transform_options)
|
25
|
+
result["code"]
|
24
26
|
end
|
25
27
|
|
26
28
|
# search for transformer file using sprockets - allows user to override
|
data/lib/react/jsx/processor.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module JSX
|
3
5
|
# Depending on the Sprockets version,
|
@@ -17,15 +19,15 @@ module React
|
|
17
19
|
# @param [Symbol, Nil] A strategy name, or `nil` to detect a strategy
|
18
20
|
def attach_with_strategy(sprockets_env, strategy_or_nil)
|
19
21
|
strategy = strategy_or_nil || detect_strategy
|
20
|
-
|
22
|
+
public_send(strategy, sprockets_env)
|
21
23
|
end
|
22
24
|
|
23
25
|
# @return [Symbol] based on the environment, return a method name to call with the sprockets environment
|
24
26
|
def detect_strategy
|
25
27
|
sprockets_version = Gem::Version.new(Sprockets::VERSION)
|
26
|
-
if sprockets_version >= Gem::Version.new(
|
28
|
+
if sprockets_version >= Gem::Version.new("4.a")
|
27
29
|
:register_processors
|
28
|
-
elsif sprockets_version >= Gem::Version.new(
|
30
|
+
elsif sprockets_version >= Gem::Version.new("3.0.0")
|
29
31
|
:register_engine_with_mime_type
|
30
32
|
else
|
31
33
|
:register_engine
|
@@ -33,20 +35,24 @@ module React
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def register_engine(sprockets_env)
|
36
|
-
sprockets_env.register_engine(
|
38
|
+
sprockets_env.register_engine(".jsx", React::JSX::Template)
|
37
39
|
end
|
38
40
|
|
39
41
|
def register_engine_with_mime_type(sprockets_env)
|
40
|
-
sprockets_env.register_engine(
|
42
|
+
sprockets_env.register_engine(".jsx", React::JSX::Processor, mime_type: "application/javascript",
|
43
|
+
silence_deprecation: true)
|
41
44
|
end
|
42
45
|
|
43
46
|
def register_processors(sprockets_env)
|
44
|
-
sprockets_env.register_mime_type(
|
45
|
-
sprockets_env.register_mime_type(
|
46
|
-
sprockets_env.register_transformer(
|
47
|
-
sprockets_env.register_transformer(
|
48
|
-
|
49
|
-
sprockets_env.register_preprocessor(
|
47
|
+
sprockets_env.register_mime_type("application/jsx", extensions: [".jsx", ".js.jsx", ".es.jsx", ".es6.jsx"])
|
48
|
+
sprockets_env.register_mime_type("application/jsx+coffee", extensions: [".jsx.coffee", ".js.jsx.coffee"])
|
49
|
+
sprockets_env.register_transformer("application/jsx", "application/javascript", React::JSX::Processor)
|
50
|
+
sprockets_env.register_transformer("application/jsx+coffee", "application/jsx",
|
51
|
+
Sprockets::CoffeeScriptProcessor)
|
52
|
+
sprockets_env.register_preprocessor("application/jsx",
|
53
|
+
Sprockets::DirectiveProcessor.new(comments: ["//", ["/*", "*/"]]))
|
54
|
+
sprockets_env.register_preprocessor("application/jsx+coffee",
|
55
|
+
Sprockets::DirectiveProcessor.new(comments: ["#", ["###", "###"]]))
|
50
56
|
end
|
51
57
|
end
|
52
58
|
end
|
data/lib/react/jsx/template.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tilt"
|
2
4
|
|
3
5
|
module React
|
4
6
|
module JSX
|
5
7
|
# Sprockets 2-compliant processor
|
6
8
|
class Template < Tilt::Template
|
7
|
-
self.default_mime_type =
|
9
|
+
self.default_mime_type = "application/javascript"
|
8
10
|
|
9
|
-
def prepare
|
10
|
-
end
|
11
|
+
def prepare; end
|
11
12
|
|
12
|
-
def evaluate(
|
13
|
-
@
|
13
|
+
def evaluate(_scope, _locals)
|
14
|
+
@evaluate ||= JSX.transform(data)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
data/lib/react/jsx.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "execjs"
|
4
|
+
require "react/jsx/processor"
|
5
|
+
require "react/jsx/template"
|
6
|
+
require "react/jsx/jsx_transformer"
|
7
|
+
require "react/jsx/babel_transformer"
|
8
|
+
require "react/jsx/sprockets_strategy"
|
9
|
+
require "rails"
|
8
10
|
|
9
11
|
module React
|
10
12
|
module JSX
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module Rails
|
3
5
|
# This class accepts some options for which build you want, then exposes where you can find
|
4
6
|
# them. In general, these paths should be added to the sprockets environment.
|
5
7
|
class AssetVariant
|
6
|
-
GEM_ROOT = Pathname.new(
|
8
|
+
GEM_ROOT = Pathname.new("../../../../").expand_path(__FILE__)
|
7
9
|
# @return [String] "production" or "development"
|
8
10
|
attr_reader :react_build
|
9
11
|
|
@@ -15,12 +17,11 @@ module React
|
|
15
17
|
|
16
18
|
# @param [Hash] Options for the asset variant
|
17
19
|
# @option variant [Symbol] if `:production`, use the minified React.js build
|
18
|
-
def initialize(options={})
|
19
|
-
|
20
|
-
@react_build = options[:variant] == :production ? 'production' : 'development'
|
20
|
+
def initialize(options = {})
|
21
|
+
@react_build = options[:variant] == :production ? "production" : "development"
|
21
22
|
|
22
|
-
@react_directory = GEM_ROOT.join(
|
23
|
-
@jsx_directory = GEM_ROOT.join(
|
23
|
+
@react_directory = GEM_ROOT.join("lib/assets/react-source/").join(@react_build).to_s
|
24
|
+
@jsx_directory = GEM_ROOT.join("lib/assets/javascripts/").to_s
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module Rails
|
3
5
|
# This is the default view helper implementation.
|
@@ -9,6 +11,7 @@ module React
|
|
9
11
|
include ActionView::Helpers::TagHelper
|
10
12
|
include ActionView::Helpers::TextHelper
|
11
13
|
attr_accessor :output_buffer
|
14
|
+
|
12
15
|
mattr_accessor :camelize_props_switch
|
13
16
|
|
14
17
|
def initialize
|
@@ -21,57 +24,62 @@ module React
|
|
21
24
|
@controller = controller
|
22
25
|
end
|
23
26
|
|
24
|
-
def teardown(controller)
|
25
|
-
end
|
27
|
+
def teardown(controller); end
|
26
28
|
|
27
29
|
# Render a UJS-type HTML tag annotated with data attributes, which
|
28
30
|
# are used by react_ujs to actually instantiate the React component
|
29
31
|
# on the client.
|
30
32
|
def react_component(name, props = {}, options = {}, &block)
|
31
|
-
options = { :
|
32
|
-
if options.fetch(:camelize_props, camelize_props_switch)
|
33
|
-
props = React.camelize_props(props)
|
34
|
-
end
|
33
|
+
options = { tag: options } if options.is_a?(Symbol)
|
34
|
+
props = React.camelize_props(props) if options.fetch(:camelize_props, camelize_props_switch)
|
35
35
|
|
36
36
|
prerender_options = options[:prerender]
|
37
|
-
if prerender_options
|
38
|
-
|
39
|
-
|
37
|
+
block = proc { concat(prerender_component(name, props, prerender_options)) } if prerender_options
|
38
|
+
|
39
|
+
html_options = generate_html_options(name, options, props, prerender_options)
|
40
|
+
|
41
|
+
rendered_tag(html_options, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# If this controller has checked out a renderer, use that one.
|
47
|
+
# Otherwise, use {React::ServerRendering} directly (which will check one out for this rendering).
|
48
|
+
def prerender_component(component_name, props, prerender_options)
|
49
|
+
renderer = @controller.try(:react_rails_prerenderer) || React::ServerRendering
|
50
|
+
renderer.render(component_name, props, prerender_options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def generate_html_options(name, options, props, prerender_options)
|
54
|
+
html_options = options.reverse_merge(data: {})
|
40
55
|
|
41
|
-
html_options = options.reverse_merge(:data => {})
|
42
56
|
unless prerender_options == :static
|
43
57
|
html_options[:data].tap do |data|
|
44
58
|
data[:react_class] = name
|
45
59
|
data[:react_props] = (props.is_a?(String) ? props : props.to_json)
|
46
|
-
data[:hydrate] =
|
60
|
+
data[:hydrate] = "t" if prerender_options
|
47
61
|
|
48
62
|
num_components = @cache_ids.count { |c| c.start_with? name }
|
49
63
|
data[:react_cache_id] = "#{name}-#{num_components}"
|
50
64
|
end
|
51
65
|
end
|
66
|
+
|
67
|
+
html_options
|
68
|
+
end
|
69
|
+
|
70
|
+
def rendered_tag(html_options, &block)
|
52
71
|
html_tag = html_options[:tag] || :div
|
53
72
|
|
54
73
|
# remove internally used properties so they aren't rendered to DOM
|
55
|
-
html_options.except
|
56
|
-
|
57
|
-
rendered_tag = content_tag(html_tag, '', html_options, &block)
|
58
|
-
if React::ServerRendering.renderer_options[:replay_console]
|
59
|
-
# Grab the server-rendered console replay script
|
60
|
-
# and move it _outside_ the container div
|
61
|
-
rendered_tag.sub!(/\n(<script class="react-rails-console-replay">.*<\/script>)<\/(\w+)>$/m,'</\2>\1')
|
62
|
-
rendered_tag.html_safe
|
63
|
-
else
|
64
|
-
rendered_tag
|
65
|
-
end
|
66
|
-
end
|
74
|
+
html_option_to_use = html_options.except(:tag, :prerender, :camelize_props)
|
67
75
|
|
68
|
-
|
76
|
+
tag = content_tag(html_tag, "", html_option_to_use, &block)
|
77
|
+
return tag unless React::ServerRendering.renderer_options[:replay_console]
|
69
78
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
renderer.render(component_name, props, prerender_options)
|
79
|
+
# Grab the server-rendered console replay script
|
80
|
+
# and move it _outside_ the container div
|
81
|
+
tag.sub!(%r{\n(<script class="react-rails-console-replay">.*</script>)</(\w+)>$}m, '</\2>\1')
|
82
|
+
tag.html_safe
|
75
83
|
end
|
76
84
|
end
|
77
85
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module Rails
|
3
5
|
# A renderer class suitable for `ActionController::Renderers`.
|
@@ -20,7 +22,7 @@ module React
|
|
20
22
|
|
21
23
|
attr_accessor :output_buffer
|
22
24
|
|
23
|
-
def initialize(options={})
|
25
|
+
def initialize(options = {})
|
24
26
|
controller = options[:controller]
|
25
27
|
@__react_component_helper = controller.__react_component_helper
|
26
28
|
end
|
data/lib/react/rails/railtie.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails"
|
2
4
|
|
3
5
|
module React
|
4
6
|
module Rails
|
@@ -17,18 +19,17 @@ module React
|
|
17
19
|
config.react.server_renderer = nil # defaults to BundleRenderer
|
18
20
|
config.react.server_renderer_options = {} # BundleRenderer provides defaults
|
19
21
|
# Changing files with these extensions in these directories will cause the server renderer to reload:
|
20
|
-
config.react.server_renderer_directories = [
|
21
|
-
config.react.server_renderer_extensions = [
|
22
|
+
config.react.server_renderer_directories = ["/app/assets/javascripts/", "app/javascript"]
|
23
|
+
config.react.server_renderer_extensions = %w[jsx js]
|
22
24
|
# View helper implementation:
|
23
25
|
config.react.view_helper_implementation = nil # Defaults to ComponentMount
|
24
26
|
|
25
27
|
# Watch .jsx files for changes in dev, so we can reload the JS VMs with the new JS code.
|
26
|
-
initializer
|
28
|
+
initializer "react_rails.add_watchable_files", after: :load_config_initializers, group: :all do |app|
|
27
29
|
# Watch files ending in `server_renderer_extensions` in each of `server_renderer_directories`
|
28
|
-
reload_paths = config.react.server_renderer_directories.
|
30
|
+
reload_paths = config.react.server_renderer_directories.each_with_object({}) do |dir, memo|
|
29
31
|
app_dir = File.join(app.root, dir)
|
30
32
|
memo[app_dir] = config.react.server_renderer_extensions
|
31
|
-
memo
|
32
33
|
end
|
33
34
|
|
34
35
|
# Rails checks these objects for changes:
|
@@ -42,8 +43,7 @@ module React
|
|
42
43
|
end
|
43
44
|
|
44
45
|
# Include the react-rails view helper lazily
|
45
|
-
initializer
|
46
|
-
|
46
|
+
initializer "react_rails.setup_view_helpers", after: :load_config_initializers, group: :all do |app|
|
47
47
|
app.config.react.jsx_transformer_class ||= React::JSX::DEFAULT_TRANSFORMER
|
48
48
|
React::JSX.transformer_class = app.config.react.jsx_transformer_class
|
49
49
|
React::JSX.transform_options = app.config.react.jsx_transform_options
|
@@ -58,11 +58,11 @@ module React
|
|
58
58
|
|
59
59
|
ActiveSupport.on_load(:action_view) do
|
60
60
|
include ::React::Rails::ViewHelper
|
61
|
-
ActionDispatch::IntegrationTest.
|
61
|
+
ActionDispatch::IntegrationTest.include React::Rails::TestHelper if ::Rails.env.test?
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
initializer
|
65
|
+
initializer "react_rails.add_component_renderer", group: :all do |_app|
|
66
66
|
ActionController::Renderers.add :component do |component_name, options|
|
67
67
|
renderer = ::React::Rails::ControllerRenderer.new(controller: self)
|
68
68
|
html = renderer.call(component_name, options)
|
@@ -71,22 +71,21 @@ module React
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
initializer
|
74
|
+
initializer "react_rails.bust_cache", after: :load_config_initializers, group: :all do |app|
|
75
75
|
asset_variant = React::Rails::AssetVariant.new({
|
76
|
-
|
77
|
-
|
76
|
+
variant: app.config.react.variant
|
77
|
+
})
|
78
78
|
|
79
79
|
sprockets_env = app.assets || app.config.try(:assets) # sprockets-rails 3.x attaches this at a different config
|
80
80
|
unless sprockets_env.nil?
|
81
|
-
sprockets_env.version = [sprockets_env.version, "react-#{asset_variant.react_build}"].compact.join(
|
81
|
+
sprockets_env.version = [sprockets_env.version, "react-#{asset_variant.react_build}"].compact.join("-")
|
82
82
|
end
|
83
|
-
|
84
83
|
end
|
85
84
|
|
86
|
-
initializer
|
85
|
+
initializer "react_rails.set_variant", after: :engines_blank_point, group: :all do |app|
|
87
86
|
asset_variant = React::Rails::AssetVariant.new({
|
88
|
-
|
89
|
-
|
87
|
+
variant: app.config.react.variant
|
88
|
+
})
|
90
89
|
|
91
90
|
if app.config.respond_to?(:assets)
|
92
91
|
app.config.assets.paths << asset_variant.react_directory
|
@@ -105,16 +104,14 @@ module React
|
|
105
104
|
React::ServerRendering.reset_pool
|
106
105
|
end
|
107
106
|
|
108
|
-
initializer
|
107
|
+
initializer "react_rails.setup_engine", group: :all do |app|
|
109
108
|
# Sprockets 3.x expects this in a different place
|
110
|
-
sprockets_env = app.assets || defined?(Sprockets) && Sprockets
|
109
|
+
sprockets_env = app.assets || (defined?(Sprockets) && Sprockets)
|
111
110
|
|
112
111
|
if app.config.react.sprockets_strategy == false
|
113
112
|
# pass, Sprockets opt-out
|
114
113
|
elsif sprockets_env.present?
|
115
114
|
React::JSX::SprocketsStrategy.attach_with_strategy(sprockets_env, app.config.react.sprockets_strategy)
|
116
|
-
else
|
117
|
-
# pass, Sprockets is not preset
|
118
115
|
end
|
119
116
|
end
|
120
117
|
end
|
data/lib/react/rails/version.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module Rails
|
3
5
|
module ViewHelper
|
@@ -18,7 +20,7 @@ module React
|
|
18
20
|
# Otherwise, make a new instance.
|
19
21
|
def react_component(*args, &block)
|
20
22
|
helper_obj = @__react_component_helper ||= helper_implementation_class.new
|
21
|
-
helper_obj.react_component(*args) { capture
|
23
|
+
helper_obj.react_component(*args) { capture(&block) if block }
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
data/lib/react/rails.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "react/rails/asset_variant"
|
4
|
+
require "react/rails/railtie"
|
5
|
+
require "react/rails/controller_lifecycle"
|
6
|
+
require "react/rails/version"
|
7
|
+
require "react/rails/component_mount"
|
8
|
+
require "react/rails/view_helper"
|
9
|
+
require "react/rails/controller_renderer"
|
@@ -1,27 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "react/server_rendering/environment_container"
|
4
|
+
require "react/server_rendering/manifest_container"
|
5
|
+
require "react/server_rendering/yaml_manifest_container"
|
6
|
+
require "react/server_rendering/separate_server_bundle_container"
|
5
7
|
|
6
8
|
module React
|
7
9
|
module ServerRendering
|
8
10
|
# Extends ExecJSRenderer for the Rails environment
|
9
|
-
# - fetches JS code from the Rails app (
|
11
|
+
# - fetches JS code from the Rails app (Shakapacker or Sprockets)
|
10
12
|
# - stringifies props
|
11
13
|
# - implements console replay
|
12
14
|
class BundleRenderer < ExecJSRenderer
|
13
15
|
# Reimplement console methods for replaying on the client
|
14
|
-
CONSOLE_POLYFILL = File.read(File.join(File.dirname(__FILE__),
|
15
|
-
CONSOLE_REPLAY = File.read(File.join(File.dirname(__FILE__),
|
16
|
-
CONSOLE_RESET = File.read(File.join(File.dirname(__FILE__),
|
17
|
-
TIMEOUT_POLYFILL = File.read(File.join(File.dirname(__FILE__),
|
16
|
+
CONSOLE_POLYFILL = File.read(File.join(File.dirname(__FILE__), "bundle_renderer/console_polyfill.js"))
|
17
|
+
CONSOLE_REPLAY = File.read(File.join(File.dirname(__FILE__), "bundle_renderer/console_replay.js"))
|
18
|
+
CONSOLE_RESET = File.read(File.join(File.dirname(__FILE__), "bundle_renderer/console_reset.js"))
|
19
|
+
TIMEOUT_POLYFILL = File.read(File.join(File.dirname(__FILE__), "bundle_renderer/timeout_polyfill.js"))
|
18
20
|
|
19
|
-
def initialize(options={})
|
21
|
+
def initialize(options = {})
|
20
22
|
@replay_console = options.fetch(:replay_console, true)
|
21
|
-
filenames = options.fetch(:files, [
|
23
|
+
filenames = options.fetch(:files, ["server_rendering.js"])
|
22
24
|
js_code = CONSOLE_POLYFILL.dup
|
23
25
|
js_code << TIMEOUT_POLYFILL.dup
|
24
|
-
js_code << options.fetch(:code,
|
26
|
+
js_code << options.fetch(:code, "")
|
25
27
|
|
26
28
|
filenames.each do |filename|
|
27
29
|
js_code << asset_container.find_asset(filename)
|
@@ -40,12 +42,12 @@ module React
|
|
40
42
|
super(component_name, t_props, t_options)
|
41
43
|
end
|
42
44
|
|
43
|
-
def before_render(
|
44
|
-
@replay_console ? CONSOLE_RESET :
|
45
|
+
def before_render(_component_name, _props, _prerender_options)
|
46
|
+
@replay_console ? CONSOLE_RESET : ""
|
45
47
|
end
|
46
48
|
|
47
|
-
def after_render(
|
48
|
-
@replay_console ? CONSOLE_REPLAY :
|
49
|
+
def after_render(_component_name, _props, _prerender_options)
|
50
|
+
@replay_console ? CONSOLE_REPLAY : ""
|
49
51
|
end
|
50
52
|
|
51
53
|
class << self
|
@@ -71,20 +73,19 @@ module React
|
|
71
73
|
def prepare_options(options)
|
72
74
|
r_func = render_function(options)
|
73
75
|
opts = case options
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
76
|
+
when Hash then options
|
77
|
+
else
|
78
|
+
{}
|
79
|
+
end
|
79
80
|
# This seems redundant to pass
|
80
81
|
opts.merge(render_function: r_func)
|
81
82
|
end
|
82
83
|
|
83
84
|
def render_function(opts)
|
84
85
|
if opts == :static
|
85
|
-
|
86
|
+
"renderToStaticMarkup"
|
86
87
|
else
|
87
|
-
|
88
|
+
"renderToString"
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
@@ -100,22 +101,16 @@ module React
|
|
100
101
|
# Or, if the user has provided {.asset_container_class}, use that.
|
101
102
|
# @return [Class] suitable for {#asset_container}
|
102
103
|
def asset_container_class
|
103
|
-
if self.class.asset_container_class.present?
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# Even though they are precompiled, we can't find them :S
|
114
|
-
EnvironmentContainer
|
115
|
-
end
|
116
|
-
else
|
117
|
-
EnvironmentContainer
|
118
|
-
end
|
104
|
+
return self.class.asset_container_class if self.class.asset_container_class.present?
|
105
|
+
return SeparateServerBundleContainer if SeparateServerBundleContainer.compatible?
|
106
|
+
|
107
|
+
return EnvironmentContainer unless assets_precompiled?
|
108
|
+
|
109
|
+
return ManifestContainer if ManifestContainer.compatible?
|
110
|
+
return YamlManifestContainer if YamlManifestContainer.compatible?
|
111
|
+
|
112
|
+
# Even though they are precompiled, we can't find them :S
|
113
|
+
EnvironmentContainer
|
119
114
|
end
|
120
115
|
end
|
121
116
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module React
|
2
4
|
module ServerRendering
|
3
5
|
# A bare-bones renderer for React.js + Exec.js
|
@@ -8,9 +10,11 @@ module React
|
|
8
10
|
# @return [ExecJS::Runtime::Context] The JS context for this renderer
|
9
11
|
attr_reader :context
|
10
12
|
|
11
|
-
def initialize(options={})
|
12
|
-
js_code = options[:code] || raise(
|
13
|
-
|
13
|
+
def initialize(options = {})
|
14
|
+
js_code = options[:code] || raise("Pass `code:` option to instantiate a JS context!")
|
15
|
+
full_code = GLOBAL_WRAPPER + js_code
|
16
|
+
# File.write("./test/dummy/tmp/latest_js_context.js", full_code)
|
17
|
+
@context = ExecJS.compile(full_code)
|
14
18
|
end
|
15
19
|
|
16
20
|
def render(component_name, props, prerender_options)
|
@@ -23,8 +27,13 @@ module React
|
|
23
27
|
end
|
24
28
|
|
25
29
|
# Hooks for inserting JS before/after rendering
|
26
|
-
def before_render(
|
27
|
-
|
30
|
+
def before_render(_component_name, _props, _prerender_options)
|
31
|
+
""
|
32
|
+
end
|
33
|
+
|
34
|
+
def after_render(_component_name, _props, _prerender_options)
|
35
|
+
""
|
36
|
+
end
|
28
37
|
|
29
38
|
# Handle Node.js & other ExecJS contexts
|
30
39
|
GLOBAL_WRAPPER = <<-JS
|
@@ -40,7 +49,7 @@ module React
|
|
40
49
|
end
|
41
50
|
|
42
51
|
def main_render(component_name, props, prerender_options)
|
43
|
-
render_function = prerender_options.fetch(:render_function,
|
52
|
+
render_function = prerender_options.fetch(:render_function, "renderToString")
|
44
53
|
"this.ReactRailsUJS.serverRender('#{render_function}', '#{component_name}', #{props})"
|
45
54
|
end
|
46
55
|
|