-
Notifications
You must be signed in to change notification settings - Fork 756
/
Copy pathrailtie.rb
119 lines (100 loc) · 5.74 KB
/
railtie.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# frozen_string_literal: true
require "rails"
module React
module Rails
class Railtie < ::Rails::Railtie
config.react = ActiveSupport::OrderedOptions.new
# Sensible defaults. Can be overridden in application.rb
config.react.variant = (::Rails.env.production? ? :production : :development)
config.react.jsx_transform_options = {}
config.react.jsx_transformer_class = nil # defaults to BabelTransformer
config.react.camelize_props = false # pass in an underscored hash but get a camelized hash
config.react.sprockets_strategy = nil # how to attach JSX to the asset pipeline (or `false` for none)
# Server rendering:
config.react.server_renderer_pool_size = 1 # increase if you're on JRuby
config.react.server_renderer_timeout = 20 # seconds
config.react.server_renderer = nil # defaults to BundleRenderer
config.react.server_renderer_options = {} # BundleRenderer provides defaults
# Changing files with these extensions in these directories will cause the server renderer to reload:
config.react.server_renderer_directories = ["/app/assets/javascripts/", "app/javascript"]
config.react.server_renderer_extensions = %w[jsx js]
# View helper implementation:
config.react.view_helper_implementation = nil # Defaults to ComponentMount
# Watch .jsx files for changes in dev, so we can reload the JS VMs with the new JS code.
initializer "react_rails.add_watchable_files", after: :load_config_initializers, group: :all do |app|
# Watch files ending in `server_renderer_extensions` in each of `server_renderer_directories`
reload_paths = config.react.server_renderer_directories.each_with_object({}) do |dir, memo|
app_dir = File.join(app.root, dir)
memo[app_dir] = config.react.server_renderer_extensions
end
# Rails checks these objects for changes:
react_reloader = app.config.file_watcher.new([], reload_paths) do
React::ServerRendering.reset_pool
end
app.reloaders << react_reloader
# Reload renderers in dev when files change
config.to_prepare { react_reloader.execute_if_updated }
end
# Include the react-rails view helper lazily
initializer "react_rails.setup_view_helpers", after: :load_config_initializers, group: :all do |app|
app.config.react.jsx_transformer_class ||= React::JSX::DEFAULT_TRANSFORMER
React::JSX.transformer_class = app.config.react.jsx_transformer_class
React::JSX.transform_options = app.config.react.jsx_transform_options
app.config.react.view_helper_implementation ||= React::Rails::ComponentMount
React::Rails::ViewHelper.helper_implementation_class = app.config.react.view_helper_implementation
React::Rails::ComponentMount.camelize_props_switch = app.config.react.camelize_props
ActiveSupport.on_load(:action_controller) do
include ::React::Rails::ControllerLifecycle
end
ActiveSupport.on_load(:action_view) do
include ::React::Rails::ViewHelper
ActionDispatch::IntegrationTest.include React::Rails::TestHelper if ::Rails.env.test?
end
end
initializer "react_rails.add_component_renderer", group: :all do |_app|
ActionController::Renderers.add :component do |component_name, options|
renderer = ::React::Rails::ControllerRenderer.new(controller: self)
html = renderer.call(component_name, options)
render_options = options.merge(inline: html)
render(render_options)
end
end
initializer "react_rails.bust_cache", after: :load_config_initializers, group: :all do |app|
asset_variant = React::Rails::AssetVariant.new({
variant: app.config.react.variant
})
sprockets_env = app.assets || app.config.try(:assets) # sprockets-rails 3.x attaches this at a different config
unless sprockets_env.nil?
sprockets_env.version = [sprockets_env.version, "react-#{asset_variant.react_build}"].compact.join("-")
end
end
initializer "react_rails.set_variant", after: :engines_blank_point, group: :all do |app|
asset_variant = React::Rails::AssetVariant.new({
variant: app.config.react.variant
})
if app.config.respond_to?(:assets)
app.config.assets.paths << asset_variant.react_directory
app.config.assets.paths << asset_variant.jsx_directory
end
end
config.after_initialize do |app|
# The class isn't accessible in the configure block, so assign it here if it wasn't overridden:
app.config.react.server_renderer ||= React::ServerRendering::BundleRenderer
React::ServerRendering.pool_size = app.config.react.server_renderer_pool_size
React::ServerRendering.pool_timeout = app.config.react.server_renderer_timeout
React::ServerRendering.renderer_options = app.config.react.server_renderer_options
React::ServerRendering.renderer = app.config.react.server_renderer
React::ServerRendering.reset_pool
end
initializer "react_rails.setup_engine", group: :all do |app|
# Sprockets 3.x expects this in a different place
sprockets_env = app.assets || (defined?(Sprockets) && Sprockets)
if app.config.react.sprockets_strategy == false
# pass, Sprockets opt-out
elsif sprockets_env.present?
React::JSX::SprocketsStrategy.attach_with_strategy(sprockets_env, app.config.react.sprockets_strategy)
end
end
end
end
end