From 80592ce0b2993c64b42cb49eaa95acbd280c03fb Mon Sep 17 00:00:00 2001 From: Justin Gordon Date: Sat, 23 May 2020 13:34:34 -1000 Subject: [PATCH] Justin808/updates for hmr with webpacker v4 (#1240) * Added same_bundle_for_client_and_server Added configuration option `same_bundle_for_client_and_server` with default `false` because 1. Production applications would typically have a server bundle that differs from the client bundle 2. This change only affects trying to use HMR with react_on_rails with rails/webpacker. The previous behavior was to always go to the webpack-dev-server for the server bundle if the webpack-dev-server was running _and_ the server bundle was found in the `manifest.json`. If you are using the **same bundle for client and server rendering**, then set this configuration option to `true`. Also, remove the requirement that the server bundle have the default deployment path. A subdirectory can be specified for the server_bundle_js_file. --- .rubocop.yml | 30 +++- CHANGELOG.md | 23 ++- Gemfile.rails32 | 73 -------- README.md | 3 +- docs/basics/configuration.md | 107 ++++++------ docs/basics/i18n.md | 3 +- docs/basics/webpack-configuration.md | 16 +- docs/tutorial.md | 71 +++++--- lib/react_on_rails/configuration.rb | 27 +-- .../test_helper/ensure_assets_compiled.rb | 1 + lib/react_on_rails/version_checker.rb | 1 + lib/react_on_rails/webpacker_utils.rb | 13 +- rakelib/example_type.rb | 1 + react_on_rails.gemspec | 4 +- spec/dummy/Gemfile | 1 - spec/dummy/Gemfile.lock | 159 +++++++++--------- spec/dummy/spec/spec_helper.rb | 2 - spec/react_on_rails/spec_helper.rb | 3 +- .../webpack_assets_compiler_spec.rb | 2 +- spec/react_on_rails/utils_spec.rb | 50 +++++- 20 files changed, 316 insertions(+), 274 deletions(-) delete mode 100644 Gemfile.rails32 diff --git a/.rubocop.yml b/.rubocop.yml index 229e639a5..096b9406b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -41,7 +41,7 @@ Naming/FileName: Style/SafeNavigation: Enabled: false -Metrics/LineLength: +Layout/LineLength: Max: 120 Style/StringLiterals: @@ -50,6 +50,15 @@ Style/StringLiterals: Style/Documentation: Enabled: false +Style/HashEachMethods: + Enabled: true + +Style/HashTransformKeys: + Enabled: true + +Style/HashTransformValues: + Enabled: true + Lint/AssignmentInCondition: Exclude: - 'spec/dummy/bin/spring' @@ -90,3 +99,22 @@ Style/GlobalVars: Style/FrozenStringLiteralComment: EnforcedStyle: always + +Layout/EmptyLinesAroundAttributeAccessor: + Enabled: true + +Layout/SpaceAroundMethodCallOperator: + Enabled: true + +Lint/RaiseException: + Enabled: true + +Lint/StructNewOverride: + Enabled: true + +Style/ExponentialNotation: + Enabled: true + +Style/SlicingWithRange: + Enabled: true + diff --git a/CHANGELOG.md b/CHANGELOG.md index 9992eb89a..3b9d1c623 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,9 +15,6 @@ Please follow the recommendations outlined at [keepachangelog.com](http://keepac Changes since last non-beta release. *Please add entries here for your pull requests that are not yet released.* -* Added support to export locales in JSON format. New option added `i18n_output_format` which allows to specify locales format either `json` or `js`. -**`json` format is now the default** -[PR 1271](https://github.com/shakacode/react_on_rails/pull/1271) by [ashgaliyev](https://github.com/ashgaliyev). ## UPCOMING 12.0 RELEASE ### [12.0.0] @@ -38,6 +35,26 @@ for details. * Removal of support for old Rubies and Rails. * Removal of config.symlink_non_digested_assets_regex as it's no longer needed with rails/webpacker. If any business needs this, we can move the code to a separate gem. +* Added configuration option `same_bundle_for_client_and_server` with default `false` because + + 1. Production applications would typically have a server bundle that differs from the client bundle + 2. This change only affects trying to use HMR with react_on_rails with rails/webpacker. + + The previous behavior was to always go to the webpack-dev-server for the server bundle if the + webpack-dev-server was running _and_ the server bundle was found in the `manifest.json`. + + If you are using the **same bundle for client and server rendering**, then set this configuration option + to `true`. By [justin808](https://github.com/shakacode/react_on_rails/pull/1240). + +* Added support to export locales in JSON format. New option added `i18n_output_format` which allows to + specify locales format either `JSON` or `JS`. **`JSON` format is now the default.** + + Use this config setting to get the old behavior: config.i18n_output_format = 'js' + + [PR 1271](https://github.com/shakacode/react_on_rails/pull/1271) by [ashgaliyev](https://github.com/ashgaliyev). + +#### Improved +- Removed unnecessary restriction to keep the server bundle in the same directory with the client bundles. Rails/webpacker 4 has an advanced cleanup that will remove any files in the directory of other webpack files. Removing this restriction allows the server bundle to be created in a sibling directory. By [justin808](https://github.com/shakacode/react_on_rails/pull/1240). ### [11.3.0] - 2019-05-24 #### Added diff --git a/Gemfile.rails32 b/Gemfile.rails32 deleted file mode 100644 index 8d1f36da8..000000000 --- a/Gemfile.rails32 +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -eval_gemfile File.expand_path("../react_on_rails.gemspec", __FILE__) - -# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem "rails", "~> 3.2" -# Use sqlite3 as the database for Active Record -gem "sqlite3" -# Use SCSS for stylesheets -gem "sass-rails" -# Use Uglifier as compressor for JavaScript assets -gem "uglifier" -# Use CoffeeScript for .coffee assets and views -gem "coffee-rails" - -# Use jquery as the JavaScript library -gem "jquery-rails" - -gem "puma" - -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -gem "jbuilder" -# bundle exec rake doc:rails generates the API under doc/api. -gem "sdoc", group: :doc - -# Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' - -# Use Unicorn as the app server -# gem 'unicorn' - -# Use Capistrano for deployment -# gem 'capistrano-rails', group: :development - -gem "mini_racer" -gem "connection_pool" -gem "rainbow" -gem "addressable" -gem "execjs" - -group :development, :test do - # Call 'byebug' anywhere in the code to stop execution and get a debugger console - gem "awesome_print" - gem "listen" - gem "pry" - gem "pry-byebug" - gem "pry-doc" - gem "pry-rails" - gem "pry-rescue" - gem "pry-stack_explorer" - gem "rubocop", "< 0.69", require: false - gem "ruby-lint", require: false - gem "scss_lint", require: false - -end - -group :test do - gem "capybara" - gem "capybara-screenshot" - gem "coveralls", require: false - # install trouble with updated - # gem "capybara-webkit" - gem "chromedriver-helper" - gem "generator_spec" - gem "launchy" - gem "rspec-rails" - gem "rspec-retry" - gem "selenium-webdriver" - gem 'test-unit', '~> 3.0' - gem "equivalent-xml", github: "mbklein/equivalent-xml" -end diff --git a/README.md b/README.md index ea0d5a895..08b9635e8 100644 --- a/README.md +++ b/README.md @@ -285,7 +285,8 @@ For details on using react_component_hash with react-helmet, see the docs below ## I18n -You can enable the i18n functionality with [react-intl](https://github.com/yahoo/react-intl). React on Rails provides an option for automatic conversions of Rails `*.yml` locale files into `*.js` files for `react-intl`. See the [How to add I18n](docs/basics/i18n.md) for a summary of adding I18n. +React on Rails provides an option for automatic conversions of Rails `*.yml` locale files into `*.json` or `*.js*. +See the [How to add I18n](docs/basics/i18n.md) for a summary of adding I18n. ## More Details diff --git a/docs/basics/configuration.md b/docs/basics/configuration.md index b1f7a1e9a..7124f237a 100644 --- a/docs/basics/configuration.md +++ b/docs/basics/configuration.md @@ -65,52 +65,6 @@ ReactOnRails.configure do |config| # if you don't want react_on_rails building this file for you. config.build_production_command = "RAILS_ENV=production bin/webpack" - ################################################################################ - ################################################################################ - # TEST CONFIGURATION OPTIONS - # Below options are used with the use of this test helper: - # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) - ################################################################################ - - # If you are using this in your spec_helper.rb (or rails_helper.rb): - # - # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) - # - # with rspec then this controls what yarn command is run - # to automatically refresh your webpack assets on every test run. - # - config.build_test_command = "RAILS_ENV=test bin/webpack" - - # Directory where your generated assets go. All generated assets must go to the same directory. - # If you are using webpacker, this value will come from your config/webpacker.yml file. - # This is the default in webpacker.yml: - # public_output_path: packs-test - # which means files in /public/packs-test - # - # Alternately, you may configure this if you are NOT using webpacker. It is relative to your Rails - # root directory. A custom, non-webpacker, config might use something like: - # - # config.generated_assets_dir = File.join(%w[public webpack], Rails.env) - # This setting should not be used if using webpacker. - - # CONFIGURE YOUR SOURCE FILES - # The test helper needs to know where your JavaScript files exist. The default is configured - # by your config/webpacker.yml soure_path: - # source_path: client/app/javascript # if using recommended /client directory - # - # If you are not using webpacker, the `node_modules_location` is assumed to be the location of your source - # files. - - # Define the files we need to check for webpack compilation when running tests. - # The default is `%w( manifest.json )` as will be sufficient for most webpacker builds. - # However, if you are generated a server bundle that is NOT hashed (present in manifest.json), - # then include the file in this list like this: - # - config.webpack_generated_files = %w( server-bundle.js manifest.json ) - - # You can optionally add values to your rails_context. See example below for RenderingExtension - # config.rendering_extension = RenderingExtension - ################################################################################ ################################################################################ # SERVER RENDERING OPTIONS @@ -127,27 +81,35 @@ ReactOnRails.configure do |config| # you should include a name that matches your bundle name in your webpack config. config.server_bundle_js_file = "server-bundle.js" + # THE BELOW OPTIONS FOR SERVER-SIDE RENDERING RARELY NEED CHANGING + # + # This value only affects server-side rendering when using the webpack-dev-server + # If you are hashing the server bundle and you want to use the same bundle for client and server, + # you'd set this to `true` so that React on Rails reads the server bundle from the webpack-dev-server. + # Normally, you have different bundles for client and server, thus, the default is false. + # Furthermore, if you are not hashing the server bundle (not in the manifest.json), then React on Rails + # will only look for the server bundle to be created in the typical file location, typically by + # a `webpack --watch` process. + config.same_bundle_for_client_and_server = false + # If set to true, this forces Rails to reload the server bundle if it is modified # Default value is Rails.env.development? - # + # You probably will never change this. config.development_mode = Rails.env.development? - # For server rendering so that it replays in the browser console. + # For server rendering so that the server-side console replays in the browser console. # This can be set to false so that server side messages are not displayed in the browser. - # Default is true. Be cautious about turning this off. + # Default is true. Be cautious about turning this off, as it can make debugging difficult. # Default value is true - # config.replay_console = true # Default is true. Logs server rendering messages to Rails.logger.info. If false, you'll only # see the server rendering messages in the browser console. - # config.logging_on_server = true # Default is true only for development? to raise exception on server if the JS code throws for # server rendering. The reason is that the server logs will show the error and force you to fix # any server rendering issues immediately during development. - # config.raise_on_prerender_error = Rails.env.development? ################################################################################ @@ -193,8 +155,47 @@ ReactOnRails.configure do |config| ################################################################################ # default is false config.prerender = false -end + # You can optionally add values to your rails_context. This object is passed + # every time a component renders. + # See example below for an example definition of RenderingExtension + # + # config.rendering_extension = RenderingExtension + + ################################################################################ + ################################################################################ + # TEST CONFIGURATION OPTIONS + # Below options are used with the use of this test helper: + # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) + # + # NOTE: + # Instead of using this test helper, you may ensure fresh test files using rails/webpacker via: + # 1. Have `config/webpacker/test.js` exporting an array of objects to configure both client and server bundles. + # 2. Set the compile option to true in config/webpacker.yml for env test + ################################################################################ + + # If you are using this in your spec_helper.rb (or rails_helper.rb): + # + # ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) + # + # with rspec then this controls what yarn command is run + # to automatically refresh your webpack assets on every test run. + # + config.build_test_command = "RAILS_ENV=test bin/webpack" + + # CONFIGURE YOUR SOURCE FILES + # The test helper needs to know where your JavaScript files exist. The value is configured + # by your config/webpacker.yml source_path: + # source_path: client/app/javascript # if using recommended /client directory + # + # Define the files we need to check for webpack compilation when running tests. + # The default is `%w( manifest.json )` as will be sufficient for most webpacker builds. + # However, if you are generated a server bundle that is NOT hashed (present in manifest.json), + # then include the file in this list like this: + config.webpack_generated_files = %w( server-bundle.js manifest.json ) + # Note, be sure NOT to include your server-bundle.js if it is hashed, or else React on Rails will + # think the server-bundle.js is missing every time for test runs. +end ``` Example of a RenderingExtension for custom values in the `rails_context`: diff --git a/docs/basics/i18n.md b/docs/basics/i18n.md index 05fb45c73..330d261ea 100644 --- a/docs/basics/i18n.md +++ b/docs/basics/i18n.md @@ -39,7 +39,8 @@ Here's a summary of adding the I18n functionality. # Generate locales with react-intl support -By default the locales generated in JSON format. If you need to generate files in old-way, you can follow next steps: +By default the locales generated in json format. If you need to generate files in the prior way +with `react-intl` supported via js files: 1. Specify i18n output format in `react_on_rails.rb`: ```rb diff --git a/docs/basics/webpack-configuration.md b/docs/basics/webpack-configuration.md index 654c2d2f9..4f39e1bb6 100644 --- a/docs/basics/webpack-configuration.md +++ b/docs/basics/webpack-configuration.md @@ -23,7 +23,21 @@ The [ShakaCode Team](http://www.shakacode.com) _recommends_ this approach for pr The two best examples of this pattern are the [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) and the integration test example in [spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy). -In this case, you don't need to understand the nuances of customization of your Wepback config via the [Webpacker mechanism](./docs/additional-reading/webpack-tips.md). +In this case, you don't need to understand the nuances of customization of your Webpack config via the [Webpacker mechanism](./docs/additional-reading/webpack-tips.md). + +You can access values in the `config/webpacker.yml` + +```js +const { config, devServer } = require('@rails/webpacker'); +``` + +You will want consider using some of the same values set in these files: + +* https://github.com/rails/webpacker/blob/master/package/environments/base.js +* https://github.com/rails/webpacker/blob/master/package/environments/development.js + +**Note**, if your node_modules directory is not at the top level of the Rails project, then you will need to set the +ENV value of WEBPACKER_CONFIG to the location of the `config/webpacker.yml` file per [rails/webpacker PR 2561](https://github.com/rails/webpacker/pull/2561). ## Option 2: Default Generator Setup: rails/webpacker app/javascript diff --git a/docs/tutorial.md b/docs/tutorial.md index 3d6a5ce5c..c93305244 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -1,3 +1,10 @@ + + +Start work here and work through the tutorial and maybe add a simple configuration for having a different server +rendering file. + + + # React on Rails Basic Tutorial This tutorial guides you through setting up a new or existing Rails app with **React on Rails**, demonstrating Rails + React + Redux + Server Rendering. It is updated to 11.2.1. @@ -17,9 +24,9 @@ By the time you read this, the latest may have changed. Be sure to check the ver _Note: some of the screen images below show the "npm" command. react_on_rails 6.6.0 and greater uses `yarn`._ -## Setting up the environment +## Setting up your environment -Trying out **React on Rails** is super easy, so long as you have the basic prerequisites. This includes the basics for Rails 5.x and node version 6+. I recommend `rvm` and `nvm` to install Ruby and Node, and [brew](https://brew.sh/) to install [yarn](https://yarnpkg.com/en/docs/install#mac-tab). Rails can be installed as an ordinary gem. +Trying out **React on Rails** is super easy, so long as you have the basic prerequisites. This includes the basics for Rails 6.x and node version 13+. I recommend `rvm` and `nvm` to install Ruby and Node, and [brew](https://brew.sh/) to install [yarn](https://yarnpkg.com/en/docs/install#mac-tab). Rails can be installed as an ordinary gem. ``` nvm install node # download and install latest stable Node @@ -28,8 +35,8 @@ nvm list # check brew install yarn # you can use other installer if desired 11\.\d+\.\d+ -rvm install 2.5.0 # download and install latest stable Ruby (update to exact version) -rvm use 2.5.0 --default # use it and make it default +rvm install 2.6 # download and install latest stable Ruby (update to exact version) +rvm use 2.6 --default # use it and make it default rvm list # check gem install rails # download and install latest stable Rails @@ -44,13 +51,13 @@ First be sure to run `rails -v` and check you are using Rails 5.1.3 or above. If cd # any name you like for the rails app -rails new test-react-on-rails --webpack=react +rails new test-react-on-rails --webpack=react --skip-sprockets cd test-react-on-rails bundle ``` -Note: if you are installing React On Rails in an existing app or an app that uses **Rails pre 5.1.3** (*not for Rails > 5.2*), you will need to run these two commands as well: +Note: if you are adding React On Rails to an existing app you will instead to run these two commands as well: ``` bundle exec rails webpacker:install @@ -60,7 +67,7 @@ bundle exec rails webpacker:install:react Add the **React On Rails** gem to your `Gemfile`: ``` -gem 'react_on_rails', '11.2.2' # prefer exact gem version to match npm version +gem 'react_on_rails', '12.0.0' # prefer exact gem version to match npm version ``` Note: Latest released React On Rails version is considered stable. Please use the latest version to ensure you get all the security patches and the best support. @@ -81,7 +88,6 @@ Install React on Rails: `rails generate react_on_rails:install` or `rails genera ``` rails generate react_on_rails:install -bundle && yarn ``` Then run server with static client side files: @@ -96,27 +102,34 @@ foreman start -f Procfile.dev-server ``` Visit [http://localhost:3000/hello_world](http://localhost:3000/hello_world) and see your **React On Rails** app running! -Note, foreman defaults to PORT 5000 unless you set the value of PORT in your environment or in the Procfile. -## Using a pre-release of rails/webpacker -Until `rails/webpacker` v4 ships, or if you ever want to try out the master branch, you can modify the React on Rails tutorial instructions slightly. You can see the sequence of commits here. To summarize: +*Note, foreman may default to PORT 5000 unless you set the value of PORT in your environment or in the Procfile.* + +# HMR vs. React Hot Reloading + +First, check that the `hmr` option is `true` in your `config/webpacker.yml` file. + +The basic setup will have HMR working with the default webpacker setup. However, the basic will cause a full page refresh each time you save a file. + + + + + + + + + + + + + + + + -**Don't run `rails new` with the `--webpack=react` option**. Instead, add the webpacker gem to the Gemfile such that it points to master, like this if `11.2.1` is the version you want. -```ruby -gem 'webpacker', github: "rails/webpacker" -gem 'react_on_rails', '11.2.1' # always use exact version -``` -Then run these commands: -```sh -bundle exec rails webpacker:install -yarn add "rails/webpacker" # because the installer has a bug that puts in an invalid version in your package.json. -bundle exec rails webpacker:install:react -yarn add --dev webpack-dev-server -run rails generate react_on_rails:install && bundle && yarn -``` ### Custom IP & PORT setup (Cloud9 example) @@ -265,6 +278,16 @@ You can turn on server rendering by simply changing the `prerender` option to `t <%= react_component("HelloWorld", props: @hello_world_props, prerender: true) %> ``` +If you want to test this out with HMR, then you also need to add this line to your +`config/intializers/react_on_rails.rb` + +```ruby + config.same_bundle_for_client_and_server = true +``` + +More likely, you will create a different build file for server rendering. However, if you want to +use the same file from the webpack-dev-server, you'll need to add that line. + Then push to Heroku: ``` diff --git a/lib/react_on_rails/configuration.rb b/lib/react_on_rails/configuration.rb index 9a2052683..0b8fd2013 100644 --- a/lib/react_on_rails/configuration.rb +++ b/lib/react_on_rails/configuration.rb @@ -34,6 +34,7 @@ def self.configuration build_test_command: "", build_production_command: "", random_dom_id: DEFAULT_RANDOM_DOM_ID, + same_bundle_for_client_and_server: false, i18n_output_format: nil ) end @@ -47,7 +48,8 @@ class Configuration :webpack_generated_files, :rendering_extension, :build_test_command, :build_production_command, :i18n_dir, :i18n_yml_dir, :i18n_output_format, - :server_render_method, :random_dom_id + :server_render_method, :random_dom_id, + :same_bundle_for_client_and_server def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender: nil, replay_console: nil, @@ -58,10 +60,10 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender generated_assets_dir: nil, webpack_generated_files: nil, rendering_extension: nil, build_test_command: nil, build_production_command: nil, - i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil, random_dom_id: nil, - server_render_method: nil) + same_bundle_for_client_and_server: nil, + i18n_dir: nil, i18n_yml_dir: nil, i18n_output_format: nil, + random_dom_id: nil, server_render_method: nil) self.node_modules_location = node_modules_location.present? ? node_modules_location : Rails.root - self.server_bundle_js_file = server_bundle_js_file self.generated_assets_dirs = generated_assets_dirs self.generated_assets_dir = generated_assets_dir self.build_test_command = build_test_command @@ -84,6 +86,8 @@ def initialize(node_modules_location: nil, server_bundle_js_file: nil, prerender self.skip_display_none = skip_display_none # Server rendering: + self.server_bundle_js_file = server_bundle_js_file + self.same_bundle_for_client_and_server = same_bundle_for_client_and_server self.server_renderer_pool_size = self.development_mode ? 1 : server_renderer_pool_size self.server_renderer_timeout = server_renderer_timeout # seconds @@ -99,7 +103,6 @@ def setup_config_values configure_generated_assets_dirs_deprecation configure_skip_display_none_deprecation ensure_generated_assets_dir_present - ensure_server_bundle_js_file_has_no_path check_i18n_directory_exists check_i18n_yml_directory_exists check_server_render_method_is_only_execjs @@ -198,24 +201,12 @@ def configure_generated_assets_dirs_deprecation def ensure_webpack_generated_files_exists return unless webpack_generated_files.empty? - files = ["hello-world-bundle.js"] + files = ["manifest.json"] files << server_bundle_js_file if server_bundle_js_file.present? self.webpack_generated_files = files end - def ensure_server_bundle_js_file_has_no_path - return unless server_bundle_js_file.include?(File::SEPARATOR) - - assets_dir = ReactOnRails::Utils.generated_assets_full_path - self.server_bundle_js_file = File.basename(server_bundle_js_file) - - Rails.logger.warn do - "[DEPRECATION] ReactOnRails: remove path from server_bundle_js_file in configuration. "\ - "All generated files must go in #{assets_dir}. Using file basename #{server_bundle_js_file}" - end - end - def configure_skip_display_none_deprecation return if skip_display_none.nil? diff --git a/lib/react_on_rails/test_helper/ensure_assets_compiled.rb b/lib/react_on_rails/test_helper/ensure_assets_compiled.rb index 9739f24d3..4f3bcbdd7 100644 --- a/lib/react_on_rails/test_helper/ensure_assets_compiled.rb +++ b/lib/react_on_rails/test_helper/ensure_assets_compiled.rb @@ -5,6 +5,7 @@ module TestHelper class EnsureAssetsCompiled class << self attr_accessor :has_been_run + @has_been_run = false end diff --git a/lib/react_on_rails/version_checker.rb b/lib/react_on_rails/version_checker.rb index 8db5fbbca..eda8fa066 100644 --- a/lib/react_on_rails/version_checker.rb +++ b/lib/react_on_rails/version_checker.rb @@ -5,6 +5,7 @@ module ReactOnRails # against each otherat runtime. class VersionChecker attr_reader :node_package_version + MAJOR_MINOR_PATCH_VERSION_REGEX = /(\d+)\.(\d+)\.(\d+)/.freeze def self.build diff --git a/lib/react_on_rails/webpacker_utils.rb b/lib/react_on_rails/webpacker_utils.rb index 556e4eba8..241354b24 100644 --- a/lib/react_on_rails/webpacker_utils.rb +++ b/lib/react_on_rails/webpacker_utils.rb @@ -12,7 +12,9 @@ def self.dev_server_running? Webpacker.dev_server.running? end - # This returns either a URL for the webpack-dev-server or a file path + # This returns either a URL for the webpack-dev-server, non-server bundle or + # the hashed server bundle if using the same bundle for the client. + # Otherwise returns 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") @@ -20,11 +22,14 @@ def self.bundle_js_uri_from_webpacker(bundle_name) # Next line will throw if the file or manifest does not exist hashed_bundle_name = Webpacker.manifest.lookup!(bundle_name) - # If someday we add support for hashing the server-bundle and having that built + # support for hashing the server-bundle and having that built # by a webpack watch process and not served by the webpack-dev-server, then we - # need to add an extra config value "same_bundle_for_client_and_server" where a value of false + # need an extra config value "same_bundle_for_client_and_server" where a value of false # would mean that the bundle is created by a separate webpack watch process. - if Webpacker.dev_server.running? + is_server_bundle = bundle_name == ReactOnRails.configuration.server_bundle_js_file + + if Webpacker.dev_server.running? && (!is_server_bundle || + ReactOnRails.configuration.same_bundle_for_client_and_server) "#{Webpacker.dev_server.protocol}://#{Webpacker.dev_server.host_with_port}#{hashed_bundle_name}" else File.expand_path(File.join("public", hashed_bundle_name)).to_s diff --git a/rakelib/example_type.rb b/rakelib/example_type.rb index 1639882a9..978366090 100644 --- a/rakelib/example_type.rb +++ b/rakelib/example_type.rb @@ -50,6 +50,7 @@ def required_gems # Options we pass when running `rails new` from the command-line. attr_writer :rails_options + def rails_options @rails_options ||= "--skip-bundle --skip-spring --skip-git --skip-test-unit --skip-active-record" end diff --git a/react_on_rails.gemspec b/react_on_rails.gemspec index bd840329a..a16e170b8 100644 --- a/react_on_rails.gemspec +++ b/react_on_rails.gemspec @@ -41,14 +41,12 @@ Gem::Specification.new do |s| s.add_development_dependency "pry-byebug" s.add_development_dependency "pry-doc" s.add_development_dependency "pry-rescue" - s.add_development_dependency "pry-stack_explorer" s.add_development_dependency "pry-state" - s.add_development_dependency "pry-toys" s.add_development_dependency "rails", "~> 5.2" s.add_development_dependency "rake", "~> 10.0" s.add_development_dependency "rspec" - s.add_development_dependency "rubocop", "~> 0.79.0" + s.add_development_dependency "rubocop" s.post_install_message = ' -------------------------------------------------------------------------------- diff --git a/spec/dummy/Gemfile b/spec/dummy/Gemfile index 797694083..934976f0d 100644 --- a/spec/dummy/Gemfile +++ b/spec/dummy/Gemfile @@ -56,7 +56,6 @@ group :development, :test do gem "pry-doc" gem "pry-rails" gem "pry-rescue" - gem "pry-stack_explorer" gem "rubocop", require: false gem "ruby-lint", require: false gem "scss_lint", require: false diff --git a/spec/dummy/Gemfile.lock b/spec/dummy/Gemfile.lock index e9ea357df..485a30335 100644 --- a/spec/dummy/Gemfile.lock +++ b/spec/dummy/Gemfile.lock @@ -17,72 +17,70 @@ PATH GEM remote: https://rubygems.org/ specs: - actioncable (6.0.2.2) - actionpack (= 6.0.2.2) + actioncable (6.0.3) + actionpack (= 6.0.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.2.2) - actionpack (= 6.0.2.2) - activejob (= 6.0.2.2) - activerecord (= 6.0.2.2) - activestorage (= 6.0.2.2) - activesupport (= 6.0.2.2) + actionmailbox (6.0.3) + actionpack (= 6.0.3) + activejob (= 6.0.3) + activerecord (= 6.0.3) + activestorage (= 6.0.3) + activesupport (= 6.0.3) mail (>= 2.7.1) - actionmailer (6.0.2.2) - actionpack (= 6.0.2.2) - actionview (= 6.0.2.2) - activejob (= 6.0.2.2) + actionmailer (6.0.3) + actionpack (= 6.0.3) + actionview (= 6.0.3) + activejob (= 6.0.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.2.2) - actionview (= 6.0.2.2) - activesupport (= 6.0.2.2) + actionpack (6.0.3) + actionview (= 6.0.3) + activesupport (= 6.0.3) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.2.2) - actionpack (= 6.0.2.2) - activerecord (= 6.0.2.2) - activestorage (= 6.0.2.2) - activesupport (= 6.0.2.2) + actiontext (6.0.3) + actionpack (= 6.0.3) + activerecord (= 6.0.3) + activestorage (= 6.0.3) + activesupport (= 6.0.3) nokogiri (>= 1.8.5) - actionview (6.0.2.2) - activesupport (= 6.0.2.2) + actionview (6.0.3) + activesupport (= 6.0.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.0.2.2) - activesupport (= 6.0.2.2) + activejob (6.0.3) + activesupport (= 6.0.3) globalid (>= 0.3.6) - activemodel (6.0.2.2) - activesupport (= 6.0.2.2) - activerecord (6.0.2.2) - activemodel (= 6.0.2.2) - activesupport (= 6.0.2.2) - activestorage (6.0.2.2) - actionpack (= 6.0.2.2) - activejob (= 6.0.2.2) - activerecord (= 6.0.2.2) + activemodel (6.0.3) + activesupport (= 6.0.3) + activerecord (6.0.3) + activemodel (= 6.0.3) + activesupport (= 6.0.3) + activestorage (6.0.3) + actionpack (= 6.0.3) + activejob (= 6.0.3) + activerecord (= 6.0.3) marcel (~> 0.3.1) - activesupport (6.0.2.2) + activesupport (6.0.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - zeitwerk (~> 2.2) + zeitwerk (~> 2.2, >= 2.2.2) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) ast (2.4.0) awesome_print (1.8.0) - binding_of_caller (0.8.0) - debug_inspector (>= 0.0.1) bootsnap (1.4.6) msgpack (~> 1.0) builder (3.2.4) - byebug (11.1.1) - capybara (3.31.0) + byebug (11.1.3) + capybara (3.32.2) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) @@ -111,7 +109,6 @@ GEM thor (>= 0.19.4, < 2.0) tins (~> 1.6) crass (1.0.6) - debug_inspector (0.0.3) diff-lcs (1.3) docile (1.3.2) erubi (1.9.0) @@ -125,10 +122,9 @@ GEM i18n (1.8.2) concurrent-ruby (~> 1.0) interception (0.5) - jaro_winkler (1.5.4) jbuilder (2.10.0) activesupport (>= 5.0.0) - jquery-rails (4.3.5) + jquery-rails (4.4.0) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) @@ -147,26 +143,26 @@ GEM marcel (0.3.3) mimemagic (~> 0.3.2) method_source (1.0.0) - mimemagic (0.3.4) + mimemagic (0.3.5) mini_mime (1.0.2) mini_portile2 (2.4.0) - mini_racer (0.2.9) - libv8 (>= 6.9.411) - minitest (5.14.0) + mini_racer (0.2.14) + libv8 (> 7.3) + minitest (5.14.1) msgpack (1.3.3) nio4r (2.5.2) nokogiri (1.10.9) mini_portile2 (~> 2.4.0) parallel (1.19.1) - parser (2.7.0.5) + parser (2.7.1.2) ast (~> 2.4.0) - pry (0.13.0) + pry (0.13.1) coderay (~> 1.1) method_source (~> 1.0) pry-byebug (3.9.0) byebug (~> 11.0) pry (~> 0.13.0) - pry-doc (1.0.0) + pry-doc (1.1.0) pry (~> 0.11) yard (~> 0.9.11) pry-rails (0.3.9) @@ -174,10 +170,7 @@ GEM pry-rescue (1.5.0) interception (>= 0.5) pry (>= 0.12.0) - pry-stack_explorer (0.4.9.3) - binding_of_caller (>= 0.7) - pry (>= 0.9.11) - public_suffix (4.0.3) + public_suffix (4.0.5) puma (4.3.3) nio4r (~> 2.0) rack (2.2.2) @@ -185,49 +178,49 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.0.2.2) - actioncable (= 6.0.2.2) - actionmailbox (= 6.0.2.2) - actionmailer (= 6.0.2.2) - actionpack (= 6.0.2.2) - actiontext (= 6.0.2.2) - actionview (= 6.0.2.2) - activejob (= 6.0.2.2) - activemodel (= 6.0.2.2) - activerecord (= 6.0.2.2) - activestorage (= 6.0.2.2) - activesupport (= 6.0.2.2) + rails (6.0.3) + actioncable (= 6.0.3) + actionmailbox (= 6.0.3) + actionmailer (= 6.0.3) + actionpack (= 6.0.3) + actiontext (= 6.0.3) + actionview (= 6.0.3) + activejob (= 6.0.3) + activemodel (= 6.0.3) + activerecord (= 6.0.3) + activestorage (= 6.0.3) + activesupport (= 6.0.3) bundler (>= 1.3.0) - railties (= 6.0.2.2) + railties (= 6.0.3) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - railties (6.0.2.2) - actionpack (= 6.0.2.2) - activesupport (= 6.0.2.2) + railties (6.0.3) + actionpack (= 6.0.3) + activesupport (= 6.0.3) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) rainbow (3.0.0) rake (13.0.1) - rb-fsevent (0.10.3) + rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) rdoc (6.2.1) regexp_parser (1.7.0) rexml (3.2.4) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) - rspec-expectations (3.9.1) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) - rspec-rails (4.0.0) + rspec-rails (4.0.1) actionpack (>= 4.2) activesupport (>= 4.2) railties (>= 4.2) @@ -237,17 +230,16 @@ GEM rspec-support (~> 3.9) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.9.2) + rspec-support (3.9.3) rspec_junit_formatter (0.4.1) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.80.1) - jaro_winkler (~> 1.5.1) + rubocop (0.83.0) parallel (~> 1.10) parser (>= 2.7.0.1) rainbow (>= 2.2.2, < 4.0) rexml ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) + unicode-display_width (>= 1.4.0, < 2.0) ruby-lint (2.3.1) parser (~> 2.2) slop (~> 3.4, >= 3.4.7) @@ -260,7 +252,7 @@ GEM rb-inotify (~> 0.9, >= 0.9.7) sass-rails (6.0.0) sassc-rails (~> 2.1, >= 2.1.1) - sassc (2.2.1) + sassc (2.3.0) ffi (~> 1.9) sassc-rails (2.1.2) railties (>= 4.0.0) @@ -297,7 +289,7 @@ GEM thor (1.0.1) thread_safe (0.3.6) tilt (2.0.10) - tins (1.24.1) + tins (1.25.0) sync turbolinks (5.2.1) turbolinks-source (~> 5.2) @@ -306,12 +298,12 @@ GEM thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) - unicode-display_width (1.6.1) + unicode-display_width (1.7.0) webdrivers (3.9.4) nokogiri (~> 1.6) rubyzip (~> 1.0) selenium-webdriver (~> 3.0) - webpacker (5.0.1) + webpacker (5.1.1) activesupport (>= 5.2) rack-proxy (>= 0.6.1) railties (>= 5.2) @@ -321,7 +313,7 @@ GEM websocket-extensions (0.1.4) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.24) + yard (0.9.25) zeitwerk (2.3.0) PLATFORMS @@ -346,7 +338,6 @@ DEPENDENCIES pry-doc pry-rails pry-rescue - pry-stack_explorer puma rails react_on_rails! diff --git a/spec/dummy/spec/spec_helper.rb b/spec/dummy/spec/spec_helper.rb index 847820a44..c69e7452c 100644 --- a/spec/dummy/spec/spec_helper.rb +++ b/spec/dummy/spec/spec_helper.rb @@ -20,8 +20,6 @@ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration require "pry" require "pry-byebug" -require "pry-stack_explorer" -require "pry-doc" RSpec.configure do |config| config.example_status_persistence_file_path = "spec/examples.txt" diff --git a/spec/react_on_rails/spec_helper.rb b/spec/react_on_rails/spec_helper.rb index 8c7555479..57ea19e8f 100644 --- a/spec/react_on_rails/spec_helper.rb +++ b/spec/react_on_rails/spec_helper.rb @@ -9,15 +9,14 @@ require "awesome_print" require "pry" require "pry-byebug" -require "pry-stack_explorer" require "pry-doc" # Fails travis # require "pry-state" # require "pry-toys" # require "pry-rescue" +# require "binding_of_caller" -require "binding_of_caller" require "awesome_print" require "rspec/retry" diff --git a/spec/react_on_rails/test_helper/webpack_assets_compiler_spec.rb b/spec/react_on_rails/test_helper/webpack_assets_compiler_spec.rb index cf7123b1d..d3d47fbb3 100644 --- a/spec/react_on_rails/test_helper/webpack_assets_compiler_spec.rb +++ b/spec/react_on_rails/test_helper/webpack_assets_compiler_spec.rb @@ -32,7 +32,7 @@ expect do ReactOnRails::TestHelper::WebpackAssetsCompiler.new.compile_assets - rescue SystemExit # rubocop:disable Lint/SuppressedException + rescue SystemExit # No op end.to output(/#{expected_output}/).to_stdout end diff --git a/spec/react_on_rails/utils_spec.rb b/spec/react_on_rails/utils_spec.rb index 98ef7451b..c5173bd5c 100644 --- a/spec/react_on_rails/utils_spec.rb +++ b/spec/react_on_rails/utils_spec.rb @@ -41,6 +41,8 @@ module ReactOnRails allow(Webpacker).to receive_message_chain("manifest.lookup!") .with("webpack-bundle.js") .and_return("/webpack/dev/webpack-bundle-0123456789abcdef.js") + allow(ReactOnRails).to receive_message_chain("configuration.server_bundle_js_file") + .and_return("server-bundle.js") end it { expect(subject).to eq("#{webpacker_public_output_path}/webpack-bundle-0123456789abcdef.js") } @@ -125,17 +127,61 @@ module ReactOnRails end end - context "With Webpacker enabled and server file in the manifest", :webpacker do + context "With Webpacker enabled and server file in the manifest, used for client", :webpacker do it "returns the correct path hashed server path" do allow(ReactOnRails).to receive_message_chain("configuration.server_bundle_js_file") .and_return("webpack-bundle.js") + allow(ReactOnRails).to receive_message_chain("configuration.same_bundle_for_client_and_server") + .and_return(true) allow(Webpacker).to receive_message_chain("manifest.lookup!") .with("webpack-bundle.js") .and_return("webpack/development/webpack-bundle-123456.js") path = Utils.server_bundle_js_file_path - expect(path).to end_with("public/webpack/development/webpack-bundle-123456.js") + expect(path).to start_with("/") + end + end + + context "With Webpacker enabled and server file in the manifest, used for client, "\ + " and webpack-dev-server running, and same file used for server and client", :webpacker do + it "returns the correct path hashed server path" do + allow(ReactOnRails).to receive_message_chain("configuration.server_bundle_js_file") + .and_return("webpack-bundle.js") + allow(ReactOnRails).to receive_message_chain("configuration.same_bundle_for_client_and_server") + .and_return(true) + allow(Webpacker).to receive_message_chain("dev_server.running?") + .and_return(true) + allow(Webpacker).to receive_message_chain("dev_server.protocol") + .and_return("http") + allow(Webpacker).to receive_message_chain("dev_server.host_with_port") + .and_return("localhost:3035") + allow(Webpacker).to receive_message_chain("manifest.lookup!") + .with("webpack-bundle.js") + .and_return("/webpack/development/webpack-bundle-123456.js") + + path = Utils.server_bundle_js_file_path + + expect(path).to eq("http://localhost:3035/webpack/development/webpack-bundle-123456.js") + end + end + + context "With Webpacker enabled, dev-server running, and server file in the manifest, and "\ + " separate client/server files", :webpacker do + it "returns the correct path hashed server path" do + allow(ReactOnRails).to receive_message_chain("configuration.server_bundle_js_file") + .and_return("server-bundle.js") + allow(ReactOnRails).to receive_message_chain("configuration.same_bundle_for_client_and_server") + .and_return(false) + allow(Webpacker).to receive_message_chain("manifest.lookup!") + .with("server-bundle.js") + .and_return("webpack/development/server-bundle-123456.js") + allow(Webpacker).to receive_message_chain("dev_server.running?") + .and_return(true) + + path = Utils.server_bundle_js_file_path + + expect(path).to end_with("/public/webpack/development/server-bundle-123456.js") end end end