Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server Side rendering disabled if HMR running #1156

Merged
merged 2 commits into from
Oct 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ Changes since last non-beta release.

*Please add entries here for your pull requests that are not yet released.*

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

#### Improved
- Improved tutorial and support for HMR when using `rails/webpacker` for Webpack configuration. [PR 1156](https://github.com/shakacode/react_on_rails/pull/1156) by [justin808](https://github.com/justin808).

### [11.1.7] - 2018-10-10
#### Fixed
- Fixed bug where intl parsing would fail when trying to parse integers or blank entries. by [sepehr500](https://github.com/sepehr500)
Expand Down Expand Up @@ -834,7 +839,8 @@ Best done with Object destructing:
##### Fixed
- Fix several generator related issues.

[Unreleased]: https://github.com/shakacode/react_on_rails/compare/11.1.7...master
[Unreleased]: https://github.com/shakacode/react_on_rails/compare/11.1.8...master
[11.1.8]: https://github.com/shakacode/react_on_rails/compare/11.1.7...11.1.8
[11.1.7]: https://github.com/shakacode/react_on_rails/compare/11.1.6...11.1.7
[11.1.6]: https://github.com/shakacode/react_on_rails/compare/11.1.5...11.1.6
[11.1.5]: https://github.com/shakacode/react_on_rails/compare/11.1.4...11.1.5
Expand Down
2 changes: 1 addition & 1 deletion SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
+ [Setting up Hot Reloading during Rails Development, API docs](./docs/api/ruby-api-hot-reload-view-helpers.md)
+ [Developing with the Webpack Dev Server](./docs/additional-reading/webpack-dev-server.md)
+ [Webpack, the Asset Pipeline, and Using Assets w/ React](./docs/additional-reading/rails-assets-relative-paths.md)
+ [Hot Reloading of Assets For Rails Development](./docs/additional-reading/hot-reloading-rails-development.md)
+ [Hot Reloading of Assets For Rails Development for Asset Pipeline](docs/additional-reading/hot-reloading-rails-development-asset-pipeline.md)

## **[CONTRIBUTING](CONTRIBUTING.md)**
+ [Generator Testing](./docs/contributor-info/generator-testing.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
# Live Reloading vs. Hot Reloading (aka HMR)

The use of the [webpack-dev-server](https://webpack.js.org/configuration/dev-server/) provides "Live Reloading" by default. The difference between live and hot reloading is that live reloading will act similarly to hitting refresh in the browser. Hot reloading will attempt to preserve the state of any props.

See the Webpack document [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) for more details on the concepts of live vs. hot reloading.

The remainder of this document discusses HMR.

# Using the Webpacker Webpack setup

If you are using the default Webpacker setup of running the dev server with `bin/webpack-dev-server`, see the [Webpacker Webpack Dev Server discussion of HMR](https://github.com/rails/webpacker/blob/master/docs/webpack-dev-server.md#hot-module-replacement).
*This document should only be referenced if you're **NOT** using the current technique of the rails/webpacker helpers to place your client-side assets in your `/public` directory.*


# Hot Reloading of Assets For Rails Development

_Note, this document is not yet updated for React on Rails v8+. See [PR #865](https://github.com/shakacode/react_on_rails/pull/865) for a detailed example of doing hot reloading using V8+ with Webpack v2. Any volunteers to update this page? See [#772](https://github.com/shakacode/react_on_rails/issues/772) and [#361](https://github.com/shakacode/react-webpack-rails-tutorial/issues/361)._
_See [PR #865](https://github.com/shakacode/react_on_rails/pull/865) for a detailed example of doing hot reloading using V8+ with Webpack v2. See [#772](https://github.com/shakacode/react_on_rails/issues/772) and [#361](https://github.com/shakacode/react-webpack-rails-tutorial/issues/361)._

------

Expand Down
2 changes: 1 addition & 1 deletion docs/misc-pending/manual-installation-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The default path: `public/webpack` can be loaded with webpackConfigLoader as sho
1. Add `gem "webpacker"` to the Gemfile, run bundle. The gem provides the `stylesheet_pack_tag` and `javascript_pack_tag` helpers which is used to load the bundled assets to your layouts.[Dummy Example](../../spec/dummy/app/views/layouts/application.html.erb)
1. Configure the `config/initializers/react_on_rails.rb`. You can adjust some necessary settings and defaults. See file [spec/dummy/config/initializers/react_on_rails.rb](../../spec/dummy/config/initializers/react_on_rails.rb) for a detailed example of configuration, including comments on the different values to configure.
1. Configure your Procfiles per the example apps. These are at the root of your Rails installation.
1. Configure your top level JavaScript files for inclusion in your layout. You'll want a version that you use for static assets, and you want a file for any files in your setup that are not part of your webpack build. The reason for this is for use with hot-reloading. If you are not using hot reloading, then you only need to configure your `application.js` file to include your Webpack generated files. For more information on hot reloading, see [Hot Reloading of Assets For Rails Development](../additional-reading/hot-reloading-rails-development.md)
1. Configure your top level JavaScript files for inclusion in your layout. You'll want a version that you use for static assets, and you want a file for any files in your setup that are not part of your webpack build. The reason for this is for use with hot-reloading. If you are not using hot reloading, then you only need to configure your `application.js` file to include your Webpack generated files. For more information on hot reloading, see [Hot Reloading of Assets For Rails Development](../additional-reading/hot-reloading-rails-development-asset-pipeline.md)
1. If you are deploying to Heroku, see [heroku-deployment.md](/docs/additional-reading/heroku-deployment.md)

If I missed anything, please submit a PR or file an issue.
24 changes: 21 additions & 3 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,26 @@ mv app/javascript client
source_path: client
```

At this point, you can optionally turn off server rendering and use `foreman start -f Procfile.dev-server`.
## Using HMR with the rails/webpacker setup

Hot reloading using default rails/webpacker configuration with server rendering is not supported.
Start the app using `foreman start -f Procfile.dev-server`.

Feedback is greatly appreciated! As are stars on github! If you want personalized help, don't hesitate to get in touch with us at [[email protected]](mailto:[email protected]).
When you change a JSX file and save, the browser will automatically refresh!

So you get some basics from HMR with no code changes. If you want to go further, take a look at these links:

* https://github.com/rails/webpacker/blob/master/docs/webpack-dev-server.md
* https://webpack.js.org/configuration/dev-server/
* https://webpack.js.org/concepts/hot-module-replacement/
* https://gaearon.github.io/react-hot-loader/getstarted/
* https://github.com/gaearon/react-hot-loader

React on Rails will automatically handle disabling server rendering if there is only one bundle file created by the Webpack development server by rails/webpacker.

## Conclusion

* Browse the docs either on the [gitbook](https://shakacode.gitbooks.io/react-on-rails/content/) or in the [docs directory on github](https://github.com/shakacode/react_on_rails/tree/master/docs)

Feedback is greatly appreciated! As are stars on github!

If you want personalized help, don't hesitate to get in touch with us at [[email protected]](mailto:[email protected]). We offer [React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki) and consulting so you can focus on your app and not on how to make Webpack plus Rails work optimally.
4 changes: 3 additions & 1 deletion lib/react_on_rails/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,9 @@ def props_string(props)

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

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 @@ -95,19 +95,21 @@ def eval_js(js_code, _render_options)
end
end

def read_bundle_js_code
server_js_file = ReactOnRails::Utils.server_bundle_js_file_path
File.read(server_js_file)
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 "\
"avoid this warning.\nError is: #{e}"
raise ReactOnRails::Error, msg
end

def create_js_context
return if ReactOnRails.configuration.server_bundle_js_file.blank?

server_js_file = ReactOnRails::Utils.server_bundle_js_file_path
bundle_js_code = read_bundle_js_code

begin
bundle_js_code = File.read(server_js_file)
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 "\
"avoid this warning.\nError is: #{e}"
raise ReactOnRails::Error, msg
end
# rubocop:disable Layout/IndentHeredoc
base_js_code = <<-JS
#{console_polyfill}
Expand All @@ -118,7 +120,10 @@ def create_js_context
file_name = "tmp/base_js_code.js"
begin
if ReactOnRails.configuration.trace
Rails.logger.info { "[react_on_rails] Created JavaScript context with file #{server_js_file}" }
Rails.logger.info do
"[react_on_rails] Created JavaScript context with file "\
"#{ReactOnRails::Utils.server_bundle_js_file_path}"
end
end
ExecJS.compile(base_js_code)
rescue StandardError => e
Expand Down
4 changes: 4 additions & 0 deletions lib/react_on_rails/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def self.invoke_and_exit_if_failed(cmd, failure_message)
[stdout, stderr, status]
end

def self.server_bundle_path_is_http?
server_bundle_js_file_path =~ %r{https?://}
end

def self.server_bundle_js_file_path
# Either:
# 1. Using same bundle for both server and client, so server bundle will be hashed in manifest
Expand Down
5 changes: 5 additions & 0 deletions lib/react_on_rails/webpacker_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ def self.using_webpacker?
ReactOnRails::Utils.gem_available?("webpacker")
end

def self.dev_server_running?
return false unless using_webpacker?
Webpacker.dev_server.running?
end

def self.bundle_js_file_path_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")
Expand Down