class Reactssr::ServerRendering::SsrRenderer

Constants

CONSOLE_POLYFILL

@see ‘react/server_rendring/sprockets_rendering.rb`

CONSOLE_REPLAY

@see ‘react/server_rendring/sprockets_rendering.rb`

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method
# File lib/reactssr/server_rendering/ssr_renderer.rb, line 9
def initialize(options = {})
  @replay_console = options.fetch(:replay_console, true)
  filenames = options.fetch(:files, ['react.js'])

  js_code = CONSOLE_POLYFILL.dup 

  filenames.each do |filename|
    js_code << ::Rails.application.assets[filename].to_s
  end

  @before_render_code ||= File.read("#{File.dirname __FILE__}/../assets/before_render.js")
  
  @manifest_base ||= File.join(::Rails.public_path, ::Rails.application.config.assets.prefix)
  load_asset_on_init

  super(options.merge(code: js_code))
end

Public Instance Methods

after_render(component_name, props, prerender_options) click to toggle source
# File lib/reactssr/server_rendering/ssr_renderer.rb, line 76
def after_render(component_name, props, prerender_options)
  @replay_console ? CONSOLE_REPLAY : ""
end
before_render(component_name, props, prerender_options) click to toggle source

This will insert some js code before the React.render So, we will gather all the code for that controller#action in here.

# File lib/reactssr/server_rendering/ssr_renderer.rb, line 58
def before_render(component_name, props, prerender_options)
  jscode = @before_render_code.dup

  success = false
  if ::Rails.env.production?
    content, success = load_asset(entry)
  end

  if not success
    jscode << ::Rails.application.assets[entry].to_s
  else 
    jscode << content
  end

  # the result is jscode
  jscode
end
render(component_name, props, pre_options) click to toggle source
Calls superclass method
# File lib/reactssr/server_rendering/ssr_renderer.rb, line 27
def render(component_name, props, pre_options)
  prerender_options = pre_options[:prerender_options]

  @controller_path = pre_options.fetch(:controller_path, nil)
  # @action_name = pre_options.fetch(:action_name, nil)

  # if @controller_path.nil? or @action_name.nil?
  if @controller_path.nil?
    raise Reactssr::ServerRendering::RuntimeCommonError.new("Could not found the controller path or action name in current context.")
  end

  # pass prerender: :static to use renderToStaticMarkup
  react_render_method = if prerender_options == :static
      "renderToStaticMarkup"
    else
      "renderToString"
    end

  if !props.is_a?(String)
    props = props.to_json
  end

  our_component_name = "Components.#{component_name}"

  super(our_component_name, props, {render_function: react_render_method})
end

Protected Instance Methods

entry() click to toggle source
# File lib/reactssr/server_rendering/ssr_renderer.rb, line 105
def entry
  components = ::Rails.application.config.reactssr.assets_base || 'components'
  path = @controller_path.to_s.split('.').join('_')
  entry = File.join(components, "#{path}.ssr.js")
end

Private Instance Methods

assets() click to toggle source
# File lib/reactssr/server_rendering/ssr_renderer.rb, line 129
def assets
  @data['assets'] ||= {}
end
files() click to toggle source
# File lib/reactssr/server_rendering/ssr_renderer.rb, line 133
def files
  @data['files'] ||= {}
end
json_decode(obj) click to toggle source
# File lib/reactssr/server_rendering/ssr_renderer.rb, line 166
def json_decode(obj)
  ::MultiJson.load(obj)
end
load_asset(filename) click to toggle source

Return asset content

# File lib/reactssr/server_rendering/ssr_renderer.rb, line 114
def load_asset(filename)
  digest_path = assets[filename]

  if digest_path.nil?
    return '', false 
  end

  file = File.join(@manifest_base, digest_path)
  if not File.exist?(file)
    return '', false 
  end

  return File.read(file), true
end
load_asset_on_init() click to toggle source

load assets from Rails.public_path

# File lib/reactssr/server_rendering/ssr_renderer.rb, line 138
def load_asset_on_init
  paths = Dir[File.join(@manifest_base, "manifest*.json")]
  if paths.any?
    path = paths.first
  else 
    paths = File.join(@manifest_base, "manifest.yml")
    if !File.exist?(paths)
      # No precompile
      return {}
    end
    
    data = ::YAML::load(File.read(paths))
    @data = data.is_a?(Hash) ? data : {}
    return @data
  end

  begin
    if File.exist?(path)
      data = json_decode(File.read(path))
    end
  rescue ::MultiJson::DecodeError => e
    return {}
  end

  @data = data.is_a?(Hash) ? data : {}
end