Skip to content

Commit

Permalink
Small refactorings
Browse files Browse the repository at this point in the history
  • Loading branch information
justin808 committed Apr 23, 2018
1 parent 8dbd5b9 commit 3163d84
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 63 deletions.
6 changes: 4 additions & 2 deletions lib/react_on_rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ def self.configure
end

DEFAULT_GENERATED_ASSETS_DIR = File.join(%w[public webpack], Rails.env).freeze
DEFAULT_SERVER_RENDER_TIMEOUT = 20
DEFAULT_POOL_SIZE = 1

def self.setup_config_values
ensure_webpack_generated_files_exists
Expand Down Expand Up @@ -112,8 +114,8 @@ def self.configuration
raise_on_prerender_error: false,
trace: Rails.env.development?,
development_mode: Rails.env.development?,
server_renderer_pool_size: 1,
server_renderer_timeout: 20,
server_renderer_pool_size: DEFAULT_POOL_SIZE,
server_renderer_timeout: DEFAULT_SERVER_RENDER_TIMEOUT,
skip_display_none: nil,
# skip_display_none is deprecated
webpack_generated_files: %w[manifest.json],
Expand Down
22 changes: 12 additions & 10 deletions lib/react_on_rails/react_on_rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ def server_rendered_react_component_html(
# Read more here: http://timelessrepo.com/json-isnt-a-javascript-subset

# rubocop:disable Layout/IndentHeredoc
wrapper_js = <<-JS
js_code = <<-JS
(function() {
var railsContext = #{rails_context(server_side: true).to_json};
#{initialize_redux_stores}
Expand All @@ -427,26 +427,28 @@ def server_rendered_react_component_html(
JS
# rubocop:enable Layout/IndentHeredoc

result = ReactOnRails::ServerRenderingPool.server_render_js_with_console_logging(wrapper_js)
begin
result = ReactOnRails::ServerRenderingPool.server_render_js_with_console_logging(js_code)
rescue StandardError => err
# This error came from the renderer
raise ReactOnRails::PrerenderError, component_name: react_component_name,
# Sanitize as this might be browser logged
props: sanitized_props_string(props),
err: err,
js_code: js_code
end

if result["hasErrors"] && raise_on_prerender_error
# We caught this exception on our backtrace handler
raise ReactOnRails::PrerenderError, component_name: react_component_name,
# Sanitize as this might be browser logged
props: sanitized_props_string(props),
err: nil,
js_code: wrapper_js,
js_code: js_code,
console_messages: result["consoleReplayScript"]

end
result
rescue ExecJS::ProgramError => err
# This error came from execJs
raise ReactOnRails::PrerenderError, component_name: react_component_name,
# Sanitize as this might be browser logged
props: sanitized_props_string(props),
err: err,
js_code: wrapper_js
end

def initialize_redux_stores
Expand Down
104 changes: 53 additions & 51 deletions lib/react_on_rails/server_rendering_pool/ruby_embedded_java_script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,60 @@
module ReactOnRails
module ServerRenderingPool
class RubyEmbeddedJavaScript
def self.reset_pool
options = {
size: ReactOnRails.configuration.server_renderer_pool_size,
timeout: ReactOnRails.configuration.server_renderer_timeout
}
@js_context_pool = ConnectionPool.new(options) { create_js_context }
end
class << self
def reset_pool
options = {
size: ReactOnRails.configuration.server_renderer_pool_size,
timeout: ReactOnRails.configuration.server_renderer_timeout
}
@js_context_pool = ConnectionPool.new(options) { create_js_context }
end

def self.reset_pool_if_server_bundle_was_modified
return unless ReactOnRails.configuration.development_mode
def reset_pool_if_server_bundle_was_modified
return unless ReactOnRails.configuration.development_mode

file_mtime = File.mtime(ReactOnRails::Utils.server_bundle_js_file_path)
@server_bundle_timestamp ||= file_mtime
return if @server_bundle_timestamp == file_mtime
file_mtime = File.mtime(ReactOnRails::Utils.server_bundle_js_file_path)
@server_bundle_timestamp ||= file_mtime
return if @server_bundle_timestamp == file_mtime

@server_bundle_timestamp = file_mtime
@server_bundle_timestamp = file_mtime

ReactOnRails::ServerRenderingPool.reset_pool
end

# js_code: JavaScript expression that returns a string.
# Returns a Hash:
# html: string of HTML for direct insertion on the page by evaluating js_code
# consoleReplayScript: script for replaying console
# hasErrors: true if server rendering errors
# Note, js_code does not have to be based on React.
# js_code MUST RETURN json stringify Object
# Calling code will probably call 'html_safe' on return value before rendering to the view.
def self.server_render_js_with_console_logging(js_code)
if ReactOnRails.configuration.trace
@file_index ||= 1
trace_js_code_used("Evaluating code to server render.", js_code,
"tmp/server-generated-#{@file_index % 10}.js")
@file_index += 1
ReactOnRails::ServerRenderingPool.reset_pool
end
json_string = eval_js(js_code)
result = JSON.parse(json_string)

if ReactOnRails.configuration.logging_on_server
console_script = result["consoleReplayScript"]
console_script_lines = console_script.split("\n")
console_script_lines = console_script_lines[2..-2]
re = /console\.(log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
if console_script_lines
console_script_lines.each do |line|
match = re.match(line)
Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match

# js_code: JavaScript expression that returns a string.
# evaluator: Ruby object with method eval_js
# Returns a Hash:
# html: string of HTML for direct insertion on the page by evaluating js_code
# consoleReplayScript: script for replaying console
# hasErrors: true if server rendering errors
# Note, js_code does not have to be based on React.
# js_code MUST RETURN json stringify Object
# Calling code will probably call 'html_safe' on return value before rendering to the view.
def server_render_js_with_console_logging(js_code, evaluator = self)
if ReactOnRails.configuration.trace
@file_index ||= 1
trace_js_code_used("Evaluating code to server render.", js_code,
"tmp/server-generated-#{@file_index % 10}.js")
@file_index += 1
end
json_string = evaluator.eval_js(js_code)
result = JSON.parse(json_string)

if ReactOnRails.configuration.logging_on_server
console_script = result["consoleReplayScript"]
console_script_lines = console_script.split("\n")
console_script_lines = console_script_lines[2..-2]
re = /console\.(log|error)\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
if console_script_lines
console_script_lines.each do |line|
match = re.match(line)
Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
end
end
end
result
end
result
end

class << self
private

def trace_js_code_used(msg, js_code, file_name = "tmp/server-generated.js", force: false)
return unless ReactOnRails.configuration.trace || force
Expand Down Expand Up @@ -101,8 +100,7 @@ def create_js_context
end
# rubocop:disable Layout/IndentHeredoc
base_js_code = <<-JS
#{console_polyfill}
#{execjs_timer_polyfills}
#{js_polyfills}
#{bundle_js_code};
JS
# rubocop:enable Layout/IndentHeredoc
Expand All @@ -124,6 +122,11 @@ def create_js_context
end
end

def js_polyfills
console_polyfill
execjs_timer_polyfills
end

def execjs_timer_polyfills
# rubocop:disable Layout/IndentHeredoc
<<-JS
Expand Down Expand Up @@ -156,8 +159,7 @@ def execjs_timer_polyfills

def undefined_for_exec_js_logging(function_name)
if ReactOnRails.configuration.trace
"console.error('[React on Rails Rendering] #{function_name} is not defined for execJS. See "\
"https://github.com/sstephenson/execjs#faq. Note babel-polyfill may call this.');\n"\
"console.error('[React on Rails Rendering] #{function_name} is not defined for server rendering.');\n"\
" console.error(getStackTrace().join('\\n'));"
else
""
Expand Down

0 comments on commit 3163d84

Please sign in to comment.