Skip to content

Commit

Permalink
Enable webpack-dev-server with SSR (#1173)
Browse files Browse the repository at this point in the history
* enable webpack-dev-server & ssr
* upgrade nps for security issue
* Ensure proper encoding when reading file from URL from
  webpack-dev-server
  • Loading branch information
Judahmeek authored and justin808 committed Dec 6, 2018
1 parent b4d3763 commit fa292c7
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 113 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Change Log
All notable changes to this project's source code will be documented in this file. Items under `Unreleased` is upcoming features that will be out in next version. NOTE: major versions of the npm module and the gem must be kept in sync.

Migration instructions for the major updates can be found [here](docs/basics/upgrading-react-on-rails.md#upgrading-to-version-9.md). Some smaller migration information can be found here.
Migration instructions for the major updates can be found [here](docs/basics/upgrading-react-on-rails.md#upgrading-to-version-9.md). Some smaller migration information can be found here.

## Need Help Migrating?
If you would like help in migrating between React on Rails versions or help with implementing server rendering, please contact [justin@shakacode.com](mailto:justin@shakacode.com) for information about our [ShakaCode Pro Support](https://www.shakacode.com/work/shakacode-pro-support.pdf).
Expand All @@ -20,6 +20,8 @@ Changes since last non-beta release.
#### Improved
- To support React v16, updated API for manually calling `ReactOnRails.render(name, props, domNodeId, hydrate)`. Added 3rd @param hydrate Pass truthy to update server rendered html. Default is falsey Any truthy values calls hydrate rather than render. (https://github.com/shakacode/react_on_rails/pull/1159) by [justin808](https://github.com/justin808) and [coopersamuel](https://github.com/coopersamuel).

- Enabled the use of webpack-dev-server with Server-side rendering. (https://github.com/shakacode/react_on_rails/pull/1173) by [justin808](https://github.com/justin808) and [judahmeek](https://github.com/judahmeek).

### [11.1.8] - 2018-10-14

#### Improved
Expand Down Expand Up @@ -54,7 +56,7 @@ Changes since last non-beta release.

#### Fixed
- Tests now properly exit if the config.build_test_command fails!
- Source path for project using Webpacker would default to "app/javascript" even if when the node_modules
- Source path for project using Webpacker would default to "app/javascript" even if when the node_modules
directory was set to "client". Fix now makes the configuration of this crystal clear.
- renamed method RenderOptions.has_random_dom_id? to RenderOptions.random_dom_id? for rubocop rule.
[PR 1133](https://github.com/shakacode/react_on_rails/pull/1133) by [justin808](https://github.com/justin808)
Expand Down
1 change: 0 additions & 1 deletion docs/basics/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ ReactOnRails.configure do |config|
# While you may configure this to be the same as your client bundle file, this file is typically
# different. Note, be sure to include the exact file name with the ".js" if you are not hashing this file.
# If you are hashing this file (supposing you are using the same file for client rendering), then
#
# you should include a name that matches your bundle name in your webpack config.
config.server_bundle_js_file = "server-bundle.js"

Expand Down
4 changes: 1 addition & 3 deletions lib/react_on_rails/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,7 @@ def props_string(props)

# Returns object with values that are NOT html_safe!
def server_rendered_react_component(render_options)
if !render_options.prerender || ReactOnRails::Utils.server_bundle_path_is_http?
return { "html" => "", "consoleReplayScript" => "" }
end
return { "html" => "", "consoleReplayScript" => "" } unless render_options.prerender

react_component_name = render_options.react_component_name
props = render_options.props
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

module ReactOnRails
module ServerRenderingPool
# rubocop:disable Metrics/ClassLength
class RubyEmbeddedJavaScript
# rubocop:enable Metrics/ClassLength
class << self
def reset_pool
options = {
Expand All @@ -17,12 +19,16 @@ def reset_pool
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

@server_bundle_timestamp = file_mtime
if ReactOnRails::Utils.server_bundle_path_is_http?
return if @server_bundle_url == ReactOnRails::Utils.server_bundle_js_file_path
@server_bundle_url = ReactOnRails::Utils.server_bundle_js_file_path
else
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
end
ReactOnRails::ServerRenderingPool.reset_pool
end

Expand Down Expand Up @@ -97,7 +103,11 @@ def eval_js(js_code, _render_options)

def read_bundle_js_code
server_js_file = ReactOnRails::Utils.server_bundle_js_file_path
File.read(server_js_file)
if ReactOnRails::Utils.server_bundle_path_is_http?
file_url_to_string(server_js_file)
else
File.read(server_js_file)
end
rescue StandardError => e
msg = "You specified server rendering JS file: #{server_js_file}, but it cannot be "\
"read. You may set the server_bundle_js_file in your configuration to be \"\" to "\
Expand Down Expand Up @@ -194,6 +204,19 @@ def console_polyfill
JS
# rubocop:enable Layout/IndentHeredoc
end

private

def file_url_to_string(url)
response = Net::HTTP.get_response(URI.parse(url))
content_type_header = response["content-type"]
match = content_type_header.match(/\A.*; charset=(?<encoding>.*)\z/)
encoding_type = match[:encoding]
response.body.force_encoding(encoding_type)
rescue StandardError => e
msg = "file_url_to_string #{url} failed\nError is: #{e}"
raise ReactOnRails::Error, msg
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/react_on_rails/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def self.server_bundle_js_file_path

def self.bundle_js_file_path(bundle_name)
if ReactOnRails::WebpackerUtils.using_webpacker? && bundle_name != "manifest.json"
ReactOnRails::WebpackerUtils.bundle_js_file_path_from_webpacker(bundle_name)
ReactOnRails::WebpackerUtils.bundle_js_uri_from_webpacker(bundle_name)
else
# Default to the non-hashed name in the specified output directory, which, for legacy
# React on Rails, this is the output directory picked up by the asset pipeline.
Expand Down
3 changes: 2 additions & 1 deletion lib/react_on_rails/webpacker_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ def self.dev_server_running?
Webpacker.dev_server.running?
end

def self.bundle_js_file_path_from_webpacker(bundle_name)
# This returns either a URL for the webpack-dev-server or a file path
def self.bundle_js_uri_from_webpacker(bundle_name)
# Note Webpacker 3.4.3 manifest lookup is inside of the public_output_path
# [2] (pry) ReactOnRails::WebpackerUtils: 0> Webpacker.manifest.lookup("app-bundle.js")
# "/webpack/development/app-bundle-c1d2b6ab73dffa7d9c0e.js"
Expand Down
3 changes: 3 additions & 0 deletions spec/dummy/Procfile.static
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Run Rails without hot reloading (static assets).
# For debugging with Pry:
# Tab 1: `foreman start -f Procfile.dev -m puma=0,all=1`
# Tab 2: `rails s webrick`
rails: rails s -b 0.0.0.0

# Build client assets, watching for changes.
Expand Down
Loading

0 comments on commit fa292c7

Please sign in to comment.