diff --git a/README.md b/README.md index d286f4bd..f4c8cbb4 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ where you will put your components //= require react_ujs //= require components ``` +- create a `server_rendering.js` manifest file and precompile it with `config/initializers/react_server_rendering.rb`. (Use `--skip-server-rendering` if you don't want this.) ## Usage @@ -177,8 +178,8 @@ _(It will also be mounted by the UJS on page load.)_ There are some requirements for this to work: -- `react-rails` must load your code. By convention, it uses `components.js`, which was created -by the install task. This file must include your components _and_ their dependencies (eg, Underscore.js). +- `react-rails` must load your code. By convention, it uses `server_rendering.js`, which was created +by the install task. This file must include React, ReactDOMServer, your components _and_ their dependencies (eg, Underscore.js). - Your components must be accessible in the global scope. If you are using `.js.jsx.coffee` files then the wrapper function needs to be taken into account: @@ -202,7 +203,7 @@ MyApp::Application.configure do config.react.server_renderer_timeout ||= 20 # seconds config.react.server_renderer = React::ServerRendering::SprocketsRenderer config.react.server_renderer_options = { - files: ["react-server.js", "components.js"], # files to load for prerendering + files: ["server_rendering.js"], # files to load for prerendering replay_console: true, # if true, console.* will be replayed client-side } end diff --git a/lib/generators/react/install_generator.rb b/lib/generators/react/install_generator.rb index 97cf5ab6..7653e4fc 100644 --- a/lib/generators/react/install_generator.rb +++ b/lib/generators/react/install_generator.rb @@ -11,9 +11,16 @@ class InstallGenerator < ::Rails::Generators::Base default: false, desc: 'Skip Git keeps' + class_option :skip_server_rendering, + type: :boolean, + default: false, + desc: "Don't generate server_rendering.js or config/initializers/react_server_rendering.rb" + def create_directory empty_directory 'app/assets/javascripts/components' - create_file 'app/assets/javascripts/components/.gitkeep' unless options[:skip_git] + if !options[:skip_git] + create_file 'app/assets/javascripts/components/.gitkeep' + end end def inject_react @@ -48,6 +55,14 @@ def create_components create_file components_file, components_js end + def create_server_rendering + return if options[:skip_server_rendering] + manifest_path = "app/assets/javascripts/server_rendering.js" + template("server_rendering.js", manifest_path) + initializer_path = "config/initializers/react_server_rendering.rb" + template("react_server_rendering.rb", initializer_path) + end + private def manifest diff --git a/lib/generators/templates/react_server_rendering.rb b/lib/generators/templates/react_server_rendering.rb new file mode 100644 index 00000000..4d09c78b --- /dev/null +++ b/lib/generators/templates/react_server_rendering.rb @@ -0,0 +1,2 @@ +# To render React components in production, precompile the server rendering manifest: +Rails.application.config.assets.precompile += ["server_rendering.js"] diff --git a/lib/generators/templates/server_rendering.js b/lib/generators/templates/server_rendering.js new file mode 100644 index 00000000..78bd57a3 --- /dev/null +++ b/lib/generators/templates/server_rendering.js @@ -0,0 +1,5 @@ +//= require react-server +//= require ./components +// +// By default, this file is loaded for server-side rendering. +// It should require your components and any dependencies. diff --git a/lib/react/server_rendering/sprockets_renderer.rb b/lib/react/server_rendering/sprockets_renderer.rb index 86a0b13d..3a48c94b 100644 --- a/lib/react/server_rendering/sprockets_renderer.rb +++ b/lib/react/server_rendering/sprockets_renderer.rb @@ -13,7 +13,7 @@ class SprocketsRenderer < ExecJSRenderer def initialize(options={}) @replay_console = options.fetch(:replay_console, true) - filenames = options.fetch(:files, ["react-server.js", "components.js"]) + filenames = options.fetch(:files, ["server_rendering.js"]) js_code = CONSOLE_POLYFILL.dup filenames.each do |filename| diff --git a/test/dummy/app/assets/javascripts/server_rendering.js b/test/dummy/app/assets/javascripts/server_rendering.js new file mode 100644 index 00000000..689430aa --- /dev/null +++ b/test/dummy/app/assets/javascripts/server_rendering.js @@ -0,0 +1,2 @@ +//= require react-server +//= require ./components diff --git a/test/generators/install_generator_test.rb b/test/generators/install_generator_test.rb index a54ef35c..809862a1 100644 --- a/test/generators/install_generator_test.rb +++ b/test/generators/install_generator_test.rb @@ -62,6 +62,25 @@ def copy_directory(dir) assert_application_file_modified end + test "creates server_rendering.js with default requires" do + run_generator + server_rendering_file_path = "app/assets/javascripts/server_rendering.js" + assert_file server_rendering_file_path, %r{//= require react-server\n} + assert_file server_rendering_file_path, %r{//= require ./components\n} + end + + test "creates server rendering initializer" do + run_generator + initializer_path = "config/initializers/react_server_rendering.rb" + assert_file(initializer_path, %r{Rails.application.config.assets.precompile \+= \["server_rendering.js"\]}) + end + + test "skipping server rendering" do + run_generator %w(--skip-server-rendering) + assert_no_file "config/initializers/react_server_rendering.rb" + assert_no_file "app/assets/javascripts/server_rendering.js" + end + def init_application_js(content) FileUtils.mkdir_p destination_root + '/app/assets/javascripts/' File.write destination_root + '/app/assets/javascripts/application.js', content