react-rails 2.7.1 → 3.0.0.rc.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +53 -41
- 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 +7 -49
- 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
|
|