-
Notifications
You must be signed in to change notification settings - Fork 746
Expand file tree
/
Copy pathrailtie.rb
More file actions
140 lines (114 loc) · 6.37 KB
/
railtie.rb
File metadata and controls
140 lines (114 loc) · 6.37 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# 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
})
assets = app.assets || app.config.try(:assets) # sprockets-rails 3.x attaches this at a different config
Railtie.append_react_build_to_assets_version!(assets, asset_variant.react_build)
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
# :nodoc:
def self.append_react_build_to_assets_version!(assets, react_build)
versioned_assets = versioned_assets_for(assets)
return if versioned_assets.nil?
versioned_assets.version = [versioned_assets.version, "react-#{react_build}"].compact.join("-")
end
def self.versioned_assets_for(assets)
return assets if versioned_assets?(assets)
config = assets.config if assets.respond_to?(:config)
return config if versioned_assets?(config)
nil
end
def self.versioned_assets?(assets)
assets.respond_to?(:version) && assets.respond_to?(:version=)
end
private_class_method :versioned_assets_for, :versioned_assets?
end
end
end