diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e22faee4db..3c0489f78d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -79,7 +79,7 @@ jobs: run: cd spec/dummy && rm -rf public/webpack/test && yarn run build:rescript && RAILS_ENV="test" NODE_ENV="test" bin/${{ matrix.versions == 'oldest' && 'web' || 'shaka' }}packer - id: get-sha run: echo "sha=\"$(git rev-parse HEAD)\"" >> "$GITHUB_OUTPUT" - - name: Save test webpack bundles to cache (for build number checksum used by rspec job) + - name: Save test Webpack bundles to cache (for build number checksum used by RSpec job) uses: actions/cache/save@v4 with: path: spec/dummy/public/webpack @@ -139,7 +139,7 @@ jobs: key: dummy-app-node-modules-cache-${{ hashFiles('spec/dummy/package.json') }}-${{ matrix.versions }} - id: get-sha run: echo "sha=\"$(git rev-parse HEAD)\"" >> "$GITHUB_OUTPUT" - - name: Save test webpack bundles to cache (for build number checksum used by rspec job) + - name: Save test Webpack bundles to cache (for build number checksum used by RSpec job) uses: actions/cache@v4 with: path: spec/dummy/public/webpack diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bd29c6b5e..e6374f2b68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,7 +55,7 @@ See [Release Notes](docs/release-notes/15.0.0.md) for full details. #### Fixed -- Separated streamServerRenderedReactComponent from the ReactOnRails object in order to stop users from getting errors during webpack compilation about needing the `stream-browserify` package. [PR 1680](https://github.com/shakacode/react_on_rails/pull/1680) by [judahmeek](https://github.com/judahmeek). +- Separated streamServerRenderedReactComponent from the ReactOnRails object in order to stop users from getting errors during Webpack compilation about needing the `stream-browserify` package. [PR 1680](https://github.com/shakacode/react_on_rails/pull/1680) by [judahmeek](https://github.com/judahmeek). - Removed obsolete `js-yaml` peer dependency. [PR 1678](https://github.com/shakacode/react_on_rails/pull/1678) by [alexeyr-ci](https://github.com/alexeyr-ci). ### [14.1.0] - 2025-01-06 @@ -163,7 +163,7 @@ _Major bump because dropping support for Ruby 2.7 and deprecated `webpackConfigL #### Fixed -- Fixed race condition where a react component could attempt to initialize before it had been registered. [PR 1540](https://github.com/shakacode/react_on_rails/pull/1540) by [judahmeek](https://github.com/judahmeek). +- Fixed race condition where a React component could attempt to initialize before it had been registered. [PR 1540](https://github.com/shakacode/react_on_rails/pull/1540) by [judahmeek](https://github.com/judahmeek). ### [13.3.4] - 2023-05-23 @@ -202,7 +202,7 @@ _Major bump because dropping support for Ruby 2.7 and deprecated `webpackConfigL #### Fixed - Fixed pack not found warning while using `react_component` and `react_component_hash` helpers, even when corresponding chunks are present. [PR 1511](https://github.com/shakacode/react_on_rails/pull/1511) by [pulkitkkr](https://github.com/pulkitkkr). -- Fixed FS-based packs generation functionality to trigger pack generation on the creation of a new react component inside `components_subdirectory`. [PR 1506](https://github.com/shakacode/react_on_rails/pull/1506) by [pulkitkkr](https://github.com/pulkitkkr). +- Fixed FS-based packs generation functionality to trigger pack generation on the creation of a new React component inside `components_subdirectory`. [PR 1506](https://github.com/shakacode/react_on_rails/pull/1506) by [pulkitkkr](https://github.com/pulkitkkr). - Upgrade several JS dependencies to fix security issues. [PR 1514](https://github.com/shakacode/react_on_rails/pull/1514) by [ahangarha](https://github.com/ahangarha). #### Added @@ -297,12 +297,12 @@ _Major bump because dropping support for Ruby 2.7 and deprecated `webpackConfigL #### Added - Support for React 18, including the changed SSR API. [PR 1409](https://github.com/shakacode/react_on_rails/pull/1409) by [kylemellander](https://github.com/kylemellander). -- Added webpack configuration files as part of the generator and updated webpacker to version 6. [PR 1404](https://github.com/shakacode/react_on_rails/pull/1404) by [gscarv13](https://github.com/gscarv13). +- Added Webpack configuration files as part of the generator and updated webpacker to version 6. [PR 1404](https://github.com/shakacode/react_on_rails/pull/1404) by [gscarv13](https://github.com/gscarv13). - Supports Rails 7. #### Changed -- Changed logic of determining the usage of the default rails/webpacker webpack config or a custom command to only check if the config.build_production_command is defined. [PR 1402](https://github.com/shakacode/react_on_rails/pull/1402) by [justin808](https://github.com/justin808) and [gscarv13](https://github.com/gscarv13). +- Changed logic of determining the usage of the default rails/webpacker Webpack config or a custom command to only check if the config.build_production_command is defined. [PR 1402](https://github.com/shakacode/react_on_rails/pull/1402) by [justin808](https://github.com/justin808) and [gscarv13](https://github.com/gscarv13). - Minimum required Ruby is 2.7 to match latest rails/webpacker. ### [12.4.0] - 2021-09-22 @@ -328,7 +328,7 @@ _Major bump because dropping support for Ruby 2.7 and deprecated `webpackConfigL #### Added -- Ability to configure server react rendering to throw rather than just logging the error. Useful for +- Ability to configure server React rendering to throw rather than just logging the error. Useful for React on Rails Pro Node rendering [PR 1365](https://github.com/shakacode/react_on_rails/pull/1365) by [justin808](https://github.com/justin808). ### [12.1.0] - 2021-03-23 @@ -394,12 +394,12 @@ for details. #### Other Updates -- `react_on_rails` fully supports `rails/webpacker`. The example test app in `spec/dummy` was recently converted over to use rails/webpacker v4+. It's a good example of how to leverage rails/webpacker's webpack configuration for server-side rendering. +- `react_on_rails` fully supports `rails/webpacker`. The example test app in `spec/dummy` was recently converted over to use rails/webpacker v4+. It's a good example of how to leverage rails/webpacker's Webpack configuration for server-side rendering. - Changed the precompile task to use the rails/webpacker one by default - Updated generators to use React hooks - Requires the use of rails/webpacker view helpers -- If the webpacker webpack config files exist, then React on Rails will not override the default - assets:precompile setup by rails/webpacker. If you are not using the rails/webpacker setup for webpack, +- If the webpacker Webpack config files exist, then React on Rails will not override the default + assets:precompile set up by rails/webpacker. If you are not using the rails/webpacker setup for Webpack, then be sure to remove the JS files inside of config/webpack, like `config/webpack/production.js.` - Removed **env_javascript_include_tag** and **env_stylesheet_link_tag** as these are replaced by view helpers from rails/webpacker @@ -424,8 +424,8 @@ for details. [PR 1271](https://github.com/shakacode/react_on_rails/pull/1271) by [ashgaliyev](https://github.com/ashgaliyev). -* Added Typescript definitions to the Node package. By [justin808](https://github.com/justin808) and [judahmeek](https://github.com/judahmeek) in [PR 1287](https://github.com/shakacode/react_on_rails/pull/1287). -* Removed 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). +- Added Typescript definitions to the Node package. By [justin808](https://github.com/justin808) and [judahmeek](https://github.com/judahmeek) in [PR 1287](https://github.com/shakacode/react_on_rails/pull/1287). +- Removed 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 @@ -674,7 +674,7 @@ Do not use. Unpublished. Caused by an issue with the release script. #### Fixed -- Use redux component in generated redux Hello World example: [PR 1006](https://github.com/shakacode/react_on_rails/pull/1006) by [lewaabahmad](https://github.com/lewaabahmad). +- Use Redux component in the generated Redux Hello World example: [PR 1006](https://github.com/shakacode/react_on_rails/pull/1006) by [lewaabahmad](https://github.com/lewaabahmad). - Fixed `Utils.bundle_js_file_path` generating the incorrect path for `manifest.json` in webpacker projects: [Issue #1011](https://github.com/shakacode/react_on_rails/issues/1011) by [elstgav](https://github.com/elstgav) ### [10.0.2] - 2017-11-10 @@ -742,7 +742,7 @@ Moved to [our documentation](https://www.shakacode.com/react-on-rails/docs/guide #### Fixed - Fixes server rendering when using a CDN. Server rendering would try to fetch a file with the "asset_host". This change updates the webpacker_lite dependency to 2.1.0 which has a new helper `pack_path`. [#901](https://github.com/shakacode/react_on_rails/pull/901) by [justin808](https://github.com/justin808). Be sure to update webpacker_lite to 2.1.0. -- The package.json file created by the generator now creates minified javascript production builds by default. This was done by adding the -p flag to webpack on the build:production script. [#895](https://github.com/shakacode/react_on_rails/pull/895) by [serodriguez68 ](https://github.com/serodriguez68) +- The package.json file created by the generator now creates minified javascript production builds by default. This was done by adding the -p flag to Webpack on the build:production script. [#895](https://github.com/shakacode/react_on_rails/pull/895) by [serodriguez68 ](https://github.com/serodriguez68) - Fixes GitUtils.uncommitted_changes? throwing an error when called in an environment without Git, and allows install generator to be run successfully with `--ignore-warnings` [#878](https://github.com/shakacode/react_on_rails/pull/878) by [jasonblalock](https://github.com/jasonblalock). ## [8.0.5] - 2017-07-04 @@ -1008,7 +1008,7 @@ No changes. #### Fixed -- The redux generator now creates a HelloWorld component that uses redux rather than local state. [#669](https://github.com/shakacode/react_on_rails/issues/669) by [justin808](https://github.com/justin808). +- The Redux generator now creates a HelloWorld component that uses redux rather than local state. [#669](https://github.com/shakacode/react_on_rails/issues/669) by [justin808](https://github.com/justin808). ## [6.3.4] - 2016-12-25 @@ -1059,7 +1059,7 @@ No changes. ##### Changed -- Updated the generator templates to reflect current best practices, especially for the redux version. [#584](https://github.com/shakacode/react_on_rails/pull/584) by [nostophilia](https://github.com/nostophilia). +- Updated the generator templates to reflect current best practices, especially for the Redux version. [#584](https://github.com/shakacode/react_on_rails/pull/584) by [nostophilia](https://github.com/nostophilia). ## [6.1.2] - 2016-10-24 @@ -1092,13 +1092,13 @@ No changes. ##### Added -- Added better error messages to avoid issues with shared redux stores [#470](https://github.com/shakacode/react_on_rails/pull/470) by [justin808](https://github.com/justin808). +- Added better error messages to avoid issues with shared Redux stores [#470](https://github.com/shakacode/react_on_rails/pull/470) by [justin808](https://github.com/justin808). ## [6.0.4] - 2016-06-13 ##### Fixed -- Added polyfill for clearTimeout which is used by babel-polyfill [#451](https://github.com/shakacode/react_on_rails/pull/451) by [martyphee](https://github.com/martyphee) +- Added a polyfill for `clearTimeout` which is used by `babel-polyfill` [#451](https://github.com/shakacode/react_on_rails/pull/451) by [martyphee](https://github.com/martyphee) ## [6.0.3] - 2016-06-07 @@ -1224,11 +1224,11 @@ All 5.1.0 changes can be found in [#362](https://github.com/shakacode/react_on_r ##### Added -- Added `railsContext`, an object which gets passed always as the second parameter to both react component and redux store generator functions, both for server and client rendering. This provides data like the current locale, the pathname, etc. The data values are customizable by a new configuration called `rendering_extension` where you can create a module with a method called `rendering_extension`. This allows you to add additional values to the Rails Context. Implement one static method called `custom_context(view_context)` and return a Hash. See [#345](https://github.com/shakacode/react_on_rails/pull/345) by [justin808](https://github.com/justin808) +- Added `railsContext`, an object which gets passed always as the second parameter to both React component and Redux store generator functions, both for server and client rendering. This provides data like the current locale, the pathname, etc. The data values are customizable by a new configuration called `rendering_extension` where you can create a module with a method called `rendering_extension`. This allows you to add additional values to the Rails Context. Implement one static method called `custom_context(view_context)` and return a Hash. See [#345](https://github.com/shakacode/react_on_rails/pull/345) by [justin808](https://github.com/justin808) ##### Changed -- Previously, you could pass arbitrary additional html attributes to react_component. Now, you need to pass them in as a named parameter `html_options` to react_component. +- Previously, you could pass arbitrary additional HTML attributes to react_component. Now, you need to pass them in as a named parameter `html_options` to react_component. ##### Breaking Changes @@ -1259,7 +1259,7 @@ All 5.1.0 changes can be found in [#362](https://github.com/shakacode/react_on_r - [spec/dummy](spec/dummy) is a full sample app of React on Rails techniques **including** the hot reloading of assets from Rails! - Added helpers `env_stylesheet_link_tag` and `env_javascript_include_tag` to support hot reloading Rails. See the [README.md](./README.md) for more details and see the example application in `spec/dummy`. Also see how this is used in the [tutorial: application.html.erb](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/app%2Fviews%2Flayouts%2Fapplication.html.erb#L6) - Added optional parameter for ReactOnRails.getStore(name, throwIfMissing = true) so that you can check if a store is defined easily. -- Added controller `module ReactOnRails::Controller`. Adds method `redux_store` to setup redux stores in the view. +- Added controller `module ReactOnRails::Controller`. Adds method `redux_store` to set up Redux stores in the view. - Added option `defer: true` for view helper `redux_store`. This allows the view helper to specify the props for store hydration, yet still render the props at the bottom of the view. - Added view helper `redux_store_hydration_data` to render the props on the application's layout, near the bottom. This allows for the client hydration data to be parsed after the server rendering, which may result in a faster load time. - The checker for outdated bundles before running tests will two configuration options: `generated_assets_dir` and `webpack_generated_files`. @@ -1354,7 +1354,7 @@ All 5.1.0 changes can be found in [#362](https://github.com/shakacode/react_on_r You'll get a deprecation message to change this. - Renamed `ReactOnRails.configure_rspec_to_compile_assets` to `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`. The code has also been optimized to check for whether or not the compiled webpack bundles are up to date or not and will not run if not necessary. If you are using non-standard directories for your generated webpack assets (`app/assets/javascripts/generated` and `app/assets/stylesheets/generated`) or have additional directories you wish the helper to check, you need to update your ReactOnRails configuration accordingly. See [documentation](https://www.shakacode.com/react-on-rails/docs/guides/rspec_configuration) for how to do this. [#253](https://github.com/shakacode/react_on_rails/pull/253). -- You have to call `ReactOnRails.register` to register react components. This was deprecated in v2. [#273](https://github.com/shakacode/react_on_rails/pull/273). +- You have to call `ReactOnRails.register` to register React components. This was deprecated in v2. [#273](https://github.com/shakacode/react_on_rails/pull/273). ##### Migration Steps v2 to v3 @@ -1469,9 +1469,9 @@ such as: ``` - All npm dependency libraries updated. Most notable is going to Babel 6. -- Dropped support for react 0.13. +- Dropped support for React 0.13. - JS Linter uses ShakaCode JavaScript style: https://github.com/shakacode/style-guide-javascript -- Generators account these differences. +- Generators account for these differences. ##### Migration Steps v1 to v2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 292364e0c2..6a78f0a0f9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ - [docs/contributor-info/pull-requests](./docs/contributor-info/pull-requests.md) - See other docs in [docs/contributor-info](./docs/contributor-info) -## To run tests: +## Prerequisites - [Yalc](https://github.com/whitecolor/yalc) must be installed globally for most local development. - After updating code via Git, to prepare all examples: @@ -19,7 +19,7 @@ and [Running tests](#running-tests) for more details on running tests. # IDE/IDE SETUP -It's critical to configure your IDE/editor to ignore certain directories. Otherwise your IDE might slow to a crawl! +It's critical to configure your IDE/editor to ignore certain directories. Otherwise, your IDE might slow to a crawl! - /coverage - /tmp @@ -37,7 +37,7 @@ It's critical to configure your IDE/editor to ignore certain directories. Otherw You can test the `react-on-rails` gem using your own external test app or the gem's internal `spec/dummy` app. The `spec/dummy` app is an example of the various setup techniques you can use with the gem. -``` +```text ├── test_app | └── client └── react_on_rails @@ -55,9 +55,9 @@ gem "react_on_rails", path: "../path-to-react-on-rails" Note that you will need to bundle install after making this change, but also that **you will need to restart your Rails application if you make any changes to the gem**. -## Testing the Node package for react-on-rails via Yalc +## Testing the Node package for React on Rails via Yalc -In addition to testing the Ruby parts out, you can also test the node package parts of the gem with an external application. First, be **sure** to build the NPM package: +In addition to testing the Ruby parts out, you can also test the Node package parts of the gem with an external application. First, be **sure** to build the NPM package: ```sh cd react_on_rails/ @@ -112,13 +112,13 @@ Don't forget you may need to run yarn after adding packages with yalc to install ### Prereqs -After checking out the repo, making sure you have rvm and nvm setup (setup ruby and node), cd to `spec/dummy` and run `bin/setup` to install ruby dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment. +After checking out the repo, making sure you have Ruby and Node version managers set up (such as rvm and nvm, or rbenv and nodenv, etc.), cd to `spec/dummy` and run `bin/setup` to install ruby dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment. ### Local Node Package -Note, the example and dummy apps will use your local node_package folder as the react-on-rails node package. This will also be done automatically for you via the `rake examples:gen_all` rake task. +Note, the example and dummy apps will use your local `node_packages` folder as the `react-on-rails` node package. This will also be done automatically for you via the `rake examples:gen_all` rake task. -_Side note: It's critical to use the alias section of the webpack config to avoid a double inclusion error. This has already been done for you in the example and dummy apps, but for reference:_ +_Side note: It's critical to use the alias section of the Webpack config to avoid a double inclusion error. This has already been done for you in the example and dummy apps, but for reference:_ ```js resolve: { @@ -137,8 +137,8 @@ yarn yarn build ``` -Or run this which builds the yarn package, then the webpack files for spec/dummy, and runs tests in -spec/dummy. +Or run this, which builds the Yarn package, then the Webpack files for `spec/dummy`, and runs tests in +`spec/dummy`. ```sh # Optionally change default capybara driver @@ -182,7 +182,7 @@ yarn run check ### Starting the Dummy App -To run the dummy app, it's **CRITICAL** to not just run `rails s`. You have to run `foreman start` with one of the Procfiles. If you don't do this, then `webpack` will not generate a new bundle, and you will be seriously confused when you change JavaScript and the app does not change. If you change the webpack configs, then you need to restart foreman. If you change the JS code for react-on-rails, you need to run `yarn run build`. Since the react-on-rails package should be sym linked, you don't have to `yarn react-on-rails` after every change. +To run the dummy app, it's **CRITICAL** to not just run `rails s`. You have to run `foreman start` with one of the Procfiles. If you don't do this, then `webpack` will not generate a new bundle, and you will be seriously confused when you change JavaScript and the app does not change. If you change the Webpack configs, then you need to restart Foreman. If you change the JS code for react-on-rails, you need to run `yarn run build` in the project root. ### RSpec Testing diff --git a/NEWS.md b/NEWS.md index 03c0cddca4..3da29f290b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,9 +5,9 @@ _A history of the news. A few bullets at the top will also show on the [README.m - **October 14, 2020**: [RUBY ROGUES RR 474: React on Rails V12 – Don’t Shave That Yak! with Justin Gordon](https://devchat.tv/ruby-rogues/rr-474-react-on-rails-v12-dont-shave-that-yak-with-justin-gordon/). -- **October 1, 2020**: See the [spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy) example repo for a simple configuration of webpack via the rails/webpacker gem +- **October 1, 2020**: See the [spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy) example repo for a simple configuration of Webpack via the rails/webpacker gem that supports SSR. -- **August 2, 2020**: See the example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_demo_ssr_hmr) for a new way to setup the creation of your SSR bundle with `rails/webpacker`. +- **August 2, 2020**: See the example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_demo_ssr_hmr) for a new way to set up the creation of your SSR bundle with `rails/webpacker`. - July 8, 2020: Release **v12**. 1. **React Hooks Support** for top level components 2. **Typescript bindings** @@ -23,7 +23,7 @@ _A history of the news. A few bullets at the top will also show on the [README.m - 2017-03-06: Updated to Webpack v2! - 2017-03-02: Demo of internationalization (i18n) is live at [reactrails.com](https://www.reactrails.com/). Docs [here](docs/guides/i18n.md). - 2017-02-28: See [discussions here on Webpacker](https://github.com/rails/webpacker/issues/139) regarding how Webpacker will allow React on Rails to avoid using the asset pipeline in the near future. -- 2017-02-28: Upgrade to Webpack v2 or use the `--bail` option in your webpack script for test and production builds. See the discussion on [PR #730](https://github.com/shakacode/react_on_rails/pull/730). +- 2017-02-28: Upgrade to Webpack v2 or use the `--bail` option in your Webpack script for test and production builds. See the discussion on [PR #730](https://github.com/shakacode/react_on_rails/pull/730). - 2016-11-03: Spoke at [LA Ruby: "React on Rails: Why, What, and How?"](http://www.meetup.com/laruby/events/234825187/). [Video and pictures in this article](https://blog.shakacode.com/my-react-on-rails-talk-at-the-la-ruby-rails-meetup-november-10-2016-eaaa83aff800#.ej6h4eglp). - 2016-12-20: New Video on Egghead.io: [Creating a component with React on Rails](https://egghead.io/lessons/react-creating-a-component-with-react-on-rails) - 2016-11-03: Spoke at [LA Ruby, 7pm, Thursday, November 10 in Venice, CA: "React on Rails: Why, What, and How?"](http://www.meetup.com/laruby/events/234825187/). [Video and pictures in this article](https://blog.shakacode.com/my-react-on-rails-talk-at-the-la-ruby-rails-meetup-november-10-2016-eaaa83aff800#.ej6h4eglp). @@ -42,7 +42,7 @@ _A history of the news. A few bullets at the top will also show on the [README.m - 2016-03-17: **4.0.2** Shipped! Includes using the new Heroku buildpack steps. - Better support for hot reloading of assets from Rails with new helpers and updates to the sample testing app, [spec/dummy](spec/dummy). - Better support for Turbolinks 5. - - Controller rendering of shared redux stores and ability to render store data at bottom of HTML page. + - Controller rendering of shared Redux stores and ability to render store data at bottom of HTML page. - See [#311](https://github.com/shakacode/react_on_rails/pull/311/files). - Some breaking changes! See [CHANGELOG.md](./CHANGELOG.md) for details. - 2016-02-28: We added a [Projects page](PROJECTS.md). Please edit the page your project or [email us](mailto:contact@shakacode.com) and we'll add you. We also love stars as it helps us attract new users and contributors. [jbhatab](https://github.com/jbhatab) is leading an effort to ease the onboarding process for newbies with simpler project generators. See [#245](https://github.com/shakacode/react_on_rails/issues/245). @@ -53,7 +53,7 @@ _A history of the news. A few bullets at the top will also show on the [README.m 1. Support for ensuring JavaScript is current when running tests. 2. Support for multiple React components with one Redux store. So you can have a header React component and different body React components talking to the same Redux store! 3. Support for Turbolinks 5! -- There was a fatal error when using the lastest version of Redux for server rendering. See [Redux #1335](https://github.com/reactjs/redux/issues/1335). See [diff 3.1.6...3.1.4](https://github.com/reactjs/redux/commit/e2e14d26f09ca729ae0555442f50fcfc45bfb423#diff-1fdf421c05c1140f6d71444ea2b27638). Workaround for server rendering: Use Redux 3.1.7 or upgrade to React On Rails v2.3.0. [this commit](https://github.com/shakacode/react_on_rails/commit/59f1e68d3d233775e6abc63bff180ea59ac2d79e) on [PR #244](https://github.com/shakacode/react_on_rails/pull/244/). +- There was a fatal error when using the latest version of Redux for server rendering. See [Redux #1335](https://github.com/reactjs/redux/issues/1335). See [diff 3.1.6...3.1.4](https://github.com/reactjs/redux/commit/e2e14d26f09ca729ae0555442f50fcfc45bfb423#diff-1fdf421c05c1140f6d71444ea2b27638). Workaround for server rendering: Use Redux 3.1.7 or upgrade to React On Rails v2.3.0. [this commit](https://github.com/shakacode/react_on_rails/commit/59f1e68d3d233775e6abc63bff180ea59ac2d79e) on [PR #244](https://github.com/shakacode/react_on_rails/pull/244/). - 2.x Highlights: 1. Fixed a **critical** problem with TurboLinks. Be sure to see [turbolinks docs](docs/additional-reading/turbolinks.md) for more information on how to debug TurboLinks issues. 2. Provides a convenient helper to ensure that JavaScript assets are compiled before running tests. diff --git a/PROJECTS.md b/PROJECTS.md index 21dc1343dd..9e12d244dc 100644 --- a/PROJECTS.md +++ b/PROJECTS.md @@ -29,7 +29,7 @@ _Please support the project by [emailing Justin Gordon](mailto:justin@shakacode. - **[Deliveroo](https://deliveroo.co.uk/)**: The leading food delivery site in Europe has gone live with React on Rails, with multi-lingual JavaScript support! ![2016-05-03_19-18-34](https://cloud.githubusercontent.com/assets/1118459/15027253/91fd151a-11de-11e6-93e3-720518995fe0.png) - **[Airgoat](https://airgoat.com/)**: Marketplace for sneakers. -- **[Apprentus](https://www.apprentus.com/)**: A marketplace to find the best private teachers. Using react-on-rails from the homepage to infinity! +- **[Apprentus](https://www.apprentus.com/)**: A marketplace to find the best private teachers. Using React on Rails from the homepage to infinity! - **[Confident Financial Solutions](https://www.mycfsapp.com/)**: Auto Repair Financing to help people get back on the road and back to life. - **[Flyhomes](https://www.flyhomes.com/)**: Real estate brokerage service that awards frequent flyer miles. - **[Undeveloped](https://undeveloped.com/)**: Buy and sell domain names. ![image](https://cloud.githubusercontent.com/assets/1118459/19623703/7c6d63d0-9870-11e6-83f2-8b83ca49daa9.png) @@ -49,13 +49,15 @@ _Please support the project by [emailing Justin Gordon](mailto:justin@shakacode. - [Relay Rails Blog](https://github.com/gauravtiwari/relay-rails-blog): Tutorial to learn Relay with Rails. - [Hot Module Replacement with react_on_rails](https://medium.com/@hrishio/lesson-5-hot-module-replacement-for-react-in-rails-using-the-react-on-rails-gem-643c5b01f3d7#.ehevxok16) : Step-by-step tutorial for a quick basic set up of hot asset reloading with HMR in a Rails 5 app. [Code on Github](https://github.com/learnetto/calreact-hmr)..... -## Per Github. - ---- - ## Projects Based on React on Rails - [github.com/Limenius/symfony-react-sandbox](https://github.com/Limenius/symfony-react-sandbox) - [github.com/tswayne/react-helper](https://github.com/tswayne/react-helper) - [github.com/KissKissBankBank/kitten](https://github.com/KissKissBankBank/kitten) - [github.com/sharetribe/sharetribe](https://github.com/sharetribe/sharetribe): Open source marketplace platform. +- [GitHub search for repos using `react_on_rails`](https://github.com/search?q=gem+react_on_rails&ref=advsearch&type=repositories&utf8=%E2%9C%93) (may include some false positives) + +## Reverse dependencies + +- [Gems depending on `react_on_rails`](https://rubygems.org/gems/react_on_rails/reverse_dependencies) +- [NPM packages depending on `react-on-rails`](https://www.npmjs.com/browse/depended/react-on-rails) diff --git a/README.md b/README.md index 7a32d7cf01..9605bef669 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ If you think ShakaCode can help your project, [click here](https://meetings.hubs ## React on Rails Pro -Are you interested in optimizing your webpack setup for React on Rails, including code splitting with [react-router](https://github.com/ReactTraining/react-router#readme) and [loadable-components](https://loadable-components.com/) with server-side rendering for SEO and hot-reloading for developers? +Are you interested in optimizing your Webpack setup for React on Rails, including code splitting with [React Router](https://reactrouter.com/) and [loadable-components](https://loadable-components.com/) with server-side rendering for SEO and hot-reloading for developers? We did this for Popmenu, [lowering Heroku costs 20-25% while getting a 73% decrease in average response times](https://www.shakacode.com/recent-work/popmenu/). Several years later, Popmenu serves tens of millions of SSR requests daily with React on Rails Pro. If you're interested, read more about [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) and [book a call](https://meetings.hubspot.com/justingordon/30-minute-consultation). @@ -67,7 +67,7 @@ Given that `shakacode/shakapacker` gem already provides basic React integration, Tight integration with [shakapacker](https://github.com/shakacode/shakapacker) (or its predecessor [rails/webpacker](https://github.com/rails/webpacker)). 1. Server-Side Rendering (SSR), often used for SEO crawler indexing and UX performance. 1. [Automated optimized entry-point creation and bundle inclusion when placing a component on a page. With this feature, you no longer need to configure `javascript_pack_tags` and `stylesheet_pack_tags` on your layouts based on what’s shown. “It just works!”](https://www.shakacode.com/react-on-rails/docs/guides/file-system-based-automated-bundle-generation/) -1. [Redux](https://github.com/reactjs/redux) and [React Router](https://github.com/ReactTraining/react-router#readme) integration with server-side-rendering. +1. [Redux](https://redux.js.org/) and [React Router](https://reactrouter.com/) integration with server-side-rendering. 1. [Internationalization (I18n) and (localization)](https://www.shakacode.com/react-on-rails/docs/guides/i18n) 1. A supportive community. This [web search shows how live public sites are using React on Rails](https://publicwww.com/websites/%22react-on-rails%22++-undeveloped.com+depth%3Aall/). 1. [ReScript Support](https://github.com/shakacode/rescript-react-on-rails-example). diff --git a/SUMMARY.md b/SUMMARY.md index 3dcaf31e03..24058df901 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -36,7 +36,7 @@ Here is the new link: ## **Additional Details** -- [Migration from react-rails](./docs/guides/migrating-from-react-rails.md) +- [Migration from `react-rails`](./docs/guides/migrating-from-react-rails.md) - [Generator Details](docs/guides/generator-details.md) - [Updating Dependencies](./docs/additional-reading/updating-dependencies.md) - [Manual Installation Overview](docs/outdated/manual-installation-overview.md) diff --git a/docs/additional-details/generator-details.md b/docs/additional-details/generator-details.md index bb3e7e5139..199f64634d 100644 --- a/docs/additional-details/generator-details.md +++ b/docs/additional-details/generator-details.md @@ -43,7 +43,7 @@ Another good option is to create a simple test app per the [Tutorial](https://ww The generated client code follows our organization scheme. Each unique set of functionality is given its own folder inside of `app/javascript/app/bundles`. This encourages modularity of _domains_. -Inside of the generated "HelloWorld" domain you will find the following folders: +Inside the generated "HelloWorld" domain you will find the following folders: - `startup`: contains the entry point files for webpack. It defaults to a single file that is used for both server and client compilation. But if these need to be different, then you can create two Webpack configurations with separate endpoints. Since RoR v14.2 this is strongly recommended because the client can import `react-on-rails/client` instead of `react-on-rails` for decreased bundle size. - `containers`: contains "smart components" (components that have functionality and logic that is passed to child "dumb components"). diff --git a/docs/additional-details/manual-installation-overview.md b/docs/additional-details/manual-installation-overview.md index 8b82761b1d..ebf52a5a75 100644 --- a/docs/additional-details/manual-installation-overview.md +++ b/docs/additional-details/manual-installation-overview.md @@ -10,19 +10,19 @@ This directory has no references to Rails outside of the destination directory f The only requirements within this directory for basic React on Rails integration are: -1. Your webpack configuration files: +1. Your Webpack configuration files: 1. Create outputs in a directory like `/public/webpack`, which is customizable in your `config/initializers/react_on_rails.rb`. 1. Provide server rendering if you wish to use that feature. 1. Your JavaScript code "registers" any components and stores per the ReactOnRails APIs of ReactOnRails.register(components) and ReactOnRails.registerStore(stores). See [our javascript API docs](https://www.shakacode.com/react-on-rails/docs/api/javascript-api/) and the [ReactOnRails.js source](https://github.com/shakacode/react_on_rails/tree/master/node_package/src/ReactOnRails.js). 1. Set your registration file as an "entry" point in your Webpack configs. -1. You create scripts in `client/package.json` per the example apps. These are used for building your Webpack assets. Also do this for your top level `package.json`. +1. Configure scripts in `client/package.json` as shown in the example apps. These are used for building your Webpack assets. Also do this for your top-level `package.json`. -## Rails Steps (outside of /client) +## Rails Steps (outside `/client`) -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](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/views/layouts/application.html.erb) +1. Add `gem "shakapacker"` to the Gemfile, run `bundle`. The gem provides the `stylesheet_pack_tag` and `javascript_pack_tag` helpers, which are used to load the bundled assets in your layouts. [Dummy Example](https://github.com/shakacode/react_on_rails/tree/master/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 [https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/react_on_rails.rb](https://github.com/shakacode/react_on_rails/tree/master/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. -1. If you are deploying to Heroku, see [our heroku deployment documentation](https://www.shakacode.com/react-on-rails/docs/deployment/heroku-deployment/) +1. Configure your top-level JavaScript files for inclusion in your layout. Use one file for static assets, and a separate file for any files in your setup that are not part of your Webpack build. This separation is needed for hot reloading. If hot reloading is not needed, simply configure your `application.js` file to include the Webpack-generated files. +1. If you are deploying to Heroku, see [our Heroku deployment documentation](https://www.shakacode.com/react-on-rails/docs/deployment/heroku-deployment/). If I missed anything, please submit a PR or file an issue. diff --git a/docs/additional-details/migrating-from-react-rails.md b/docs/additional-details/migrating-from-react-rails.md index 1b89e1ff5c..41f68b537e 100644 --- a/docs/additional-details/migrating-from-react-rails.md +++ b/docs/additional-details/migrating-from-react-rails.md @@ -8,11 +8,11 @@ In this guide, it is assumed that you have upgraded the `react-rails` project to 2. Remove `react_ujs` from `package.json` and run `yarn install`. 3. Commit changes! -2. Run `rails g react_on_rails:install` but do not commit the change. `react_on_rails` installs node dependencies and also creates sample react component, Rails view/controller, and update `config/routes.rb`. +2. Run `rails g react_on_rails:install` but do not commit the change. `react_on_rails` installs node dependencies and also creates sample React component, Rails view/controller, and updates `config/routes.rb`. 3. Adapt the project: Check the changes and carefully accept, reject, or modify them as per your project's needs. Besides changes in `config/shakapacker` or `babel.config` which are project-specific, here are the most noticeable changes to address: - 1. Check webpack config files at `config/webpack/*`. If coming from `react-rails` v3, the changes are minor since you have already made separate configurations for client and server bundles. The most important change here is to notice the different names for the server bundle entry file. You may choose to stick with `server_rendering.js` or use `server-bundle.js` which is the default name in `react_on_rails`. The decision made here, affects the other steps. + 1. Check Webpack config files at `config/webpack/*`. If coming from `react-rails` v3, the changes are minor since you have already made separate configurations for client and server bundles. The most important change here is to notice the different names for the server bundle entry file. You may choose to stick with `server_rendering.js` or use `server-bundle.js` which is the default name in `react_on_rails`. The decision made here affects the other steps. 2. In `app/javascript` directory you may notice some changes. diff --git a/docs/additional-details/recommended-project-structure.md b/docs/additional-details/recommended-project-structure.md index db90ff4bb3..b6d74c5415 100644 --- a/docs/additional-details/recommended-project-structure.md +++ b/docs/additional-details/recommended-project-structure.md @@ -2,13 +2,13 @@ The React on Rails generator uses the standard Shakapacker convention of this structure: -```yml +```text app/javascript: ├── bundles: - │ # Logical groups of files that can be used for code splitting + │ # Logical groups of files that can be used for code splitting │ └── hello-world-bundle.js ├── packs: - │ # only webpack entry files here + │ # only Webpack entry files here │ └── hello-world-bundle.js ``` @@ -19,7 +19,7 @@ you should consider keeping your codebase mostly consistent with the defaults fo 1. Move the directory: -``` +```sh mv app/javascript client ``` @@ -29,9 +29,9 @@ mv app/javascript client source_path: client ``` -## Moving node_modules from `/` to `/client` with a custom webpack setup. +## Moving node_modules from `/` to `/client` with a custom Webpack setup -Shakapacker probably doesn't support having your main node_modules directory under `/client`, so only follow these steps if you want to use your own webpack configuration. +Shakapacker probably doesn't support having your main `node_modules` directory under `/client`, so only follow these steps if you want to use your own Webpack configuration. 1. Move the `/package.json` to `/client/package.json` 2. Create a `/package.json` that delegates to `/client/package.json`. @@ -53,15 +53,15 @@ You have 2 basic choices: ### Simple Rails Way -This isn't really any technique, as you keep handling all your styling assets using Rails standard tools, such as using the [sass-rails gem](https://rubygems.org/gems/sass-rails/versions/5.0.4). Basically, Webpack doesn't get involved with styling. Your Rails layouts just doing the styling the standard Rails way. +This isn't really a technique, as you keep handling all your styling assets using Rails standard tools, such as using the [sass-rails gem](https://rubygems.org/gems/sass-rails/versions/5.0.4). Basically, Webpack doesn't get involved with styling. Your Rails layouts just continue doing the styling the standard Rails way. #### Advantages to the Simple Rails Way -1. Much simpler! There's no changes really from your current processes. +1. Much simpler! There's no change from your current processes. ### Using Webpack to Manage Styling Assets -This technique involves customization of the webpack config files to generate CSS, image, and font assets. +This technique involves customization of the Webpack config files to generate CSS, image, and font assets. #### Directory structure @@ -70,6 +70,6 @@ This technique involves customization of the webpack config files to generate CS #### Advantages to having Webpack Manage Styles -1. You can use [CSS modules](https://github.com/css-modules/css-modules), which is super compelling once you seen the benefits. +1. You can use [CSS modules](https://github.com/css-modules/css-modules), which is super compelling once you see the benefits. 1. You can use CSS in JS. 1. You can do hot reloading of your assets. Thus, you do not have to refresh your web page to see asset change, including changing styles. diff --git a/docs/additional-details/updating-dependencies.md b/docs/additional-details/updating-dependencies.md index 8af1728667..175277fc42 100644 --- a/docs/additional-details/updating-dependencies.md +++ b/docs/additional-details/updating-dependencies.md @@ -1,6 +1,6 @@ # Updating Dependencies -If you frequently update you dependencies in small batches, you will avoid large and painful updates later. Then again, if you don't have good tests coverage, it's hazardous to update dependencies at any time. +If you frequently update dependencies in small batches, you will avoid large and painful updates later. Then again, if you don't have good test coverage, it's hazardous to update dependencies at any time. ## Ruby @@ -16,11 +16,11 @@ bundle update 1. Run `yarn outdated` and read CHANGELOGs of major updated packages before you update. You might not be ready for some updates. 1. Run these commands. You may or may not need to `rm -rf` your `node_modules` directory. -``` -cd client -ncu -u -a -yarn -``` + ```bash + cd client + ncu -u -a + yarn + ``` Some combinations that I often run: diff --git a/docs/api/javascript-api.md b/docs/api/javascript-api.md index d5510e5ad1..deb802f365 100644 --- a/docs/api/javascript-api.md +++ b/docs/api/javascript-api.md @@ -22,15 +22,15 @@ The best source of docs is the main [ReactOnRails.ts](https://github.com/shakaco ```js /** - * Main entry point to using the react-on-rails npm package. This is how Rails will be able to + * Main entry point to using the react-on-rails NPM package. This is how Rails will be able to * find you components for rendering. Components get called with props, or you may use a * "Render-Function" to return a React component or an object with the following shape: * { renderedHtml, redirectLocation, error }. * For server rendering, if you wish to return multiple HTML strings from a Render-Function, - * you may return an Object from your Render-Function with a single top level property of - * renderedHtml. Inside this Object, place a key called componentHtml, along with any other - * needed keys. This is useful when you using side effects libraries like react helmet. - * Your Ruby code with get this Object as a Hash containing keys componentHtml and any other + * you may return an object from your Render-Function with a single top level property of + * renderedHtml. Inside this object, place a key called componentHtml, along with any other + * needed keys. This is useful when you using side effects libraries like React Helmet. + * Your Ruby code with get this object as a Hash containing keys componentHtml and any other * custom keys that you added: * { renderedHtml: { componentHtml, customKey1, customKey2 } } * See the example in https://www.shakacode.com/react-on-rails/docs/javascript/react-helmet @@ -39,9 +39,9 @@ The best source of docs is the main [ReactOnRails.ts](https://github.com/shakaco register(components); /** - * Allows registration of store generators to be used by multiple react components on one Rails - * view. store generators are functions that take one arg, props, and return a store. Note that - * the setStore API is different in tha it's the actual store hydrated with props. + * Allows registration of store generators to be used by multiple React components on one Rails + * view. Store generators are functions that take one arg, props, and return a store. Note that + * the setStore API is different in that it's the actual store hydrated with props. * @param stores (key is store name, value is the store generator) */ registerStore(stores); @@ -74,7 +74,7 @@ reactHydrateOrRender(domNode, reactElement, hydrate); setOptions(options); /** - * Allow directly calling the page loaded script in case the default events that trigger react + * Allow directly calling the page loaded script in case the default events that trigger React * rendering are not sufficient, such as when loading JavaScript asynchronously with TurboLinks: * More details can be found here: * https://www.shakacode.com/react-on-rails/docs/rails/turbolinks diff --git a/docs/api/redux-store-api.md b/docs/api/redux-store-api.md index 4ad24dc28b..d908814d31 100644 --- a/docs/api/redux-store-api.md +++ b/docs/api/redux-store-api.md @@ -1,10 +1,12 @@ # Redux Store -_This redux API is no longer recommended as it prevents dynamic code splitting for performance. Instead, you should use the standard react_component view helper passing in a "Render-Function."_ +> [!WARNING] +> +> This Redux API is no longer recommended as it prevents dynamic code splitting for performance. Instead, you should use the standard `react_component` view helper passing in a "Render-Function." -You don't need to use the `redux_store` api to use redux. This api was setup to support multiple calls to `react_component` on one page that all talk to the same redux store. +You don't need to use the `redux_store` api to use Redux. This API was set up to support multiple calls to `react_component` on one page that all talk to the same Redux store. -If you are only rendering one react component on a page, as is typical to do a "Single Page App" in React, then you should _probably_ pass the props to your React component in a "Render-Function." +If you are only rendering one React component on a page, as is typical to do a "Single Page App" in React, then you should _probably_ pass the props to your React component in a "Render-Function." Consider using the `redux_store` helper for the two following use cases: diff --git a/docs/api/view-helpers-api.md b/docs/api/view-helpers-api.md index a3f374b314..c2420caeed 100644 --- a/docs/api/view-helpers-api.md +++ b/docs/api/view-helpers-api.md @@ -27,7 +27,7 @@ Uncommonly used options: - **component_name:** Can be a React component, created using a React Function Component, an ES6 class or a Render-Function that returns a React component (or, only on the server side, an object with shape `{ redirectLocation, error, renderedHtml }`), or a "renderer function" that manually renders a React component to the dom (client side only). Note, a "renderer function" is a special type of "Render-Function." A "renderer function" takes a 3rd param of a DOM ID. All options except `props, id, html_options` will inherit from your `react_on_rails.rb` initializer, as described [here](https://www.shakacode.com/react-on-rails/docs/guides/configuration/). - **general options:** - - **props:** Ruby Hash which contains the properties to pass to the react object, or a JSON string. If you pass a string, we'll escape it for you. + - **props:** Ruby Hash which contains the properties to pass to the React object, or a JSON string. If you pass a string, we'll escape it for you. - **prerender:** enable server-side rendering of a component. Set to false when debugging! - **auto_load_bundle:** will automatically load the bundle for component by calling `append_javascript_pack_tag` and `append_stylesheet_pack_tag` under the hood. - **id:** Id for the div, will be used to attach the React component. This will get assigned automatically if you do not provide an id. Must be unique. @@ -87,7 +87,7 @@ Fragment caching is a [React on Rails Pro](https://github.com/shakacode/react_on 1. The `cache_key` takes the same parameters as any Rails `cache` view helper. 1. The **props** are passed via a block so that evaluation of the props is not done unless the cache is broken. Suppose you put your props calculation into some method called `some_slow_method_that_returns_props`: -```ruby +```erb <%= cached_react_component("App", cache_key: [@user, @post], prerender: true) do some_slow_method_that_returns_props end %> @@ -97,7 +97,7 @@ end %> ### rails_context -You can call `rails_context` or `rails_context(server_side: true|false)` from your controller or view to see what values are in the Rails Context. Pass true or false depending on whether you want to see the server side or the client side rails_context. Typically, for computing cache keys, you should leave server_side as the default true. When calling this from a controller method, use `helpers.rails_context`. +You can call `rails_context` or `rails_context(server_side: true|false)` from your controller or view to see what values are in the Rails Context. Pass true or false depending on whether you want to see the server-side or the client-side `rails_context`. Typically, for computing cache keys, you should leave `server_side` as the default true. When calling this from a controller method, use `helpers.rails_context`. --- @@ -113,9 +113,9 @@ Renderer functions are not meant to be used on the server since there's no DOM o ### React Router -[React Router](https://github.com/reactjs/react-router) is supported, including server-side rendering! See: +[React Router](https://reactrouter.com/) is supported, including server-side rendering! See: -1. [React on Rails docs for react-router](https://www.shakacode.com/react-on-rails/docs/javascript/react-router/) +1. [React on Rails docs for React Router](https://www.shakacode.com/react-on-rails/docs/javascript/react-router/) 2. Examples in [spec/dummy/app/views/react_router](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/app/views/react_router) and follow to the JavaScript code in the [spec/dummy/client/app/startup/ServerRouterApp.jsx](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/client/app/startup/ServerRouterApp.jsx). 3. [Code Splitting docs](https://www.shakacode.com/react-on-rails/docs/javascript/code-splitting/) for information about how to set up code splitting for server rendered routes. diff --git a/docs/contributor-info/generator-testing.md b/docs/contributor-info/generator-testing.md index 407067809a..d84d8233c7 100644 --- a/docs/contributor-info/generator-testing.md +++ b/docs/contributor-info/generator-testing.md @@ -1,6 +1,6 @@ # Generator Testing -We create several applications that are examples of running the generator (see [lib/generators/react_on_rails/install_generator.rb](https://github.com/shakacode/react_on_rails/blob/master/lib/generators/react_on_rails/install_generator.rb)) with various different options. We can then run tests with these apps just like we would any Rails app and thus ensure that our generator makes apps that actually function properly. +We create several applications that are examples of running the generator (see [lib/generators/react_on_rails/install_generator.rb](https://github.com/shakacode/react_on_rails/blob/master/lib/generators/react_on_rails/install_generator.rb)) with various options. We can then run tests with these apps just like we would any Rails app and thus ensure that our generator makes apps that actually function properly. Special rake tasks in rakelib/examples.rake handle creating the example apps and running a special hidden generator ([lib/generators/react_on_rails/dev_tests_generator.rb](https://github.com/shakacode/react_on_rails/blob/master/lib/generators/react_on_rails/dev_tests_generator.rb)) that installs the tests we want to run for each app. These tests can be run manually like any Rails app, or they can be run via the `rake run_rspec:shakapacker_examples` command. There are also commands for running each app individually, i.e., `rake run_rspec:shakapacker_example_basic`. diff --git a/docs/contributor-info/linters.md b/docs/contributor-info/linters.md index 543f492618..f6e6cc53c9 100644 --- a/docs/contributor-info/linters.md +++ b/docs/contributor-info/linters.md @@ -7,21 +7,21 @@ These linters support the [ShakaCode Style Guidelines](https://www.shakacode.com If you haven't tried the autofix options for `eslint` and `rubocop`, you're seriously missing out! 1. Be **SURE** you have a clean git status, as you'll want to review what the autofix does to your code! -2. **Rubocop:** Be sure to be in the right directory where you have Ruby files, probably the top level of your Rails project. +2. **Rubocop:** Be sure to be in the correct directory where you have Ruby files, usually the top level of your Rails project. -``` +```bash rubocop -a ``` -3. **eslint:**: Be sure to be in the right directory where you have JS files. +3. **ESLint:** Be sure to be in the correct directory where you have JS files. -``` +```bash eslint --fix . ``` or -``` +```bash npm run lint -- --fix ``` @@ -29,11 +29,15 @@ Autofixing is a **HUGE** time saver! ## ESLint +See the [ESLint](https://eslint.org/) website for more information. + ### Configuring Rules -Rules are configured with a 0, 1 or 2. Setting a rule to 0 is turning it off, setting it to 1 triggers a warning if that rule is violated, and setting it to 2 triggers an error. +See [the documentation](https://eslint.org/docs/latest/use/configure/rules) first. + +Rule severity is configured with `'off'`, `'warn'` or `'error'`. In older configurations you can see `0`, `1`, and `2` instead. -Rules can also take a few additional options. In this case, the rule can be set to an array, the first item of which is the 0/1/2 flag and the rest are options. +Rules can also take a few additional options. In this case, the rule can be set to an array, the first item of which is the severity and the rest are options. See file [.eslintrc](https://github.com/shakacode/react_on_rails/tree/master/.eslintrc) for examples of configuration @@ -63,9 +67,6 @@ alert('more alert'); You can disable all rules for a line or block, or only specific rules, as shown above. -### Useful Reference Links +## RuboCop -- [Configuring ESLint](http://eslint.org/docs/user-guide/configuring.html#configuring-rules) -- [ESLint quick start](http://untilfalse.com/eslint-quick-start/) -- [RuboCop](https://github.com/bbatsov/rubocop) -- [ESLint](http://eslint.org/) +See the [RuboCop website](https://rubocop.org/). diff --git a/docs/contributor-info/pull-requests.md b/docs/contributor-info/pull-requests.md index 4f18795aed..f0a24b819e 100644 --- a/docs/contributor-info/pull-requests.md +++ b/docs/contributor-info/pull-requests.md @@ -2,7 +2,7 @@ ## Checklist before Committing -1. `rake`: runs all linters and specs (you need Docker setup, see below) +1. Run all linters and specs (you need Docker set up, see below). 2. Did you need any more tests for your change? 3. Did you document your change? Update the README.md? 4. Did you add a CHANGELOG.md entry? @@ -19,7 +19,7 @@ For non-doc fixes: From [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) -#### The seven rules of a great git commit message +### The seven rules of a great git commit message > Keep in mind: This has all been said before. @@ -37,8 +37,8 @@ When making doc changes, we want the change to work on both the gitbook and the ### Links to other docs: -- When making references to doc files, use a relative URL path like: +- When making references to doc files, use a full URL to , for example: `[Installation Overview](https://www.shakacode.com/react-on-rails/docs/additional-details/manual-installation-overview/)` -- When making references to source code files, use a full url path like: +- When making references to source code files, use a full GitHub URL, for example: `[spec/dummy/config/initializers/react_on_rails.rb](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/initializers/react_on_rails.rb)` diff --git a/docs/deployment/elastic-beanstalk.md b/docs/deployment/elastic-beanstalk.md index 24a196b1e9..7f8957e469 100644 --- a/docs/deployment/elastic-beanstalk.md +++ b/docs/deployment/elastic-beanstalk.md @@ -1,7 +1,7 @@ # Deploying React on Rails to Elastic Beanstalk -In order to deploy a React on Rails app to elastic beanstalk, you must install yarn on each instance. -If yarn is not installed, asset compilation will fail on the elastic beanstalk instance. +In order to deploy a React on Rails app to Elastic Beanstalk, you must install yarn on each instance. +If yarn is not installed, asset compilation will fail on the Elastic Beanstalk instance. You can install `yarn` by adding a `0x_install_yarn.config` file to your `.ebextensions` folder which contains these commands. @@ -42,9 +42,9 @@ files: chmod 700 /home/webapp ``` -This script installs `yarn` and all `node.js` dependencies before the rails do `assets:precompile`. Also, it creates `/home/webapp` directory allowing the precompile task to create temp files. +This script installs `yarn` and all JS dependencies before Rails runs `assets:precompile`. Also, it creates `/home/webapp` directory, allowing the precompile task to create temporary files. -Your app can be deployed to elastic beanstalk successfully. However, the react app javascript files are under `public/packs`. If you are using nginx, you need to let it know the location of `https://yourhost/packs`. +Your app can be deployed to Elastic Beanstalk successfully. However, the React app JavaScript files are under `public/packs`. If you are using Nginx, you need to let it know the location of `https://yourhost/packs`. In your `proxy.conf` setting, please add the following code. diff --git a/docs/deployment/heroku-deployment.md b/docs/deployment/heroku-deployment.md index 4f24c80df8..5a3266a326 100644 --- a/docs/deployment/heroku-deployment.md +++ b/docs/deployment/heroku-deployment.md @@ -15,12 +15,12 @@ For more information, see [Using Multiple Buildpacks for an App](https://devcent ## assets:precompile -### Shakapacker webpack configuration +### Shakapacker Webpack configuration Shakapacker hooks up a new `shakapacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`. If you are not using Sprockets, `shakapacker:compile` is automatically aliased to `assets:precompile`. -If you're using the standard `shakacode/shakapacker` configuration of webpack, then `shakacode/shakapacker` +If you're using the standard `shakacode/shakapacker` configuration for Webpack, then `shakacode/shakapacker` will automatically modify or create an `assets:precompile` task to build your assets. Alternatively, you can specify `config.build_production_command` to have diff --git a/docs/getting-started.md b/docs/getting-started.md index 68fd0215c8..299094b337 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -71,7 +71,7 @@ issue. - Configure `config/initializers/react_on_rails.rb`. You can adjust some necessary settings and defaults. See file [docs/basics/configuration.md](https://www.shakacode.com/react-on-rails/docs/guides/configuration/) for documentation of all configuration options. - Configure `config/shakapacker.yml`. If you used the generator and the default Shakapacker setup, you don't need to touch this file. If you are customizing your setup, then consult the [spec/dummy/config/shakapacker.yml](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/config/shakapacker.yml) example or the official default [shakapacker.yml](https://github.com/shakacode/shakapacker/blob/master/lib/install/config/shakapacker.yml). -- Most apps should rely on the Shakapacker setup for Webpack. Shakapacker v6+ includes support for webpack version 5. +- Most apps should rely on the Shakapacker setup for Webpack. Shakapacker v6+ includes support for Webpack version 5. ## Including your React Component on your Rails Views @@ -95,11 +95,11 @@ issue. ReactOnRails.register({ HelloWorld }); ``` - Exposing your component in this way is how React on Rails is able to reference your component from a Rails view. You can expose as many components as you like, as long as their names do not collide. See below for the details of how you expose your components via the react_on_rails webpack configuration. You may call `ReactOnRails.register` many times. + Exposing your component in this way allows you to reference the component from a Rails view. You can expose as many components as you like, but their names must be unique. See below for the details of how you expose your components via the React on Rails Webpack configuration. You may call `ReactOnRails.register` many times. - `@some_props` can be either a hash or JSON string. This is an optional argument assuming you do not need to pass any options (if you want to pass options, such as `prerender: true`, but you do not want to pass any properties, simply pass an empty hash `{}`). This will make the data available in your component: - ```ruby + ```erb # Rails View <%= react_component("HelloWorld", props: { name: "Stranger" }) %> ``` @@ -139,9 +139,9 @@ ReactOnRails.register({ HelloWorld }); #### Different Server-Side Rendering Code (and a Server-Specific Bundle) -You may want different code for your server-rendered components running server side versus client side. For example, if you have an animation that runs when a component is displayed, you might need to turn that off when server rendering. One way to handle this is conditional code like `if (window) { doClientOnlyCode() }`. +You may want different code for your server-rendered components running on the server side versus the client side. For example, if you have an animation that runs when a component is displayed, you might need to turn that off when server rendering. One way to handle this is conditional code like `if (typeof window !== 'undefined') { doClientOnlyCode() }`. -Another way is to use a separate webpack configuration file that can use a different server side entry file, like 'serverRegistration.js' as opposed to 'clientRegistration.js.' That would set up different code for server rendering. +Another way is to use a separate Webpack configuration file that can use a different server-side entry file, like 'serverRegistration.js' as opposed to 'clientRegistration.js.' That would set up different code for server rendering. For details on techniques to use different code for client and server rendering, see: [How to use different versions of a file for client and server rendering](https://forum.shakacode.com/t/how-to-use-different-versions-of-a-file-for-client-and-server-rendering/1352). (_Requires creating a free account._) diff --git a/docs/guides/client-vs-server-rendering.md b/docs/guides/client-vs-server-rendering.md index 204c3c5030..e9b5c59b26 100644 --- a/docs/guides/client-vs-server-rendering.md +++ b/docs/guides/client-vs-server-rendering.md @@ -1,6 +1,6 @@ # Client-Side Rendering vs. Server-Side Rendering -_Also, see [our react server-rendering documentation](https://www.shakacode.com/react-on-rails/docs/guides/react-server-rendering/)._ +_Also, see [our React server-rendering documentation](https://www.shakacode.com/react-on-rails/docs/guides/react-server-rendering/)._ In most cases, you should use the `prerender: false` (default behavior) with the provided helper method to render the React component from your Rails views. In some cases, such as when SEO is vital, or many users will not have JavaScript enabled, you can enable server-rendering by passing `prerender: true` to your helper, or you can simply change the default in `config/initializers/react_on_rails`. @@ -20,8 +20,8 @@ If you open the HTML source of any web page using React on Rails, you'll see the # Different Server-Side Rendering Code (and a Server-Specific Bundle) -You may want different code for your server-rendered components running server side versus client side. For example, if you have an animation that runs when a component is displayed, you might need to turn that off when server rendering. One way to handle this is conditional code like `if (window) { doClientOnlyCode() }`. +You may want different code for your server-rendered components running server-side versus client-side. For example, if you have an animation that runs when a component is displayed, you might need to turn that off when server rendering. One way to handle this is conditional code like `if (window) { doClientOnlyCode() }`. -Another way is to use a separate Webpack configuration file that can use a different server-side entry file, like 'serverRegistration.js' as opposed to 'clientRegistration.js.' That would set up different code for server rendering. +Another way is to use a separate Webpack configuration file that can use a different server-side entry file, like `serverRegistration.js` as opposed to `clientRegistration.js`. That would set up different code for server rendering. For details on techniques to use different code for client and server rendering, see: [How to use different versions of a file for client and server rendering](https://forum.shakacode.com/t/how-to-use-different-versions-of-a-file-for-client-and-server-rendering/1352). _Requires creating a free account._ diff --git a/docs/guides/configuration.md b/docs/guides/configuration.md index 17ca3060b6..9ae3462081 100644 --- a/docs/guides/configuration.md +++ b/docs/guides/configuration.md @@ -8,12 +8,12 @@ Here is the setup when using the recommended `/` directory for your `node_module # Note: Base output directory of /public is assumed for static files default: &default compile: false - # Used in your webpack configuration. Must be created in the + # Used in your Webpack configuration. Must be created in the # public_output_path folder manifest: manifest.json cache_manifest: false - # Source path is used to check if webpack compilation needs to be run for `compile: true` + # Source path is used to check if Webpack compilation needs to be run for `compile: true` source_path: client/app development: @@ -23,7 +23,7 @@ development: test: <<: *default - # Ensure that shakapacker invokes webpack to build files for tests if not using the + # Ensure that shakapacker invokes Webpack to build files for tests if not using the # ReactOnRails rspec helper. compile: true @@ -70,7 +70,7 @@ ReactOnRails.configure do |config| # defaults to "" (top level) config.node_modules_location = "" # If using Shakapacker you should use "". - # If you're using the standard Shakapacker configuration of webpack, then Shakapacker + # If you're using the standard Shakapacker configuration of Webpack, then Shakapacker # will automatically modify or create an assets:precompile task to build your assets. If so, # set this value to nil. Alternatively, you can specify `config.build_production_command` # to have react_on_rails invoke a command for you during assets:precompile. @@ -101,7 +101,7 @@ 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. + # you should include a name that matches your bundle name in your Webpack config. config.server_bundle_js_file = "server-bundle.js" # `prerender` means server-side rendering @@ -232,7 +232,7 @@ ReactOnRails.configure do |config| # 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. + # to automatically refresh your Webpack assets on every test run. # config.build_test_command = "RAILS_ENV=test bin/shakapacker" @@ -241,7 +241,7 @@ ReactOnRails.configure do |config| # by your config/shakapacker.yml source_path: # source_path: client/app # if using recommended /client directory # - # Define the files we need to check for webpack compilation when running tests. + # 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 shakapacker builds. # However, if you are generating a server bundle that is NOT hashed (present in manifest.json), # then include the file in this list like this: diff --git a/docs/guides/file-system-based-automated-bundle-generation.md b/docs/guides/file-system-based-automated-bundle-generation.md index b7b71c9a84..fed6fa0c41 100644 --- a/docs/guides/file-system-based-automated-bundle-generation.md +++ b/docs/guides/file-system-based-automated-bundle-generation.md @@ -123,7 +123,7 @@ Your layout would contain: Now suppose you want to use bundle splitting to minimize unnecessary javascript loaded on each page, you would put each of your components in the `packs` directory. -``` +```text app/javascript: └── packs: # sets up webpack entries │ └── FooComponentOne.jsx # Internally uses ReactOnRails.register @@ -177,7 +177,7 @@ For example, if you wanted to utilize our file-system based entrypoint generatio │ │ │ └── BarComponentTwo.jsx ``` - 4. You no longer need to register the React components within the `ReactOnRails.configuration.components_subdirectory` nor directly add their bundles. For example you can have a Rails view using three components: + 4. You no longer need to register the React components within the `ReactOnRails.configuration.components_subdirectory` nor directly add their bundles. For example, you can have a Rails view using three components: ```erb <% append_javascript_pack('BarComponentTwo') %> @@ -206,12 +206,13 @@ For example, if you wanted to utilize our file-system based entrypoint generatio ### Server Rendering and Client Rendering Components -If server rendering is enabled, the component will be registered for usage both in server and client rendering. In order to have separate definitions for client and server rendering, name the component files as `ComponentName.server.jsx` and `ComponentName.client.jsx`. The `ComponentName.server.jsx` file will be used for server rendering and the `ComponentName.client.jsx` file for client rendering. If you don't want the component rendered on the server, you should only have the `ComponentName.client.jsx` file. +If server rendering is enabled, the component will be registered for usage both in server and client rendering. To have separate definitions for client and server rendering, name the component files `ComponentName.server.jsx` and `ComponentName.client.jsx`. The `ComponentName.server.jsx` file will be used for server rendering and the `ComponentName.client.jsx` file for client rendering. If you don't want the component rendered on the server, you should only have the `ComponentName.client.jsx` file. Once generated, all server entrypoints will be imported into a file named `[ReactOnRails.configuration.server_bundle_js_file]-generated.js`, which in turn will be imported into a source file named the same as `ReactOnRails.configuration.server_bundle_js_file`. If your server bundling logic is such that your server bundle source entrypoint is not named the same as your `ReactOnRails.configuration.server_bundle_js_file` and changing it would be difficult, please let us know. -_Note: If specifying separate definitions for client and server rendering, please make sure to delete the generalized `ComponentName.jsx` file._ +> [!IMPORTANT] +> When specifying separate definitions for client and server rendering, you need to delete the generalized `ComponentName.jsx` file. ### Using Automated Bundle Generation Feature with already defined packs -As of version 13.3.4, bundles inside of directories that match `config.components_subdirectory` will be automatically added as entrypoints, while bundles outside of those directories will have to be manually added to the Shakapacker.config.source_entry_path or Webpack's `entry` rules. +As of version 13.3.4, bundles inside directories that match `config.components_subdirectory` will be automatically added as entrypoints, while bundles outside those directories need to be manually added to the `Shakapacker.config.source_entry_path` or Webpack's `entry` rules. diff --git a/docs/guides/hmr-and-hot-reloading-with-the-webpack-dev-server.md b/docs/guides/hmr-and-hot-reloading-with-the-webpack-dev-server.md index 8b1a2eac3d..11a1408ad2 100644 --- a/docs/guides/hmr-and-hot-reloading-with-the-webpack-dev-server.md +++ b/docs/guides/hmr-and-hot-reloading-with-the-webpack-dev-server.md @@ -8,7 +8,7 @@ The `webpack-dev-server` provides: abruptly lose any tweaks within the Chrome development tools. 3. Optional hot-reloading. The older `react-hot-loader` has been deprecated in favor of [fast-refresh](https://reactnative.dev/docs/fast-refresh). - For use with webpack, see **Client Side rendering and HMR using react-refresh-webpack-plugin** section bellow or visit [react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin) for additional details. + For use with Webpack, see **Client Side rendering and HMR using react-refresh-webpack-plugin** section below or visit [react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin) for additional details. If you are **_not_** using server-side rendering (**_not_** using `prerender: true`), then you can follow all the regular docs for using the `bin/shakapacker-dev-server` @@ -16,8 +16,8 @@ during development. # Server Side Rendering with the Default shakacode/shakapacker bin/shakapacker-dev-server -If you are using server-side rendering, then you have a couple options. The -recommended technique is to have a different webpack configuration for server +If you are using server-side rendering, then you have a couple of options. The +recommended technique is to have a different Webpack configuration for server rendering. ## If you use the same Webpack setup for your server and client bundles @@ -25,8 +25,8 @@ rendering. If you do use the `webpack-dev-server` for prerendering, be sure to set the `config/initializers/react_on_rails.rb` setting of -``` - config.same_bundle_for_client_and_server = true +```ruby +config.same_bundle_for_client_and_server = true ``` `dev_server.hmr` maps to [devServer.hot](https://webpack.js.org/configuration/dev-server/#devserverhot). @@ -72,7 +72,7 @@ To enable the HMR functionality, you have to use `./bin/shakapacker-dev-server` const isWebpackDevServer = process.env.WEBPACK_DEV_SERVER; - //plugins + // plugins if (isWebpackDevServer) { environment.plugins.append( 'ReactRefreshWebpackPlugin', @@ -98,9 +98,9 @@ To enable the HMR functionality, you have to use `./bin/shakapacker-dev-server` ``` That's it :). -Now Browser should reflect `.js` along with `.css` changes without reloading. +Now the browser should reflect changes in `.js` and `.css` files without reloading. -If by some reason plugin doesn't work you could revert changes and left only devServer hmr/inline to true affecting only css files. +If for some reason the plugin doesn't work, you can revert the changes and leave only devServer `hmr`/`inline` set to true, affecting only CSS files. These plugins are working and tested with diff --git a/docs/guides/how-react-on-rails-works.md b/docs/guides/how-react-on-rails-works.md index da362cc5bd..42a270dade 100644 --- a/docs/guides/how-react-on-rails-works.md +++ b/docs/guides/how-react-on-rails-works.md @@ -4,11 +4,11 @@ Webpack is used to generate JavaScript and CSS "bundles" directly to your `/public` directory. [Shakapacker](https://github.com/shakacode/shakapacker) provides view helpers to access the Webpack-generated (and fingerprinted) JS and CSS. These files totally skip the Rails asset pipeline. You are responsible for properly configuring your Webpack output. You will either use the standard Webpack configuration (_recommended_) or the `shakapacker` setup for Webpack. -Ensure these generated bundle files are in your `.gitignore`, as you never want to add the large compiled bundles to git. +Ensure these generated bundle files are in your `.gitignore`, as you never want to add the large compiled bundles to Git. -Inside your Rails views, you can now use the `react_component` helper method provided by React on Rails. You can pass props directly to the react component helper. +Inside your Rails views, you can now use the `react_component` helper method provided by React on Rails. You can pass props directly to the React component helper. -Optionally, you can also initialize a Redux store with the view or controller helper `redux_store` so that the redux store can be shared amongst multiple React components. +Optionally, you can also initialize a Redux store with the view or controller helper `redux_store` so that the Redux store can be shared amongst multiple React components. ## Client-Side Rendering vs. Server-Side Rendering @@ -28,13 +28,13 @@ You can see all this on the source for [reactrails.com](https://www.reactrails.c ## Building the Bundles -Each time you change your client code, you will need to re-generate the bundles (the webpack-created JavaScript files included in application.js). The included example Foreman `Procfile.dev` files will take care of this for you by starting a webpack process with the watch flag. This will watch your JavaScript code files for changes. Alternatively, the `shakapacker` library also can ensure that your bundles are built. +Each time you change your client code, you will need to re-generate the bundles (the Webpack-created JavaScript files included in `application.js`). The included example Foreman `Procfile.dev` files will take care of this for you by starting a Webpack process with the watch flag. This will watch your JavaScript code files for changes. Alternatively, the `shakapacker` library also can ensure that your bundles are built. For example, you might create a [Procfile.dev](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy/Procfile.dev). -On production deployments that use asset precompilation, such as Heroku deployments, `shakapacker`, by default, will automatically run webpack to build your JavaScript bundles, running the command `bin/shakapacker` in your app. +On production deployments that use asset precompilation, such as Heroku deployments, `shakapacker`, by default, will automatically run Webpack to build your JavaScript bundles, running the command `bin/shakapacker` in your app. -However, if you want to run a custom command to run webpack to build your bundles, then you will: +However, if you want to run a custom command to run Webpack to build your bundles, then you will: 1. Define `config.build_production_command` in your [config/initializers/react_on_rails.rb](https://www.shakacode.com/react-on-rails/docs/guides/configuration/) diff --git a/docs/guides/how-to-use-different-files-for-client-and-server-rendering.md b/docs/guides/how-to-use-different-files-for-client-and-server-rendering.md index b717014c5c..3396da907e 100644 --- a/docs/guides/how-to-use-different-files-for-client-and-server-rendering.md +++ b/docs/guides/how-to-use-different-files-for-client-and-server-rendering.md @@ -4,7 +4,7 @@ There are 3 main ways to use different code for server vs. client rendering. ## A. Using different Entry Points -Many projects will have different entry points for client and server rendering. This only works for a top-level entry point such as the entry point for a react-router app component. +Many projects will have different entry points for client and server rendering. This only works for a top-level entry point such as the entry point for a React Router app component. Your Client Entry can look like this: diff --git a/docs/guides/i18n.md b/docs/guides/i18n.md index 2be4a4182e..d4acaa6f43 100644 --- a/docs/guides/i18n.md +++ b/docs/guides/i18n.md @@ -21,17 +21,17 @@ You can use [Rails internationalization (i18n)](https://guides.rubyonrails.org/i 3. The locale files must be generated before `yarn build` using `rake react_on_rails:locale`. - For development, you should adjust your startup scripts (`Procfile`s) so that they run `bundle exec rake react_on_rails:locale` before running any webpack watch process (`yarn run build:development`). + For development, you should adjust your startup scripts (`Procfile`s) so that they run `bundle exec rake react_on_rails:locale` before running any Webpack watch process (`yarn run build:development`). If you are not using the React on Rails test helper, - you may need to configure your CI to run `bundle exec rake react_on_rails:locale` before any webpack process as well. + you may need to configure your CI to run `bundle exec rake react_on_rails:locale` before any Webpack process as well. > [!NOTE] > If you try to lint before running tests, and you depend on the test helper to build your locales, linting will fail because the translations won't be built yet. > - > The fix is either to + > The fix is either: > - > 1. run the rake task to build the translations before running the lint command or + > 1. to run the rake task to build the translations before running the lint command, or > 2. to run the tests first. 4. If your locale files (or one of the gems locale files) contains unsafe YAML, you may need to configure `config.i18n_yml_safe_load_options` if you can't fix such YAML files properly. diff --git a/docs/guides/installation-into-an-existing-rails-app.md b/docs/guides/installation-into-an-existing-rails-app.md index bdc1159832..cbc5003576 100644 --- a/docs/guides/installation-into-an-existing-rails-app.md +++ b/docs/guides/installation-into-an-existing-rails-app.md @@ -2,7 +2,7 @@ **Also consult the instructions for installing on a fresh Rails app**, see the [React on Rails Basic Tutorial](https://www.shakacode.com/react-on-rails/docs/guides/tutorial/). -**If you have rails-5 API only project**, first [convert the rails-5 API only app to rails app](https://www.shakacode.com/react-on-rails/docs/rails/convert-rails-5-api-only-app/). +**If you have Rails 5 API only project**, first [convert the Rails 5 API only app to a normal Rails app](https://www.shakacode.com/react-on-rails/docs/rails/convert-rails-5-api-only-app/). 1. Add the following to your Gemfile and `bundle install`. We recommend fixing the version of React on Rails, as you will need to keep the exact version in sync with the version in your `package.json` file. diff --git a/docs/guides/rails-webpacker-react-integration-options.md b/docs/guides/rails-webpacker-react-integration-options.md index ec20212d98..d524392d0b 100644 --- a/docs/guides/rails-webpacker-react-integration-options.md +++ b/docs/guides/rails-webpacker-react-integration-options.md @@ -8,10 +8,10 @@ have your app make a second round trip to the Rails server to get initialization These gems provide advanced integration of React with [shakacode/shakapacker](https://github.com/shakacode/shakapacker): | Gem | Props Hydration | Server-Side-Rendering (SSR) | SSR with HMR | SSR with React-Router | SSR with Code Splitting | Node SSR | -| ----------------------------------------------------------------------- | --------------- | --------------------------- | ------------ | --------------------- | ----------------------- | -------- | --- | +| ----------------------------------------------------------------------- | --------------- | --------------------------- | ------------ | --------------------- | ----------------------- | -------- | | [shakacode/react_on_rails](https://github.com/shakacode/react_on_rails) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [react-rails](https://github.com/reactjs/react-rails) | ✅ | ✅ | | | | | | -| [webpacker-react](https://github.com/renchap/webpacker-react) | ✅ | | | | | | | +| [react-rails](https://github.com/reactjs/react-rails) | ✅ | ✅ | | | | | +| [webpacker-react](https://github.com/renchap/webpacker-react) | ✅ | | | | | | Note, Node SSR for React on Rails requires [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/). @@ -156,61 +156,60 @@ You can see an example commit of adding this [here](https://github.com/shakacode 2. Update your babel config, `babel.config.js`. Add the plugin `react-hot-loader/babel` with the option `safetyNet: false`: -``` -{ - "plugins": [ - [ - "react-hot-loader/babel", - { - "safetyNet": false - } - ] - ] -} -``` + ```js + { + plugins: [ + [ + 'react-hot-loader/babel', + { + safetyNet: false, + }, + ], + ], + } + ``` 3. Add changes like this to your entry points: -```diff -// app/javascript/app.jsx + ```diff + // app/javascript/app.jsx -import React from 'react'; -+ import { hot } from 'react-hot-loader/root'; + import React from 'react'; + + import { hot } from 'react-hot-loader/root'; -const App = () => + const App = () => -- export default App; -+ export default hot(App); -``` + - export default App; + + export default hot(App); + ``` -4. Adjust your webpack configuration for development so that `sourceMapContents` option for the sass - loader is `false`: +4. Adjust your Webpack configuration for development so that `sourceMapContents` option for the SASS loader is `false`: -```diff -// config/webpack/development.js + ```diff + // config/webpack/development.js -process.env.NODE_ENV = process.env.NODE_ENV || 'development' + process.env.NODE_ENV = process.env.NODE_ENV || 'development' -const environment = require('./environment') + const environment = require('./environment') -// allows for editing sass/scss files directly in browser -+ if (!module.hot) { -+ environment.loaders.get('sass').use.find(item => item.loader === 'sass-loader').options.sourceMapContents = false -+ } -+ -module.exports = environment.toWebpackConfig() -``` + // allows for editing sass/scss files directly in browser + + if (!module.hot) { + + environment.loaders.get('sass').use.find(item => item.loader === 'sass-loader').options.sourceMapContents = false + + } + + + module.exports = environment.toWebpackConfig() + ``` -5. Adjust your `config/webpack/environment.js` for a +5. Adjust your `config/webpack/environment.js`: -```diff -// config/webpack/environment.js + ```diff + // config/webpack/environment.js -// ... + // ... -// Fixes: React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work. -// https://github.com/gaearon/react-hot-loader/issues/1227#issuecomment-482139583 -+ environment.config.merge({ resolve: { alias: { 'react-dom': '@hot-loader/react-dom' } } }); + // Fixes: React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work. + // https://github.com/gaearon/react-hot-loader/issues/1227#issuecomment-482139583 + + environment.config.merge({ resolve: { alias: { 'react-dom': '@hot-loader/react-dom' } } }); -module.exports = environment; -``` + module.exports = environment; + ``` diff --git a/docs/guides/react-on-rails-overview.md b/docs/guides/react-on-rails-overview.md index 7f5de20175..4adda607d1 100644 --- a/docs/guides/react-on-rails-overview.md +++ b/docs/guides/react-on-rails-overview.md @@ -15,7 +15,7 @@ To provide a high performance framework for integrating Ruby on Rails with React 1. Server-Side Rendering (SSR), often used for SEO crawler indexing and UX performance, is not offered by `shakacode/shakapacker`. 1. Support for HMR for a great developer experience. 1. Supports latest versions of React with hooks. -1. [Redux](https://github.com/reactjs/redux) and [React Router](https://github.com/ReactTraining/react-router#readme) integration including server-side-rendering. +1. [Redux](https://redux.js.org/) and [React Router](https://reactrouter.com/) integration including server-side-rendering. 1. [Internationalization (I18n) and (localization)](https://www.shakacode.com/react-on-rails/docs/guides/i18n/) 1. A supportive community. This [web search shows how live public sites are using React on Rails](https://publicwww.com/websites/%22react-on-rails%22++-undeveloped.com+depth%3Aall/). 1. [ReScript (Reason ML) Support](https://github.com/shakacode/reason-react-on-rails-example). diff --git a/docs/guides/react-server-rendering.md b/docs/guides/react-server-rendering.md index 3e04b716e0..247b2e190c 100644 --- a/docs/guides/react-server-rendering.md +++ b/docs/guides/react-server-rendering.md @@ -2,9 +2,9 @@ See also [Client vs. Server Rendering](https://www.shakacode.com/react-on-rails/docs/guides/client-vs-server-rendering/). -## What is the easiest way to setup a webpack configuration for server-side-rendering? +## What is the easiest way to set up a Webpack configuration for server-side-rendering? -See the example webpack setup here: [github.com/shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr). +See the example Webpack setup here: [github.com/shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr). ## What is Server Rendering? diff --git a/docs/guides/render-functions-and-railscontext.md b/docs/guides/render-functions-and-railscontext.md index 21d2927b2f..8ea8ebd0c8 100644 --- a/docs/guides/render-functions-and-railscontext.md +++ b/docs/guides/render-functions-and-railscontext.md @@ -2,29 +2,28 @@ ## Render-Functions -When you use a render-function to create react components (or renderedHtml on the server), or you -used shared redux stores, you get two params passed to your function that creates a React component: +When you use a render-function to create React components (or `renderedHtml` on the server), or you +use shared Redux stores, you get two params passed to your function that creates a React component: 1. `props`: Props that you pass in the view helper of either `react_component` or `redux_store` 2. `railsContext`: Rails contextual information, such as the current pathname. You can customize this in your config file. **Note**: The `railsContext` is not related to the concept of a ["context" for React components](https://facebook.github.io/react/docs/context.html#how-to-use-context). -These parameters (`props` and `railsContext`) will be the same regardless of either client or server -side rendering, except for the key `serverSide` based on whether or not you are server rendering. +These parameters (`props` and `railsContext`) will be the same for client- and server-side rendering, +except for the property `railsContext.serverSide` which tells you which one it is. While you could manually configure your Rails code to pass the "`railsContext` information" with the rest of your "props", the `railsContext` is a convenience because it's passed consistently to all invocations of Render-Functions. -For example, suppose you create a "render-function" called MyAppComponent. +For example, suppose you create a "render-function" called `MyAppComponent`. ```js import React from 'react'; const MyAppComponent = (props, railsContext) => - // NOTE: need to wrap in a function so this is proper React function component that can use - // hooks + // NOTE: need to wrap in a function so this is a proper React function component that can use hooks // the props get passed again, but we ignore since we use a closure // or should we @@ -39,7 +38,7 @@ export default MyAppComponent; --- -_This would be alternate API where you have to call React.createElement and the React on Rails code doesn't do that._ +_This would be an alternate API where you have to call `React.createElement` and the React on Rails code doesn't do that._ ```js import React from 'react'; @@ -60,7 +59,8 @@ export default MyAppComponent; --- -_Note: you will get a React browser console warning if you try to serverRender this since the value of `serverSide` will be different for server rendering._ +> [!NOTE] +> You will get a React browser console warning if you try to render this on the server since the value of `serverSide` will be different for server rendering. So if you register your render-function `MyAppComponent`, it will get called like: @@ -68,27 +68,29 @@ So if you register your render-function `MyAppComponent`, it will get called lik reactComponent = MyAppComponent(props, railsContext); ``` -and, similarly, any redux store is always initialized with 2 parameters: +Similarly, any Redux store is always initialized with 2 parameters: ```js reduxStore = MyReduxStore(props, railsContext); ``` -Note: you never make these calls. React on Rails makes these calls when it does either client or server rendering. You will define functions that take these 2 params and return a React component or a Redux Store. Naturally, you do not have to use second parameter of the railsContext if you do not need it. If you don't take a second parameter, then you're probably defining a React function component and you will simply return a React Element, often just JSX. +> [!NOTE] +> You never make these calls. React on Rails makes these calls when it does either client or server rendering. You will define functions that take these 2 params and return a React component or a Redux Store. Naturally, you do not have to use second parameter, `railsContext`, if you do not need it. If you don't take a second parameter, then you're probably defining a React function component and you will simply return a React Element, often just JSX. -(Note: see below [section](#multiple-react-components-on-a-page-with-one-store) on how to setup redux stores that allow multiple components to talk to the same store.) +> [!NOTE] +> See [Redux Store](https://www.shakacode.com/react-on-rails/docs/api/redux-store-api/#multiple-react-components-on-a-page-with-one-store) on how to set up Redux stores that allow multiple components to talk to the same store. -The `railsContext` has: (see implementation in file [ReactOnRails::Helper](https://github.com/shakacode/react_on_rails/tree/master/lib/react_on_rails/helper.rb), method `rails_context` for the definitive list). +The `railsContext` has: (see the implementation in [ReactOnRails::Helper](https://github.com/shakacode/react_on_rails/tree/master/lib/react_on_rails/helper.rb), method `rails_context` for the definitive list). ```ruby { - railsEnv: Rails.env + railsEnv: Rails.env, inMailer: in_mailer?, # Locale settings i18nLocale: I18n.locale, i18nDefaultLocale: I18n.default_locale, rorVersion: ReactOnRails::VERSION, - rorPro: ReactOnRails::Utils.react_on_rails_pro? + rorPro: ReactOnRails::Utils.react_on_rails_pro?, # URL settings href: request.original_url, @@ -98,10 +100,11 @@ The `railsContext` has: (see implementation in file [ReactOnRails::Helper](https port: uri.port, pathname: uri.path, # /posts search: uri.query, # id=30&limit=5 - httpAcceptLanguage: request.env["HTTP_ACCEPT_LANGUAGE"] + httpAcceptLanguage: request.env["HTTP_ACCEPT_LANGUAGE"], # Other - serverSide: boolean # Are we being called on the server or client? Note: if you conditionally + serverSide: boolean, + # Are we being called on the server or client? Note: if you conditionally # render something different on the server than the client, then React will only show the # server version! } @@ -115,7 +118,7 @@ The `railsContext` is a second param passed to your render-functions for React c ERB view file: -```ruby +```erb # Rails View <%= react_component("HelloWorld", props: { name: "Stranger" }) %> ``` @@ -138,7 +141,7 @@ export default (props, railsContext) => { ## Why is the railsContext only passed to render-functions? -There's no reason that the railsContext would ever get passed to your React component unless the value is explicitly put into the props used for rendering. If you create a react component, rather than a render-function, for use by React on Rails, then you get whatever props are passed in from the view helper, which **does not include the Rails Context**. It's trivial to wrap your component in a "render-function" to return a new component that takes both: +There's no reason that the railsContext would ever get passed to your React component unless the value is explicitly put into the props used for rendering. If you create a React component, rather than a render-function, for use by React on Rails, then you get whatever props are passed in from the view helper, which **does not include the Rails Context**. It's trivial to wrap your component in a "render-function" to return a new component that takes both: ```js import React from 'react'; @@ -157,13 +160,13 @@ Consider this line in depth: ``` -The outer `{...` is for the [JSX spread operator for attributes](https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes) and the inner `{...` is for the [Spread in object literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Spread_in_object_literals). +The outer `{...` is for the [JSX spread operator for attributes](https://legacy.reactjs.org/docs/jsx-in-depth.html#spread-attributes) and the inner `{...` is for the [Spread in object literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Spread_in_object_literals). ## Use Cases ### Heroku Preboot Considerations -[Heroku Preboot](https://devcenter.heroku.com/articles/preboot) is a feature on Heroku that allows for faster deploy times. When you promote your staging app to production, Preboot simply switches the production server to point at the staging app's container. This means it can deploy much faster since it doesn't have to rebuild anything. However, this means that if you use the [Define Plugin](https://github.com/webpack/docs/wiki/list-of-plugins#defineplugin) to provide the rails environment to your client code as a variable, that variable will erroneously still have a value of `Staging` instead of `Production`. The `Rails.env` provided at runtime in the railsContext is, however, accurate. +[Heroku Preboot](https://devcenter.heroku.com/articles/preboot) is a feature on Heroku that allows for faster deploy times. When you promote your staging app to production, Preboot simply switches the production server to point at the staging app's container. This means it can deploy much faster since it doesn't have to rebuild anything. However, this means that if you use the [Define Plugin](https://github.com/webpack/docs/wiki/list-of-plugins#defineplugin) to provide the Rails environment to your client code as a variable, that variable will erroneously still have a value of `Staging` instead of `Production`. The `Rails.env` provided at runtime in the railsContext is, however, accurate. ### Needing the current URL path for server rendering @@ -173,7 +176,7 @@ Suppose you want to display a nav bar with the current navigation link highlight Suppose you want to turn off animation when doing server side rendering. The `serverSide` value is just what you need. -## Customization of the rails_context +## Customization of the Rails context You can customize the values passed in the `railsContext` in your `config/initializers/react_on_rails.rb`. Here's how. @@ -201,4 +204,4 @@ module RenderingExtension end ``` -In this case, a prop and value for `somethingUseful` will go into the railsContext passed to all react_component and redux_store calls. You may set any values available in the view rendering context. +In this case, a prop and value for `somethingUseful` will go into the `railsContext` passed to all `react_component` and `redux_store` calls. You may set any values available in the view rendering context. diff --git a/docs/guides/rspec-configuration.md b/docs/guides/rspec-configuration.md index 6bdfc0d457..536bccedc7 100644 --- a/docs/guides/rspec-configuration.md +++ b/docs/guides/rspec-configuration.md @@ -2,39 +2,39 @@ _Click [here for minitest](https://www.shakacode.com/react-on-rails/docs/guides/minitest-configuration/)_ -# If your webpack configurations correspond to Shakapacker's default setup +# If your Webpack configurations correspond to Shakapacker's default setup -If you're able to configure your webpack configuration to be run by having your webpack configuration +If you're able to configure your Webpack configuration to be run by having your Webpack configuration returned by the files in `/config/webpack`, then you have 2 options to ensure that your files are -compiled by webpack before running tests and during production deployment: +compiled by Webpack before running tests and during production deployment: 1. **Use Shakapacker's compile option**: Configure your `config/shakapacker.yml` so that `compile: true` is for `test` and `production` environments. Ensure that your `source_path` is correct, or else `Shakapacker` won't correctly detect changes. -2. **Use the react_on_rails settings and helpers**. Use the settings in `config/initializers/react_on_rails.rb`. Refer to [docs/configuration](https://www.shakacode.com/react-on-rails/docs/guides/configuration/). +2. **Use the React on Rails settings and helpers**. Use the settings in `config/initializers/react_on_rails.rb`. Refer to [docs/configuration](https://www.shakacode.com/react-on-rails/docs/guides/configuration/). ```yml config.build_test_command = "NODE_ENV=test RAILS_ENV=test bin/shakapacker" ``` -Which should you use? If you're already using the `Shakapacker` way to configure webpack, then +Which should you use? If you're already using the `Shakapacker` way to configure Webpack, then you can keep things simple and use the `Shakapacker` options. # Checking for stale assets using React on Rails -Because you will probably want to run RSpec tests that rely on compiled webpack assets (typically, your integration/feature specs where `js: true`), you will want to ensure you don't accidentally run tests on missing or stale webpack assets. If you did use stale Webpack assets, you will get invalid test results as your tests do not use the very latest JavaScript code. +Because you will probably want to run RSpec tests that rely on compiled Webpack assets (typically, your integration/feature specs where `js: true`), you will want to ensure you don't accidentally run tests on missing or stale Webpack assets. If you did use stale Webpack assets, you will get invalid test results as your tests do not use the very latest JavaScript code. As mentioned above, you can configure `compile: true` in `config/shakapacker.yml` _if_ you've got configuration for -your webpack in the standard `Shakapacker` spot of `config/webpack/.js` +your Webpack in the standard `Shakapacker` spot of `config/webpack/.js` -ReactOnRails also provides a helper method called `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`. Call this method from inside of the `RSpec.configure` block in your `spec/rails_helper.rb` file, passing the config as an argument. See file [lib/react_on_rails/test_helper.rb](https://github.com/shakacode/react_on_rails/tree/master/lib/react_on_rails/test_helper.rb) for more details. You can customize this to your particular needs by replacing any of the default components used by `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`. +React on Rails also provides a helper method called `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`. Call this method from inside of the `RSpec.configure` block in your `spec/rails_helper.rb` file, passing the config as an argument. See file [lib/react_on_rails/test_helper.rb](https://github.com/shakacode/react_on_rails/tree/master/lib/react_on_rails/test_helper.rb) for more details. You can customize this to your particular needs by replacing any of the default components used by `ReactOnRails::TestHelper.configure_rspec_to_compile_assets`. ```ruby RSpec.configure do |config| ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) ``` -You can pass one or more RSpec metatags as an optional second parameter to this helper method if you want this helper to run on examples other than where `:js`, `:server_rendering`, or `:controller` (those are the defaults). The helper will compile webpack files at most once per test run. The helper will not compile the webpack files unless they are out of date (stale). The helper is configurable in terms of what command is used to prepare the files. If you don't specify these metatags for your relevant JavaScript tests, then you'll need to do the following. +You can pass one or more RSpec metatags as an optional second parameter to this helper method if you want this helper to run on examples other than where `:js`, `:server_rendering`, or `:controller` (those are the defaults). The helper will compile Webpack files at most once per test run. The helper will not compile the webpack files unless they are out of date (stale). The helper is configurable in terms of what command is used to prepare the files. If you don't specify these metatags for your relevant JavaScript tests, then you'll need to do the following. If you are using Webpack to build CSS assets, you should do something like this to ensure that you assets are built for any specs under `specs/requests` or `specs/features`: @@ -51,14 +51,14 @@ Please take note of the following: - This utility uses your `build_test_command` to build the static generated files. This command **must not** include the `--watch` option. If you have different server and client bundle files, this command **must** create all the bundles. If you are using Shakapacker, the default value will come from the `config/shakapacker.yml` value for the `public_output_path` and the `source_path` -- If you add an older file to your source files, that is already older than the produced output files, no new recompilation is done. The solution to this issue is to clear out your directory of webpack generated files when adding new source files that may have older dates. +- If you add an older file to your source files, that is already older than the produced output files, no new recompilation is done. The solution to this issue is to clear out your directory of Webpack generated files when adding new source files that may have older dates. -- By default, the webpack processes look in the webpack generated files folder, configured via the `config/shakapacker.yml` config values of `public_root_path` and `public_output_path`. If the webpack generated files folder is missing, is empty, or contains files in the `config.webpack_generated_files` list with `mtime`s older than any of the files in your `client` folder, the helper will recompile your assets. +- By default, the Webpack processes look in the Webpack generated files folder, configured via the `config/shakapacker.yml` config values of `public_root_path` and `public_output_path`. If the webpack generated files folder is missing, is empty, or contains files in the `config.webpack_generated_files` list with `mtime`s older than any of the files in your `client` folder, the helper will recompile your assets. The following `config/react_on_rails.rb` settings **must** match your setup: ```ruby - # Define the files we need to check for webpack compilation when running tests. + # Define the files we need to check for Webpack compilation when running tests. config.webpack_generated_files = %w( manifest.json ) # OR if you're not hashing the server-bundle.js, then you should include your server-bundle.js in the list. @@ -66,7 +66,7 @@ The following `config/react_on_rails.rb` settings **must** match your setup: # If you are using the 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. + # to automatically refresh your Webpack assets on every test run. config.build_test_command = "yarn run build:test" ``` diff --git a/docs/guides/tutorial.md b/docs/guides/tutorial.md index da4739cfc1..af754fab69 100644 --- a/docs/guides/tutorial.md +++ b/docs/guides/tutorial.md @@ -60,7 +60,7 @@ Trying out **React on Rails** is super easy, so long as you have the basic prere Then we need to create a fresh Rails application as follows. -First, be sure to run `rails -v` and check you are using Rails 5.1.3 or above. If you are using an older version of Rails, you'll need to install webpacker with react per the instructions [here](https://github.com/rails/webpacker). +First, be sure to run `rails -v` and check you are using Rails 5.1.3 or above. If you are using an older version of Rails, you'll need to install Webpacker with React per the instructions [here](https://github.com/rails/webpacker). ```bash # For Rails 6.x @@ -113,7 +113,7 @@ one by one or enter `a` to replace all configuration files required by the proje You can check the diffs before you commit to see what changed. Note, using `redux` is no longer recommended as the basic installer uses React Hooks. -If you want the redux install, run: +If you want the Redux install, run: ```bash rails generate react_on_rails:install --redux @@ -172,7 +172,7 @@ heroku buildpacks:add --index 1 heroku/nodejs ## Swap out sqlite for postgres: -Heroku requires your app to use Postgresql. If you have not setup your app +Heroku requires your app to use Postgresql. If you have not set up your app with Postgresql, you need to change your app settings to use this database. Run the following command (in Rails 6+): @@ -215,7 +215,7 @@ production: database: ror_production ``` -Then you need to setup postgres so you can run locally: +Then you need to set up Postgres so you can run locally: ```bash rake db:setup diff --git a/docs/guides/upgrading-react-on-rails.md b/docs/guides/upgrading-react-on-rails.md index 029cc7624d..0acf7c323c 100644 --- a/docs/guides/upgrading-react-on-rails.md +++ b/docs/guides/upgrading-react-on-rails.md @@ -26,7 +26,7 @@ In summary: ### Recent versions -Make sure that you are on a relatively more recent version of rails and webpacker. Yes, the [rails/webpacker](https://github.com/rails/webpacker) gem is required! +Make sure that you are on a relatively more recent version of Rails and Webpacker. Yes, the [rails/webpacker](https://github.com/rails/webpacker) gem is required! v12 is tested on Rails 6. It should work on Rails v5. If you're on any older version, and v12 doesn't work, please file an issue. @@ -37,7 +37,7 @@ If you still need that feature, please file an issue. ### i18n default format changed to JSON -- If you're using the internalization helper, then set `config.i18n_output_format = 'js'`. You can +- If you're using the internationalization helper, then set `config.i18n_output_format = 'js'`. You can later update to the default JSON format as you will need to update your usage of that file. A JSON format is more efficient. @@ -130,7 +130,7 @@ wrapper such that you're returning a function rather than a React Element, then: ### Custom Webpack build file -The default value for `extract_css` is **false** in `config/webpack.yml`. Custom webpack builds should set this value to true or else no CSS link tags are generated. You have a custom webpack build if you are not using [rails/webpacker](https://github.com/rails/webpacker) to setup your Webpack configuration. +The default value for `extract_css` is **false** in `config/webpack.yml`. Custom Webpack builds should set this value to true, or else no CSS link tags are generated. You have a custom Webpack build if you are not using [rails/webpacker](https://github.com/rails/webpacker) to set up your Webpack configuration. ```yml default: &default # other stuff @@ -157,25 +157,25 @@ Pretty simple: Webpacker provides areas of value: -- View helpers that support bypassing the asset pipeline, which allows you to avoid double minification and enable source maps in production. This is 100% a best practice as source maps in production greatly increases the value of services such as HoneyBadger or Sentry. -- A default Webpack config so that you only need to do minimal modifications and customizations. However, if you're doing server rendering, you may not want to give up control. Since Webpacker's default webpack config is changing often, we at Shakacode can give you definitive advice on webpack configuration best practices. In general, if you're happy with doing your own Webpack configuration, then we suggest using the `client` strategy discussed below. Most corporate projects will prefer having more control than direct dependence on webpacker easily allows. +- View helpers that support bypassing the asset pipeline, which allows you to avoid double minification and enable source maps in production. This is 100% a best practice, as source maps in production greatly increases the value of services such as HoneyBadger or Sentry. +- A default Webpack config so that you only need to do minimal modifications and customizations. However, if you're doing server rendering, you may not want to give up control. Since Webpacker's default Webpack config is changing often, we at Shakacode can give you definitive advice on Webpack configuration best practices. In general, if you're happy with doing your own Webpack configuration, then we suggest using the `client` strategy discussed below. Most corporate projects will prefer having more control than direct dependence on webpacker easily allows. ### Integrating Webpacker -Reason for doing this: This enables your webpack bundles to bypass the Rails asset pipeline and it's extra minification, enabling you to use source-maps in production, while still maintaining total control over everything in the client directory +Reason for doing this: This enables your Webpack bundles to bypass the Rails asset pipeline and its extra minification, enabling you to use source-maps in production, while still maintaining total control over everything in the client directory. #### From version 7 or lower ##### ...while keeping your `client` directory -- `.gitignore`: add `/public/webpack/*` -- `Gemfile`: bump `react_on_rails` and add `webpacker` -- layout views: anything bundled by webpack will need to be requested by a `javascript_pack_tag` or `stylesheet_pack_tag`. +- `.gitignore`: add `/public/webpack/*`. +- `Gemfile`: bump `react_on_rails` and add `webpacker`. +- layout views: anything bundled by Webpack will need to be requested by a `javascript_pack_tag` or `stylesheet_pack_tag`. - Search your codebase for javascript_include_tag. Use the - `config/initializers/assets.rb`: we no longer need to modify `Rails.application.config.assets.paths` or append anything to `Rails.application.config.assets.precompile`. - `config/initializers/react_on_rails.rb`: - - Delete `config.generated_assets_dir`. Webpacker's config now supplies this information - - Replace `config.npm_build_(test|production)_command` with `config.build_(test|production)_command` + - Delete `config.generated_assets_dir`. Webpacker's config now supplies this information. + - Replace `config.npm_build_(test|production)_command` with `config.build_(test|production)_command`. - `config/webpacker.yml`: start with our [example config](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/config/webpacker.yml) (feel free to modify it as needed). I recommend setting dev_server.hmr to false however since HMR is currently broken. - `client/package.json`: bump `react_on_rails` (I recommend bumping `webpack` as well). You'll also need `js-yaml` if you're not already using `eslint` and `webpack-manifest-plugin` regardless. @@ -192,7 +192,7 @@ const configPath = path.resolve('..', 'config'); const { output } = webpackConfigLoader(configPath); ``` -- That output variable will be used for webpack's `output` rules: +- That output variable will be used for Webpack's `output` rules: ``` output: { @@ -229,7 +229,7 @@ const { output } = webpackConfigLoader(configPath); - Move your entry point files to `app/javascript/packs` - Either: - Move all your source code to `app/javascript/bundles`, move your linter configs to the root directory, and then delete the `client` directory - - or just delete the webpack config and remove webpack, its loaders, and plugins from your `client/package.json`. + - or just delete the Webpack config and remove Webpack, its loaders, and plugins from your `client/package.json`. ...and you're done. @@ -239,11 +239,11 @@ For an example of upgrading, see [react-webpack-rails-tutorial/pull/416](https:/ - Breaking Configuration Changes - 1. Added `config.node_modules_location` which defaults to `""` if Webpacker is installed. You may want to set this to 'client'`to`config/initializers/react_on_rails.rb`to keep your node_modules inside of`/client` + 1. Added `config.node_modules_location` which defaults to `""` if Webpacker is installed. You may want to set this to `'client'` in `config/initializers/react_on_rails.rb` to keep your `node_modules` inside the `/client` directory. 2. Renamed - - config.npm_build_test_command ==> config.build_test_command - - config.npm_build_production_command ==> config.build_production_command + - config.npm_build_test_command ==> config.build_test_command + - config.npm_build_production_command ==> config.build_production_command - Update the gemfile. Switch over to using the webpacker gem. @@ -251,7 +251,7 @@ For an example of upgrading, see [react-webpack-rails-tutorial/pull/416](https:/ gem "webpacker" ``` -- Update for the renaming in the `WebpackConfigLoader` in your webpack configuration. +- Update for the renaming in the `WebpackConfigLoader` in your Webpack configuration. You will need to rename the following object properties: - webpackOutputPath ==> output.path @@ -297,7 +297,7 @@ gem "webpacker" - Find your `webpacker_lite.yml` and rename it to `webpacker.yml` - Consider copying a default webpacker.yml setup such as https://github.com/shakacode/react-on-rails-v9-rc-generator/blob/master/config/webpacker.yml - - If you are not using the webpacker webpacker setup, be sure to put in `compile: false` in the `default` section. + - If you are not using the webpacker Webpack setup, be sure to put in `compile: false` in the `default` section. - Alternately, if you are updating from webpacker_lite, you can manually change these: - Add a default setting ``` diff --git a/docs/guides/webpack-configuration.md b/docs/guides/webpack-configuration.md index 3a14e713e8..16067ca7fb 100644 --- a/docs/guides/webpack-configuration.md +++ b/docs/guides/webpack-configuration.md @@ -6,8 +6,8 @@ [Shakapacker](https://github.com/shakcode/shakapacker) (the official successor of [rails/webpacker](https://github.com/rails/webpacker)) is the Ruby gem that mainly gives us 2 things: -1. View helpers for placing the webpack bundles on your Rails views. React on Rails depends on these view helpers. -2. A layer of abstraction on top of Webpack customization. The base setup works great for the client side webpack configuration. +1. View helpers for placing the Webpack bundles on your Rails views. React on Rails depends on these view helpers. +2. A layer of abstraction on top of Webpack customization. The base setup works great for the client-side Webpack configuration. To get a deeper understanding of Shakapacker, watch [RailsConf 2020 CE - Webpacker, It-Just-Works, But How? by Justin Gordon](https://youtu.be/sJLoOpc5LD8). @@ -22,15 +22,15 @@ A key decision in your use React on Rails is whether you go with the Shakapacker ## Option 1: Default Generator Setup: Shakapacker app/javascript -Typical Shakapacker apps have a standard directory structure as documented [here](https://github.com/shakacode/shakapacker/blob/master/README.md#configuration-and-code). If you follow the steps in the the [basic tutorial](https://www.shakacode.com/react-on-rails/docs/guides/tutorial/), you will see this pattern in action. In order to customize the Webpack configuration, you need to consult with the [webpack configuration](https://www.shakacode.com/react-on-rails/docs/javascript/webpack/). +Typical Shakapacker apps have a standard directory structure as documented [here](https://github.com/shakacode/shakapacker/blob/master/README.md#configuration-and-code). If you follow [the basic tutorial](https://www.shakacode.com/react-on-rails/docs/guides/tutorial/), you will see this pattern in action. In order to customize the Webpack configuration, consult [Webpack Tips](https://www.shakacode.com/react-on-rails/docs/javascript/webpack/). -The _advantage_ of using Shakapacker to configure Webpack is that there is very little code needed to get started, and you don't need to understand really anything about webpack customization. +The _advantage_ of using Shakapacker to configure Webpack is that there is very little code needed to get started, and you don't need to understand really anything about Webpack customization. ## Option 2: Traditional React on Rails using the /client directory -Until version 9, all React on Rails apps used the `/client` directory for configuring React on Rails in terms of the configuration of Webpack and location of your JavaScript and webpack files, including the `node_modules` directory. Version 9 changed the default to `/` for the `node_modules` location using this value in `config/initializers/react_on_rails.rb`: `config.node_modules_location`. +Until version 9, all React on Rails apps used the `/client` directory for configuring React on Rails in terms of the configuration of Webpack and location of your JavaScript and Webpack files, including the `node_modules` directory. Version 9 changed the default to `/` for the `node_modules` location using this value in `config/initializers/react_on_rails.rb`: `config.node_modules_location`. -You can access values in the `config/shakapacker.yml` +You can access values from `config/shakapacker.yml`: ```js const { config, devServer } = require('shakapacker'); diff --git a/docs/home.md b/docs/home.md index 786aa10e02..73083556b9 100644 --- a/docs/home.md +++ b/docs/home.md @@ -17,9 +17,9 @@ ## Example Apps -1. [spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy) example repo for a simple configuration of webpack via the `shakacode/shakapacker` gem +1. [spec/dummy](https://github.com/shakacode/react_on_rails/tree/master/spec/dummy) example repo for a simple configuration of Webpack via the `shakacode/shakapacker` gem that supports SSR. -2. Example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_demo_ssr_hmr) for a new way to setup the creation of your SSR bundle with `shakacode/shakapacker`. +2. Example repo of [React on Rails Tutorial With SSR, HMR fast refresh, and TypeScript](https://github.com/shakacode/react_on_rails_demo_ssr_hmr) for a new way to set up the creation of your SSR bundle with `shakacode/shakapacker`. 3. Live, [open source](https://github.com/shakacode/react-webpack-rails-tutorial), example of this gem, see [reactrails.com](http://reactrails.com). # Other Resources diff --git a/docs/javascript/angular-js-integration-migration.md b/docs/javascript/angular-js-integration-migration.md index 23ac7524e1..74ce803ad4 100644 --- a/docs/javascript/angular-js-integration-migration.md +++ b/docs/javascript/angular-js-integration-migration.md @@ -4,7 +4,7 @@ ## Assets Handling -Ideally, you should have your JavaScript libraries packaged by `webpack` and gathered by `yarn`. If you have not already done this, then you can setup the `ReactOnRails` default JS code directory of `/client` to load the JS libraries related to AngularJS, etc. You can configure Webpack to globally export these libraries, so inclusion this way will be no different than using the Rails asset pipeline. However, so long as you _understand_ how your JavaScript will eventually make its way onto your main layout, you will be OK. +Ideally, you should have your JavaScript libraries packaged by `webpack` and gathered by `yarn`. If you have not already done this, then you can set up the `ReactOnRails` default JS code directory of `/client` to load the JS libraries related to AngularJS, etc. You can configure Webpack to globally export these libraries, so inclusion this way will be no different from using the Rails asset pipeline. However, so long as you _understand_ how your JavaScript will eventually make its way onto your main layout, you will be OK. ## Styling and CSS Modules diff --git a/docs/javascript/capistrano-deployment.md b/docs/javascript/capistrano-deployment.md index 8b1c1366fc..f071e39592 100644 --- a/docs/javascript/capistrano-deployment.md +++ b/docs/javascript/capistrano-deployment.md @@ -1,8 +1,8 @@ # Capistrano Deployment -Make sure ReactOnRails is working in the development environment. +First, make sure ReactOnRails is working in the development environment. -Add the following to development your Gemfile and bundle install. +Add the following to your Gemfile: ```ruby group :development do @@ -10,16 +10,16 @@ group :development do end ``` -Then run Bundler to ensure Capistrano is downloaded and installed. +Then run Bundler to ensure Capistrano is downloaded and installed: ```sh -$ bundle install +bundle install ``` -Add the following in your Capfile. +Add the following to your Capfile: ```ruby require 'capistrano/yarn' ``` -If the deployment is taking too long or getting stuck at `assets:precompile` stage, it is probably because of memory. Webpack consumes a lot of memory so if possible, try increasing the RAM of your server. +If the deployment is taking too long or getting stuck at `assets:precompile` stage, it is probably because of memory. Webpack consumes a lot of memory, so if possible, try increasing the RAM of your server. diff --git a/docs/javascript/code-splitting.md b/docs/javascript/code-splitting.md index f2056d8236..76a48473e5 100644 --- a/docs/javascript/code-splitting.md +++ b/docs/javascript/code-splitting.md @@ -6,7 +6,7 @@ if you would be interested in help with code splitting using --- -What is code splitting? From the webpack documentation: +What is code splitting? From the Webpack documentation: > For big web apps it’s not efficient to put all code into a single file, especially if some blocks of code are only required under some circumstances. Webpack has a feature to split your codebase into “chunks” which are loaded on demand. Some other bundlers call them “layers”, “rollups”, or “fragments”. This feature is called “code splitting”. @@ -20,11 +20,11 @@ Let's say you're requesting a page that needs to fetch a code chunk from the ser > (server) `
<% content_for :title do %> @@ -104,6 +104,6 @@ make sense to use react_component_hash without server rendering: So now we're able to insert received title tag to our application layout: -```ruby +```erb <%= yield(:title) if content_for?(:title) %> ``` diff --git a/docs/javascript/react-router.md b/docs/javascript/react-router.md index 64fc15b460..3cae7cbdf1 100644 --- a/docs/javascript/react-router.md +++ b/docs/javascript/react-router.md @@ -2,7 +2,7 @@ _This article needs updating for the latest version of React Router_ # Using React Router -React on Rails supports the use of React Router. Client-side code doesn't need any special configuration for the React on Rails gem. Implement React Router how you normally would. Note, you might want to avoid using Turbolinks as both Turbolinks and React-Router will be trying to handle the back and forward buttons. If you get this figured out, please do share with the community! Otherwise, you might have to tweak the basic settings for Turbolinks, and this may or may not be worth the effort. +React on Rails supports the use of React Router. Client-side code doesn't need any special configuration for the React on Rails gem. Implement React Router how you normally would. Note, you might want to avoid using Turbolinks as both Turbolinks and React Router will be trying to handle the back and forward buttons. If you get this figured out, please do share with the community! Otherwise, you might have to tweak the basic settings for Turbolinks, and this may or may not be worth the effort. If you are working with the HelloWorldApp created by the react_on_rails generator, then the code below corresponds to the module in `client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx`. @@ -24,7 +24,7 @@ const RouterApp = (props, railsContext) => { }; ``` -For a fleshed out integration of react_on_rails with react-router, check out [React Webpack Rails Tutorial Code](https://github.com/shakacode/react-webpack-rails-tutorial), specifically the files: +For a fleshed out integration of React on Rails with React Router, check out [React Webpack Rails Tutorial Code](https://github.com/shakacode/react-webpack-rails-tutorial), specifically the files: - [react-webpack-rails-tutorial/client/app/bundles/comments/routes/routes.jsx](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/app/bundles/comments/routes/routes.jsx) @@ -37,9 +37,9 @@ For a fleshed out integration of react_on_rails with react-router, check out [Re Your Render-Function may not return an object with the property `renderedHtml`. Thus, you call `renderToString()` and return an object with this property. -This example **only applies to server rendering** and should be only used in the server side bundle. +This example **only applies to server-side rendering** and should only be used in the server-side bundle. -From the [original example in the ReactRouter docs](https://github.com/ReactTraining/react-router/blob/v4.3.1/packages/react-router-dom/docs/guides/server-rendering.md) +From the [original example in the React Router docs](https://github.com/ReactTraining/react-router/blob/v4.3.1/packages/react-router-dom/docs/guides/server-rendering.md) ```javascript import React from 'react'; @@ -61,7 +61,7 @@ const ReactServerRenderer = (props, railsContext) => { const { location } = railsContext; - const html = ReactDOMServer.renderToString( + const html = renderToString( @@ -76,4 +76,5 @@ const ReactServerRenderer = (props, railsContext) => { // we're good, send the response return { renderedHtml: html }; } +}; ``` diff --git a/docs/javascript/server-rendering-tips.md b/docs/javascript/server-rendering-tips.md index c83b010c0b..64bfa80059 100644 --- a/docs/javascript/server-rendering-tips.md +++ b/docs/javascript/server-rendering-tips.md @@ -4,30 +4,30 @@ For the best performance with Server Rendering, consider using [React on Rails P ## General Tips -- Your code can't reference `document`. Server side JS execution does not have access to `document`, - so jQuery and some other libs won't work in this environment. You can debug this by putting in +- Your code can't reference `document`. Server-side JS execution does not have access to `document`, + so jQuery and some other libraries won't work in this environment. You can debug this by putting in `console.log` statements in your code. - You can conditionally avoid running code that references document by either checking if `window` is defined or using the "railsContext" - your top level react component. Since the passed in props Hash from the view helper applies to - client and server side code, the best way to do this is to use a Render-Function. -- If you're serious about server rendering, it's worth the effort to have different entry points for client and server rendering. It's worth the extra complexity. The point is that you have separate files for top level client or server side, and you pass some extra option indicating that rendering is happening server side. + in your top-level React component. Since the Hash passed in `props` from the view helper applies to + both client- and server-side code, the best way to do this is to use a Render-Function. +- If you're serious about server-side rendering, it's worth the effort to have different entry points for client-side and server-side rendering. It's worth the extra complexity. The point is that you have separate files for top-level client and server side, and you pass some extra option indicating that rendering is happening server-side. - You can enable Node.js server rendering via [React on Rails Pro](https://github.com/shakacode/react_on_rails/wiki). ## Troubleshooting Server Rendering -1. First be sure your code works with server rendering disabled (`prerender: false`) -2. Be sure that `config.trace` is true. You will get the server invocation code that renders your component. If you're not using Shakapacker, you will also get the whole file used to setup the JavaScript context. +1. First make sure your code works with server rendering disabled (`prerender: false`). +2. Set `config.trace` to true. You will get the server invocation code that renders your component. If you're not using Shakapacker, you will also get the whole file used to set up the JavaScript context. ## CSS -Server bundles must always have CSS Extracted +Server bundles must always have CSS extracted. ## setTimeout, setInterval, and clearTimeout -These methods are polyfilled for server rendering to be no-ops. We log calls to these when in `trace` mode. In the past, some libraries, namely babel-polyfill, did call setTimout. +These methods are polyfilled for server rendering to be no-ops. We log calls to these when in `trace` mode. In the past, some libraries, namely babel-polyfill, did call `setTimeout`. -Here's an example of this which shows the line numbers that end up calling setTimeout: +Here's an example of this, showing the line numbers that end up calling `setTimeout`: ```text ➜ ~/shakacode/react_on_rails/gen-examples/examples/basic-server-rendering (add-rails-helper-to-generator u=) ✗ export SERVER_TRACE_REACT_ON_RAILS=TRUE diff --git a/docs/javascript/troubleshooting-when-using-shakapacker.md b/docs/javascript/troubleshooting-when-using-shakapacker.md index cb3161c92e..396611b255 100644 --- a/docs/javascript/troubleshooting-when-using-shakapacker.md +++ b/docs/javascript/troubleshooting-when-using-shakapacker.md @@ -9,7 +9,7 @@ ## The failure -Configuring Webpack to embed the runtime in each chunk and calling `react_component` twice in a rails view/partial causes the client render to crash with the following error: +Configuring Webpack to embed the runtime in each chunk and calling `react_component` twice in a Rails view/partial causes the client render to crash with the following error: ``` Could not find component registered with name XXX. Registered component names include [ YYY ]. Maybe you forgot to register the component? @@ -47,7 +47,7 @@ optimization: { ## The problem -Configuring Webpack to embed the runtime in each chunk and calling `react_component` twice in a rails view/partial causes the client render to crash. +Configuring Webpack to embed the runtime in each chunk and calling `react_component` twice in a Rails view/partial causes the client render to crash. Read more at https://github.com/shakacode/react_on_rails/issues/1558. diff --git a/docs/javascript/troubleshooting-when-using-webpacker.md b/docs/javascript/troubleshooting-when-using-webpacker.md index c03290666a..b75c890e8e 100644 --- a/docs/javascript/troubleshooting-when-using-webpacker.md +++ b/docs/javascript/troubleshooting-when-using-webpacker.md @@ -38,7 +38,7 @@ Failure/Error: raise Webpacker::Manifest::MissingEntryError, missing_file_from_m ... ``` -At the same time dev/prod environments works fine (with extra webpack calling step outside rails). +At the same time, dev/prod environments work fine (with extra Webpack calling step outside Rails). ## Configs diff --git a/docs/javascript/webpack.md b/docs/javascript/webpack.md index b48a1b05c5..496dfc58b5 100644 --- a/docs/javascript/webpack.md +++ b/docs/javascript/webpack.md @@ -10,7 +10,7 @@ Yarn v1 is our current recommendation! ## Entry Points -You should ensure you configure the entry points correctly for webpack if you want to break out libraries into a "vendor" bundle where your libraries are packaged separately from your app's code. If you send web clients your vendor bundle separately from your app bundles, then web clients might have the vendor bundle cached while they receive updates for your app. +You should ensure you configure the entry points correctly for Webpack if you want to break out libraries into a "vendor" bundle where your libraries are packaged separately from your app's code. If you send web clients your vendor bundle separately from your app bundles, then web clients might have the vendor bundle cached while they receive updates for your app. Webpack v2 makes this very convenient! See: diff --git a/docs/misc/doctrine.md b/docs/misc/doctrine.md index 0925931858..3995779829 100644 --- a/docs/misc/doctrine.md +++ b/docs/misc/doctrine.md @@ -12,12 +12,12 @@ Besides the project objective, let's stick with the "Rails Doctrine" and keep th The React on Rails setup provides several key components related to front-end developer happiness: -1. [Hot reloading of both JavaScript and CSS](https://gaearon.github.io/react-hot-loader/), via the [webpack dev server](https://webpack.github.io/docs/webpack-dev-server.html). This works for both using an [express server](http://expressjs.com/) to load stubs for the ajax requests, as well as using a live Rails server. **Oh yes**, your Rails server can do hot reloading! +1. [Hot reloading of both JavaScript and CSS](https://gaearon.github.io/react-hot-loader/), using the [webpack-dev-server](https://webpack.github.io/docs/webpack-dev-server.html) package. This works for both using an [Express server](http://expressjs.com/) to load stubs for the ajax requests, as well as using a live Rails server. **Oh yes**, your Rails server can do hot reloading! 2. [CSS modules](https://github.com/css-modules/webpack-demo) which remove the madness of a global namespace for CSS. We organize our CSS (Sass, actually) right next to our JavaScript React component files. This means no more creating long class names to ensure that CSS picks up the right styles. 3. [ES6 JavaScript](http://es6-features.org/#Constants) is a great language for client side coding, much more so than Ruby due to the asynchronous nature of UI programming. 4. JavaScript libraries and tooling work better in the native node way, rather than via some aspect of Sprockets and the Rails Asset Pipeline. We find way less frustration this way, especially from being able to get the latest advances with the rest of the JavaScript community. Why complicated beautiful JavaScript tooling Rails asset pipeline complexity? -5. We want our JavaScript from npm. Getting JavaScript from rubygems.org is comparatively frustrating. -6. Happiness for us is actively participating in open source, so we want to be where the action is, which is with the npm libraries on github.com. +5. We want our JavaScript from NPM. Getting JavaScript from rubygems.org is comparatively frustrating. +6. Happiness for us is actively participating in open source, so we want to be where the action is, which is with the NPM libraries on github.com. 7. You can get set up on React on Rails **FAST** using our application generator. 8. By placing all client-side development inside of the `/client` directory, pure JavaScript developers can productively do development separate from Rails. Instead of Rails APIs, stub APIs on an express server can provide a simple backend, allowing for rapid iteration of UI prototypes. 9. Just because we're not relying on the Rails asset pipeline for ES6 conversion does not mean that we're deploying Rails apps in any different way. We still use the asset pipeline to include our Webpack compiled JavaScript. This only requires a few small modifications, as explained in [our heroku deployment documentation](https://www.shakacode.com/react-on-rails/docs/deployment/heroku-deployment/). @@ -40,9 +40,9 @@ Here's the chef's selection from the React on Rails community: - [Bootstrap](http://getbootstrap.com/), loaded from [bootstrap-loader](https://github.com/shakacode/bootstrap-loader/). Common UI styles. - [Lodash](https://lodash.com/): Swiss army knife of utilities. -- [React](https://facebook.github.io/react/): UI components. -- [React-Router](https://github.com/reactjs/react-router): Provider of deep links for client-side application. -- [Redux](https://github.com/reactjs/redux): Flux implementation (aka "state container"). +- [React](https://react.dev/): UI components. +- [React Router](https://reactrouter.com/): Provider of deep links for client-side application. +- [Redux](https://redux.js.org/): Flux implementation (aka "state container"). ### JavaScript Tooling diff --git a/docs/misc/style.md b/docs/misc/style.md index 4d765034ee..72245aabb5 100644 --- a/docs/misc/style.md +++ b/docs/misc/style.md @@ -4,7 +4,6 @@ This document describes the coding style of [ShakaCode](http://www.shakacode.com - Use of linters with our standard linter configuration. - References to existing style guidelines that support the linter configuration. -- Anything additional goes next. ## Client Side JavaScript and React diff --git a/docs/misc/tips.md b/docs/misc/tips.md index f2f7ff3ef2..8ea0a236f8 100644 --- a/docs/misc/tips.md +++ b/docs/misc/tips.md @@ -1,12 +1,8 @@ # Tips -- **DO NOT RUN `rails s`** and instead run +- Make sure to run the Rails app using `foreman start -f Procfile.dev` (or `overmind` or other similar command) and **not `rails s`** to automatically start the Webpack file watchers that will regenerate your JavaScript. Note that RSpec does not automatically rebuild the bundle files, so you could get incorrect results from your tests if you change the client code and do not rebuild the bundles. The same problem occurs when pulling down changes from GitHub and running tests without first rebuilding the bundles. - `foreman start -f Procfile.dev` - - to automatically start the webpack file watchers that will regenerate your JavaScript. Note, RSpec does not automatically rebuild the bundle files, so you could get incorrect results from your tests if you change the client code and do not rebuild the bundles. The same problem occurs when pulling down changes from GitHub and running tests without first rebuilding the bundles. - -- The default for rendering right now is `prerender: false`. **NOTE:** Server side rendering does not work for some components that use an async setup for server rendering. You can configure the default for prerender in your config. +- The default for rendering right now is `prerender: false`. **NOTE:** Server-side rendering does not work for some components that use an async setup for server rendering. You can configure the default for prerender in your config. - You can expose either a React component or a function that returns a React component. If you wish to create a React component via a function, rather than simply props, then you need to set the property "generator" on that helper invocation to true (or change the defaults). When that is done, the function is invoked with a single parameter of "props", and that function should return a React element. -- Be sure you can first render your react component **client only** before you try to debug server rendering! -- Open up the HTML source and take a look at the generated HTML and the JavaScript to see what's going on under the covers. Note that when server rendering is turned on, then you'll see the server rendered react components. When server rendering is turned off, then you'll only see the `div` element where the in-line JavaScript will render the component. You might also notice how the props you pass (a Ruby Hash) becomes in-line JavaScript on the HTML page. +- Be sure you can first render your React component **on the client side only** before you try to debug server rendering! +- Open up the HTML source and take a look at the generated HTML and the JavaScript to see what's going on under the covers. Note that when server rendering is turned on, then you'll see the server-rendered React components. When server rendering is turned off, then you'll only see the `div` element where the in-line JavaScript will render the component. You might also notice how the props you pass (a Ruby Hash) becomes in-line JavaScript on the HTML page. diff --git a/docs/outdated/deferred-rendering.md b/docs/outdated/deferred-rendering.md index 4b858e0a87..9badd2a41e 100644 --- a/docs/outdated/deferred-rendering.md +++ b/docs/outdated/deferred-rendering.md @@ -5,7 +5,7 @@ Please see [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) i --- -What is code splitting? From the webpack documentation: +What is code splitting? From the Webpack documentation: > For big web apps it’s not efficient to put all code into a single file, especially if some blocks of code are only required under some circumstances. Webpack has a feature to split your codebase into “chunks” which are loaded on demand. Some other bundlers call them “layers”, “rollups”, or “fragments”. This feature is called “code splitting”. @@ -23,13 +23,13 @@ Different markup is generated on the client than on the server. Why does this ha ## Solution -To prevent this, you have to wait until the code chunk is fetched before doing the initial render on the client side. To accomplish this, react on rails allows you to register a renderer. This works just like registering a Render-Function, except that the function you pass takes three arguments: `renderer(props, railsContext, domNodeId)`, and is responsible for calling `ReactDOM.render` or `ReactDOM.hydrate` to render the component to the DOM. React on rails will automatically detect when a Render-Function takes three arguments, and will **not** call `ReactDOM.render` or `ReactDOM.hydrate`, instead allowing you to control the initial render yourself. Note, you have to be careful to call `ReactDOM.hydrate` rather than `ReactDOM.render` if you are server rendering. +To prevent this, you have to wait until the code chunk is fetched before doing the initial render on the client side. To accomplish this, React on Rails allows you to register a renderer. This works just like registering a Render-Function, except that the function you pass takes three arguments: `renderer(props, railsContext, domNodeId)`, and is responsible for calling `ReactDOM.render` or `ReactDOM.hydrate` to render the component to the DOM. React on rails will automatically detect when a Render-Function takes three arguments, and will **not** call `ReactDOM.render` or `ReactDOM.hydrate`, instead allowing you to control the initial render yourself. Note, you have to be careful to call `ReactDOM.hydrate` rather than `ReactDOM.render` if you are server rendering. ## Server vs. Client Code Caveats -If you're going to try to do code splitting with server rendered routes, you'll probably need to use separate route definitions for client and server to prevent code splitting from happening for the server bundle. The server bundle should be one file containing all the JavaScript code. This will require you to have separate webpack configurations for client and server. +If you're going to try to do code splitting with server rendered routes, you'll probably need to use separate route definitions for client and server to prevent code splitting from happening for the server bundle. The server bundle should be one file containing all the JavaScript code. This will require you to have separate Webpack configurations for client and server. -Do not attempt to register a renderer function on the server. Instead, register either a Render-Function or a component. If you register a renderer in the server bundle, you'll get an error when react on rails tries to server render the component. +Do not attempt to register a renderer function on the server. Instead, register either a Render-Function or a component. If you register a renderer in the server bundle, you'll get an error when React on Rails tries to server render the component. ## React on Rails Pro diff --git a/docs/outdated/rails-assets-relative-paths.md b/docs/outdated/rails-assets-relative-paths.md index 0622918f24..a77240df4d 100644 --- a/docs/outdated/rails-assets-relative-paths.md +++ b/docs/outdated/rails-assets-relative-paths.md @@ -2,15 +2,15 @@ _Note: this doc reflects using Sprockets for assets and has not been updated for # Using Webpack bundled assets with the Rails Asset Pipeline -**If you're looking to use assets in your react components, look no further. This doc is for you.** +**If you're looking to use assets in your React components, look no further. This doc is for you.** -As most of you know, when you spin up a Rails application all of your asset files that live within your `app/assets/` directory will be added into your application's Asset Pipeline. If you would like to view any of these assets (most commonly you'd want to view images), run your rails server in development mode and in a browser visit a url similar to: `localhost:3000/assets/sample_image.png`. In this case, if I had an image `sample_image.png` in my `app/assets/images/` directory, visiting the url `localhost:3000/assets/sample_image.png` in a browser would display the image to me. Meaning that `/assets/sample_image.png` is my path to that individual asset. +As most of you know, when you spin up a Rails application all of your asset files that live within your `app/assets/` directory will be added into your application's Asset Pipeline. If you would like to view any of these assets (most commonly you'd want to view images), run your Rails server in development mode and in a browser visit a url similar to: `localhost:3000/assets/sample_image.png`. In this case, if I had an image `sample_image.png` in my `app/assets/images/` directory, visiting the url `localhost:3000/assets/sample_image.png` in a browser would display the image to me. Meaning that `/assets/sample_image.png` is my path to that individual asset. ## The Problem -Sometimes we would like to use images directly in our react components or even component specific CSS. This can cause problems because it is difficult to maintain the relative path to assets in our pipeline. Normally, we would use erb to get around this, using something like ``. Unfortunately, that will not play well with webpack. +Sometimes we would like to use images directly in our React components or even component-specific CSS. This can cause problems because it is difficult to maintain the relative path to assets in our pipeline. Normally, we would use ERB to get around this, using something like ``. Unfortunately, that will not play well with Webpack. -Now we could always just place these assets in our `app/assets/` directory like normal and then reference them in our react with things like ``, and that would work! But that also will move this image out of our client side app, which isn't always ideal. Also hardcoding the path to an asset isn't a good approach considering file paths can always change, and that would then require a source code change. That's just no bueno. +Now we could always just place these assets in our `app/assets/` directory like normal and then reference them in our React with things like ``, and that would work! But that also will move this image out of our client-side app, which isn't always ideal. Also, hardcoding the path to an asset isn't a good approach considering file paths can always change, and that would then require a source code change. That's just no bueno. So how do we get around this? And find the relative paths to our assets without hardcoding the paths? @@ -20,13 +20,13 @@ Loaders are an incredibly useful part of Webpack. Simply put, they allow you to ##### Url Loader vs. File Loader -Two very common, and quite useful, Webpack loaders are the [url-loader](https://github.com/webpack-contrib/url-loader) and the [file-loader](https://github.com/webpack-contrib/file-loader). They allow you to load and access files in an easy manner. Both of these loaders are incredibly similar to one another, and in fact work together to accomplish their goals, with a very slight difference. The url-loader will load any file(s) and when accessed, will return a Data Url that can be used to access the file(s) (commonly used to inline images). File-loader on the other hand, will bundle and output the file(s) to a desired directory so they can live in the assets on your webserver along with your outputted webpack bundle. These bundled assets can then be accessed by their public paths, making it very easy to include and use them in your JavaScript code. +Two very common, and quite useful, Webpack loaders are the [url-loader](https://github.com/webpack-contrib/url-loader) and the [file-loader](https://github.com/webpack-contrib/file-loader). They allow you to load and access files in an easy manner. Both of these loaders are incredibly similar to one another, and in fact work together to accomplish their goals, with a very slight difference. The url-loader will load any file(s) and when accessed, will return a Data Url that can be used to access the file(s) (commonly used to inline images). File-loader on the other hand, will bundle and output the file(s) to a desired directory so they can live in the assets on your webserver along with your outputted Webpack bundle. These bundled assets can then be accessed by their public paths, making it very easy to include and use them in your JavaScript code. The url-loader is great to use for smaller images! It is most commonly used with a set byte limit on the size of the files that can be loaded. When this is the case, anything below the byte limit will be loaded and returned as a Data Url. Anything that exceeds the byte limit, will delegate to file-loader for loading, passing any set query parameters as well to file-loader (if that sounds like gibberish right now, don't worry. You'll learn all about it soon!). The benefit of using url-loader first, and falling back on file-loader, is that the use of Data Urls saves HTTP Requests that need to be made to fetch files. That is very important in regards to how fast a webpage will load. Generally speaking, the less HTTP requests that need to be made, the faster a page will load. For more information about usage, and the pros & cons of Data Urls read [here](https://css-tricks.com/data-uris/). -Note: _For the rest of this doc, we will be using file-loader. This is because its usage can be a little bit trickier and it is used as url-loader's back up. Keep in mind that the usage for the two are EXTREMELY similar. For more info about the url-loader's usage, check out its configuration for the `react_on_rails` sample app [here](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/webpack.client.base.config.js) (specifically lines 82-84)._ +Note: _For the rest of this doc, we will be using file-loader. This is because its usage can be a little bit trickier, and it is used as url-loader's back up. Keep in mind that the usage for the two is EXTREMELY similar. For more info about using url-loader, check out its configuration for the `react_on_rails` sample app [here](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/webpack.client.base.config.js) (specifically lines 82-84)._ ##### Configuring Webpack with file-loader @@ -48,7 +48,7 @@ query: { }, ``` -both of these two example above do the exact same thing, just using different syntaxes. For the rest of this doc we will be using the JSON object style. For more information about webpack loaders, read [this](https://webpack.github.io/docs/using-loaders.html). +Both examples above do the exact same thing, just using different syntaxes. For the rest of this doc we will be using the JSON object style. For more information about Webpack loaders, read [this](https://webpack.github.io/docs/using-loaders.html). _For the sake of this doc, we're also going to add a `resolve["alias"]` inside our webpack.config to make it easier to include our assets in our jsx files. In `resolve["alias"]`, simply add:_ @@ -58,33 +58,33 @@ _For the sake of this doc, we're also going to add a `resolve["alias"]` inside o ##### Configuring your file-loader Query Parameters -The first property we'll want to set is our file's resulting name after bundling. For now we're just going to use: +The first property we'll want to set is our file's resulting name after bundling. For now, we're just going to use: ```javascript name: '[name][md5:hash].[ext]', ``` -This will just set the name to the file's original name + a md5 digested hash + the extension of the original file (.png, .jpg, etc). +This will just set the name to the file's original name + an MD5-digested hash + the extension of the original file (.png, .jpg, etc.). -Next we'll set the outputPath for our files. This is the directory we want the files to be placed in after webpack runs. When Webpack runs with file-loader, all files (in this case assets) that have been used in the bundled JavaScript will be bundled and outputted to the output destination. **Keep in mind that react_on_rails outputs by default to the `app/assets/webpack/` directory so when we specify the outputPath here it will be relative the `app/assets/webpack` directory.** You can set the outputPath to whatever you want, in this example we will add it to a directory `/app/assets/webpack/webpack-assets/`, and here's how we would do that: +Next we'll set the outputPath for our files. This is the directory we want the files to be placed in after Webpack runs. When Webpack runs with file-loader, all files (in this case assets) that have been used in the bundled JavaScript will be bundled and outputted to the output destination. **Keep in mind that react_on_rails outputs by default to the `app/assets/webpack/` directory so when we specify the outputPath here it will be relative the `app/assets/webpack` directory.** You can set the outputPath to whatever you want, in this example we will add it to a directory `/app/assets/webpack/webpack-assets/`, and here's how we would do that: ```javascript outputPath: 'webpack-assets/', ``` -Note: _You can output these files in the asset pipeline wherever you see fit. My preference is outputting somewhere inside the `app/assets/webpack/` directory just because anything in this directory is already ignored by git due to the react_on_rails generated gitignore, meaning they will not be added by git twice! (once in your `client/app/assets/` and once in your outputted path after webpack bundling)_ +Note: _You can output these files in the asset pipeline wherever you see fit. My preference is outputting somewhere inside the `app/assets/webpack/` directory just because anything in this directory is already ignored by git due to the react_on_rails generated gitignore, meaning they will not be added by Git twice! (once in your `client/app/assets/` and once in your outputted path after Webpack bundling)_ -Lastly, we will set the publicPath to our file(s). This will be the endpoint on our rails web server that you can visit to reach the asset (if you don't know how this works, read the [intro](#using-webpack-bundled-assets-with-the-rails-asset-pipeline)). If you've been following the previous steps, you know that we set our outputPath for our assets to be absolute at `app/assets/webpack/webpack-assets/`, which your rails app should end up hosting at `/assets/webpack-assets/file-name+hash.ext` when the server is run. +Lastly, we will set the publicPath to our file(s). This will be the endpoint on our Rails web server that you can visit to reach the asset (if you don't know how this works, read the [intro](#using-webpack-bundled-assets-with-the-rails-asset-pipeline)). If you've been following the previous steps, you know that we set our outputPath for our assets to be absolute at `app/assets/webpack/webpack-assets/`, which your Rails app should end up hosting at `/assets/webpack-assets/file-name+hash.ext` when the server is run. -Note: _If you're having a hard time figuring out what an asset's path will be on your rails server, simply run `rake assets:precompile` and `cd public/`. The path from there to your file will then be the path/url on your web server to that asset. On top of this, it is also a good idea to check out [this doc](https://www.shakacode.com/react-on-rails/docs/outdated/rails-assets/) to understand how `react_on_rails` allows us to access these files after precompilation, when Rails applies another hash onto the asset._ +Note: _If you're having a hard time figuring out what an asset's path will be on your Rails server, simply run `rake assets:precompile` and `cd public/`. The path from there to your file will then be the path/url on your web server to that asset. On top of this, it is also a good idea to check out [this doc](https://www.shakacode.com/react-on-rails/docs/outdated/rails-assets/) to understand how `react_on_rails` allows us to access these files after precompilation, when Rails applies another hash onto the asset._ -Our publicPath setting will match the path to our outputted assets on our rails web server. Given our assets in this example will be outputted to `/app/assets/webpack/webpack-assets/` and hosted at `/assets/webpack-assets/`, our publicPath would be: +Our publicPath setting will match the path to our outputted assets on our Rails web server. Given our assets in this example will be outputted to `/app/assets/webpack/webpack-assets/` and hosted at `/assets/webpack-assets/`, our publicPath would be: ```javascript publicPath: '/assets/webpack-assets/', ``` -Voila! Your webpack setup is complete. +Voila! Your Webpack setup is complete. ##### Adding/Using `client/` Assets @@ -105,23 +105,23 @@ export default class MyImageBox extends React.Component { } ``` -`myImage` in the example above will resolve to the path of that asset on the web server. Therefore using it as an img's source would then properly display the image/assets when this react component is rendered. +`myImage` in the example above will resolve to the path of that asset on the web server. Therefore using it as an img's source would then properly display the image/assets when this React component is rendered. -Note: **Any assets in our `client/` directory that are not imported/required for use in our jsx files will NOT be bundled and outputted by webpack.** +Note: **Any assets in our `client/` directory that are not imported/required for use in our JSX files will NOT be bundled and outputted by Webpack.** ## Summary: Welcome people who are tired of reading If you've read this far, you probably have a grip on everything. If you didn't, and want a condensed version, here you go: -- Add webpack's file-loader to your project +- Add Webpack's file-loader to your project - Add a new loader module in your webpack.config.js file - Set this loader's test attribute to a regex of the file extensions you would like to load - Set the loader attribute to "file-loader" - Set name to something like `"[name][md5:hash].[ext]"` - Set outputPath attribute to directory of choice, relative to `app/assets/webpack` directory -- Set publicPath attribute, this should be the same as where the rails asset pipeline will serve your asset(s) on the server. See [this](#configuring-your-file-loader-query-parameters) for more info. +- Set publicPath attribute, this should be the same as where the Rails asset pipeline will serve your asset(s) on the server. See [this](#configuring-your-file-loader-query-parameters) for more info. - Add assets directory in `client/app/`, and place whatever you would like in there -- Import or Require these files in your jsx and use them all you want! +- Import or Require these files in your JSX and use them all you want! ### Here's a full example of a webpack.config.js configured with file-loader to load images: diff --git a/docs/outdated/rails-assets.md b/docs/outdated/rails-assets.md index 8c211970aa..d65c29afac 100644 --- a/docs/outdated/rails-assets.md +++ b/docs/outdated/rails-assets.md @@ -5,7 +5,7 @@ _This doc needs updating for the use of Shakapacker or rails/webpacker with Reac The [Webpack file loader](https://github.com/webpack/file-loader) copies referenced files to the destination output directory, with an MD5 hash. The other term for this is a "digest". -> By default the filename of the resulting file is the MD5 hash of the file's contents with +> By default, the filename of the resulting file is the MD5 hash of the file's contents with > the original extension of the required resource. The most common use cases for Webpack processed files are images used for backgrounds in @@ -21,22 +21,22 @@ to the file names. E.g., `img1.jpg` becomes `img1-dbu097452jf2v2.jpg`. When compiling its native css Rails transforms all urls and links to digested versions, i.e. `background-image: image-url(img1.jpg)` becomes -`background-image: url(img1-dbu097452jf2v2.jpg)`. However this doesn't happen for js and -css files compiled by webpack on the client side, because they don't use +`background-image: url(img1-dbu097452jf2v2.jpg)`. However, this doesn't happen for JS and +CSS files compiled by Webpack on the client side, because they don't use `image-url` and `asset-url`. Without some fix, these assets would fail to load. When Webpack's client JavaScript uses images in render methods, e.g. `` or in css, e.g. `background-image: url(...)` The code (such as the CSS) generated by the Webpack will have the Webpack digested name (MD5 hash). Since the Webpack generated CSS expects -just one level of "digesting", this "double-digesting" from Rails will cause such these assets -fail to load. +just one level of "digesting", this "double-digesting" from Rails will cause such assets +to fail to load. _If you are interested in learning how to use assets in your React components, read this doc: [Webpack, the Asset Pipeline, and Using Assets w/ React](https://www.shakacode.com/react-on-rails/docs/outdated/rails-assets-relative-paths/)_ ## The Solution: Symlink Original File Names to New File Names _Note, this solution was removed in v14. If you're interested in this symlink solution, please create -a github issue._ +a GitHub issue._ ## Example from /spec/dummy @@ -46,7 +46,7 @@ RAILS_ENV=production bundle exec rake assets:precompile rails s -e production ``` -You will see this. This shows how the file names output by rails. Note the original names after +You will see this. This shows how the file names output by Rails. Note the original names after being processed by Webpack are just MD5's. ``` diff --git a/docs/javascript/webpack-v1-notes.md b/docs/outdated/webpack-v1-notes.md similarity index 77% rename from docs/javascript/webpack-v1-notes.md rename to docs/outdated/webpack-v1-notes.md index 5962053f5a..3f6907048f 100644 --- a/docs/javascript/webpack-v1-notes.md +++ b/docs/outdated/webpack-v1-notes.md @@ -4,11 +4,11 @@ The following only apply to Webpack V1. Take 1 hour and update to v2! It's worth ## Use the `--bail` Option When Running Webpack for CI or Deployments if using Webpack V1 -For your scripts that statically build your Webpack bundles, use the `--bail` option. This will ensure that CI and your product deployment **halt** if Webpack cannot complete! For more details, see the documentation for [Webpack's `--bail` option](https://webpack.js.org/configuration/other-options/#bail). Note, you might not want to use the `--bail` option if you just want to depend on Webpack returning a non-zero error code and you want to see all the errors, rather than only the first error. +For your scripts that statically build your Webpack bundles, use the `--bail` option. This will ensure that CI and your product deployment **halt** if Webpack cannot complete. For more details, see the documentation for [Webpack's `--bail` option](https://webpack.js.org/configuration/other-options/#bail). Note, you might not want to use the `--bail` option if you want to see all the errors, rather than only the first error. Then make sure to check the Webpack exit code. ## Entry Points -You should ensure you configure the entry points correctly for webpack if you want to break out libraries into a "vendor" bundle where your libraries are packaged separately from your app's code. If you send web clients your vendor bundle separately from your app bundles, then web clients might have the vendor bundle cached while they receive updates for your app. +You should ensure you configure the entry points correctly for Webpack if you want to break out libraries into a "vendor" bundle where your libraries are packaged separately from your app's code. If you send web clients your vendor bundle separately from your app bundles, then web clients might have the vendor bundle cached while they receive updates for your app. You need both include `react-dom` and `react` as values for `entry`, like this: diff --git a/docs/rails/rails-engine-integration.md b/docs/rails/rails-engine-integration.md index c598708e0d..50814109c4 100644 --- a/docs/rails/rails-engine-integration.md +++ b/docs/rails/rails-engine-integration.md @@ -24,11 +24,11 @@ require "react_on_rails" Place `gem 'react_on_rails', '~> 6'` before the gem pointing at your engine in your gemfile. -Requiring `react_on_rails` and including the helper will get rid of any issues where react on rails or react_component is undefined. +Requiring `react_on_rails` and including the helper will get rid of any issues where `ReactOnRails` or `react_component` is undefined. As far as solving the assets issue, `lib/tasks/assets.rake` in `react_on_rails` would somehow have to know that `react_on_rails` was included in an engine, and decide the path accordingly. This might be impossible, especially in the case of multiple engines using `react_on_rails` in a single application. -Another solution would be to detach this rake task from the `rails assets:precompile` task. This can be done by adding `REACT_ON_RAILS_PRECOMPILE=false` to your environment. If you do so, then react assets will have to be bundled separately from `rails assets:precompile`. +Another solution would be to detach this rake task from the `rails assets:precompile` task. This can be done by adding `REACT_ON_RAILS_PRECOMPILE=false` to your environment. If you do so, then React assets will have to be bundled separately from `rails assets:precompile`. # Github Issues diff --git a/docs/rails/turbolinks.md b/docs/rails/turbolinks.md index 2cddf1b29b..cbe4e9c30e 100644 --- a/docs/rails/turbolinks.md +++ b/docs/rails/turbolinks.md @@ -4,7 +4,7 @@ - See [PR 1620](https://github.com/shakacode/react_on_rails/pull/1620). - See [PR 1374](https://github.com/shakacode/react_on_rails/pull/1374). -- Ability to use with Turbo (@hotwired/turbo), as Turbolinks gets obsolete. +- Ability to use with [Turbo (`@hotwired/turbo`)](https://turbo.hotwired.dev/), as Turbolinks becomes obsolete. # Using Turbo @@ -25,25 +25,24 @@ _The following docs may be outdated. We recommend updating to the latest Turbo o ## Why Turbolinks? -As you switch between Rails HTML controller requests, you will only load the HTML and you will -not reload JavaScript and stylesheets. This definitely can make an app perform better, even if -the JavaScript and stylesheets are cached by the browser, as they will still require parsing. +As you switch between Rails HTML controller requests, you will only load the HTML and you will not reload JavaScript and stylesheets. +This definitely can make an app perform better, even if the JavaScript and stylesheets are cached by the browser, as they will still require parsing. ## Requirements for Using Turbolinks -1. You are **not using [react-router](https://github.com/ReactTraining/react-router)** or you are prepared to deal with some potential issues with where react-router and Turbolinks overlaps. -2. You are **using one JS and one CSS file** throughout your app. Otherwise, you will have to figure out how best to handle multiple JS and CSS files throughout the app given Turbolinks. +1. Either **avoid using [React Router](https://reactrouter.com/)** or be prepared to deal with any conflicts between it and Turbolinks. +2. **Use one JS and one CSS file** throughout your app. Otherwise, you will have to figure out how best to handle multiple JS and CSS files throughout the app given Turbolinks. ## Why Not Turbolinks -1. [react-router](https://github.com/ReactTraining/react-router) handles the back and forward buttons, as does TurboLinks. You _might_ be able to make this work. _Please share your findings._ +1. [React Router](https://reactrouter.com/) handles the back and forward buttons, as does Turbolinks. You _might_ be able to make this work. _Please share your findings._ 1. You want to do code splitting to minimize the JavaScript loaded. ## More Information -- CSRF tokens need thorough checking with Turbolinks5. Turbolinks5 changes the head element by JavaScript (not only body) on page changes with the correct csrf meta tag, but if the JS code parsed this from head when several windows were opened, then our specs were not all passing. I didn't look details however, may be it is app code related, not library code. Anyway it may need additional check because there is CSRF helper in ReactOnRails and it need to work with Turbolinks5. -- Turbolinks5 sends requests without the `Accept: */*` in the header, only exactly like `Accept: text/html` which makes Rails behave a bit specifically compared to normal and mime-parsing, which is skipped by when Rails sees `*/*`. For some more details on Rails and `*/*` you can read [Mime Type Resolution in Rails](http://blog.bigbinary.com/2010/11/23/mime-type-resolution-in-rails.html). -- If you're using multiple Webpack bundles, be sure to ensure that there are no name conflicts between JS objects or redux store paths. +- CSRF tokens need thorough checking with Turbolinks5. Turbolinks5 changes the head element by JavaScript (not only body) on page changes with the correct csrf meta tag. But if the JS code parsed this from head when several windows were opened, then our specs didn't all pass. I didn't examine the details, it may be caused by app code, not library code. Anyway, it may need additional checking because there is a CSRF helper in ReactOnRails and it needs to work with Turbolinks5. +- Turbolinks5 sends requests without the `Accept: */*` in the header, only exactly like `Accept: text/html` which makes Rails behave a bit specifically compared to normal and mime-parsing, which is skipped when Rails sees `*/*`. For more details on the special handling of `*/*` you can read [Mime Type Resolution in Rails](http://blog.bigbinary.com/2010/11/23/mime-type-resolution-in-rails.html). +- If you're using multiple Webpack bundles, make sure that there are no name conflicts between JS objects or Redux store paths. ### Install Checklist @@ -64,7 +63,7 @@ NOTE: for Turbolinks 2.x, use `'data-turbolinks-track' => true` ## Turbolinks 5 -Turbolinks 5 is now being supported. React on Rails will automatically detect which version of Turbolinks you are using and use the correct event handlers. +Turbolinks 5 is now supported. React on Rails will automatically detect which version of Turbolinks you are using and use the correct event handlers. For more information on Turbolinks 5: [https://github.com/turbolinks/turbolinks](https://github.com/turbolinks/turbolinks) @@ -79,13 +78,13 @@ Turbolinks.start(); ### Async script loading -Async script loading can be done like this: +Async script loading can be done like this (starting with Shakapacker 8.2): ```erb <%= javascript_include_tag 'application', async: Rails.env.production? %> ``` -If you use `document.addEventListener("turbolinks:load", function() {...});` somewhere in your code, you will notice, that Turbolinks 5 does not fire `turbolinks:load` on initial page load. A quick workaround is to use `defer` instead of `async`: +If you use `document.addEventListener("turbolinks:load", function() {...});` somewhere in your code, you will notice that Turbolinks 5 does not fire `turbolinks:load` on initial page load. A quick workaround for React on Rails <15 is to use `defer` instead of `async`: ```erb <%= javascript_include_tag 'application', defer: Rails.env.production? %> @@ -101,6 +100,11 @@ document.addEventListener('turbolinks:load', function () { }); ``` +React on Rails 15 fixes both issues, so if you still have the listener it can be removed (and should be as `reactOnRailsPageLoaded()` is now async). + +> [!WARNING] +> Do not use `force_load: false` with Turbolinks if you have async scripts. + ## Troubleshooting To turn on tracing of Turbolinks events, put this in your registration file, where you register your components. @@ -147,6 +151,6 @@ TURBO: WITH TURBOLINKS 5: document turbolinks:before-render and turbolinks:rende TURBO: reactOnRailsPageLoaded ``` -We've noticed that Turbolinks doesn't work if you use the ruby gem version of jQuery and jQuery ujs. Therefore we recommend using the node packages instead. See the [tutorial app](https://github.com/shakacode/react-webpack-rails-tutorial) for how to accomplish this. +We've noticed that Turbolinks doesn't work if you use the RubyGem versions of jQuery and jQuery ujs. Therefore, we recommend using the JS packages instead. See the [tutorial app](https://github.com/shakacode/react-webpack-rails-tutorial) for how to accomplish this. -![2016-02-02_10-38-07](https://cloud.githubusercontent.com/assets/1118459/12760060/6546e254-c999-11e5-828b-a8aaa473e5bd.png) +![Show we only install the Turbolinks handlers once](https://cloud.githubusercontent.com/assets/1118459/12760060/6546e254-c999-11e5-828b-a8aaa473e5bd.png) diff --git a/docs/release-notes/15.0.0.md b/docs/release-notes/15.0.0.md index 51da3efd1a..216162940c 100644 --- a/docs/release-notes/15.0.0.md +++ b/docs/release-notes/15.0.0.md @@ -28,24 +28,27 @@ Major improvements to component and store hydration: - The `defer_generated_component_packs` and `force_load` configurations now default to `false` and `true` respectively. This means components will hydrate early without waiting for the full page load. This improves performance by eliminating unnecessary delays in hydration. - The previous need for deferring scripts to prevent race conditions has been eliminated due to improved hydration handling. Making scripts not defer is critical to execute the hydration scripts early before the page is fully loaded. - - The `force_load` configuration make `react-on-rails` hydrate components immediately as soon as their server-rendered HTML reaches the client, without waiting for the full page load. + - The `force_load` configuration makes `react-on-rails` hydrate components immediately as soon as their server-rendered HTML reaches the client, without waiting for the full page load. - If you want to keep the previous behavior, you can set `defer_generated_component_packs: true` or `force_load: false` in your `config/initializers/react_on_rails.rb` file. - - If we want to keep the original behavior of `force_load` for only one or more components, you can set `force_load: false` in the `react_component` helper or `force_load` configuration. - - Redux store support `force_load` option now and it uses `config.force_load` value as the default value. Which means that the redux store will hydrate immediately as soon as its server-side data reaches the client. You can override this behavior for individual redux stores by setting `force_load: false` in the `redux_store` helper. + - You can also keep it for individual components by passing `force_load: false` to `react_component` or `stream_react_component`. + - Redux store now supports `force_load` option, which defaults to `config.force_load` (and so to `true` if that isn't set). If `true`, the Redux store will hydrate immediately as soon as its server-side data reaches the client. + - You can override this behavior for individual Redux stores by calling the `redux_store` helper with `force_load: false`, same as `react_component`. - `ReactOnRails.reactOnRailsPageLoaded()` is now an async function: - - If you are manually calling this function to ensure components are hydrated (e.g. with async script loading), you must now await the promise it returns: + - If you manually call this function to ensure components are hydrated (e.g., with async script loading), you must now await the promise it returns: - ```js - // Before - ReactOnRails.reactOnRailsPageLoaded(); - // Code expecting all components to be hydrated + ```js + // Before + ReactOnRails.reactOnRailsPageLoaded(); + // Code expecting all components to be hydrated - // After - await ReactOnRails.reactOnRailsPageLoaded(); - // Code expecting all components to be hydrated - ``` + // After + await ReactOnRails.reactOnRailsPageLoaded(); + // Code expecting all components to be hydrated + ``` + + - If you call it in a `turbolinks:load` listener to work around the issue documented in [Turbolinks](https://www.shakacode.com/react-on-rails/docs/rails/turbolinks/#async-script-loading), the listener can be safely removed. ## Store Dependencies for Components @@ -75,11 +78,12 @@ Explicitly declare store dependencies for each component: <% redux_store("SimpleStore", props: @app_props_server_render, defer: true) %> <%= react_component('ReduxApp', {}, { prerender: true - + # No need to specify store_dependencies: it automatically depends on SimpleStore }) %> <%= react_component('ComponentWithNoStore', {}, { prerender: true, - store_dependencies: [] + # Explicitly declare no store dependencies + store_dependencies: [] }) %> <%= redux_store_hydration_data %> ``` diff --git a/lib/generators/USAGE b/lib/generators/USAGE index 7091d6e09b..8c403f685a 100644 --- a/lib/generators/USAGE +++ b/lib/generators/USAGE @@ -1,6 +1,6 @@ Description: -The react_on_rails:install generator integrates webpack with rails with ease. You +The react_on_rails:install generator integrates Webpack with Rails with ease. You can pass the redux option if you'd like to have redux setup for you automatically. * Redux diff --git a/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorldServer.js b/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorldServer.js index aad6e48495..5a01dabea9 100644 --- a/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorldServer.js +++ b/lib/generators/react_on_rails/templates/base/base/app/javascript/bundles/HelloWorld/components/HelloWorldServer.js @@ -1,5 +1,5 @@ import HelloWorld from './HelloWorld'; // This could be specialized for server rendering -// For example, if using React-Router, we'd have the SSR setup here. +// For example, if using React Router, we'd have the SSR setup here. export default HelloWorld; diff --git a/lib/react_on_rails/helper.rb b/lib/react_on_rails/helper.rb index 0a92daf661..a2f7116a2d 100644 --- a/lib/react_on_rails/helper.rb +++ b/lib/react_on_rails/helper.rb @@ -32,7 +32,7 @@ module Helper # # Exposing the react_component_name is necessary to both a plain ReactComponent as well as # a generator: - # See README.md for how to "register" your react components. + # See README.md for how to "register" your React components. # See spec/dummy/client/app/packs/server-bundle.js and # spec/dummy/client/app/packs/client-bundle.js for examples of this. # diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 27b786b71e..402f0820a7 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -26,7 +26,7 @@ namespace :react_on_rails do else # Left in this warning message in case this rake task is run directly msg = <<~MSG - React on Rails is aborting webpack compilation from task react_on_rails:assets:webpack + React on Rails is aborting Webpack compilation from task react_on_rails:assets:webpack because you do not have the `config.build_production_command` defined. MSG puts Rainbow(msg).red diff --git a/node_package/src/Authenticity.ts b/node_package/src/Authenticity.ts index 593af3ad67..3da0fd34d4 100644 --- a/node_package/src/Authenticity.ts +++ b/node_package/src/Authenticity.ts @@ -9,7 +9,7 @@ export default { return null; }, - authenticityHeaders(otherHeaders: { [id: string]: string } = {}): AuthenticityHeaders { + authenticityHeaders(otherHeaders: Record = {}): AuthenticityHeaders { return Object.assign(otherHeaders, { 'X-CSRF-Token': this.authenticityToken(), 'X-Requested-With': 'XMLHttpRequest', diff --git a/node_package/src/ComponentRegistry.ts b/node_package/src/ComponentRegistry.ts index 5a2d153bcf..fbf210db24 100644 --- a/node_package/src/ComponentRegistry.ts +++ b/node_package/src/ComponentRegistry.ts @@ -8,7 +8,7 @@ export default { /** * @param components { component1: component1, component2: component2, etc. } */ - register(components: { [id: string]: ReactComponentOrRenderFunction }): void { + register(components: Record): void { Object.keys(components).forEach((name) => { if (componentRegistry.has(name)) { console.warn('Called register for component that is already registered', name); diff --git a/node_package/src/ReactOnRails.client.ts b/node_package/src/ReactOnRails.client.ts index f928cea93c..252e7f5b2f 100644 --- a/node_package/src/ReactOnRails.client.ts +++ b/node_package/src/ReactOnRails.client.ts @@ -46,11 +46,11 @@ ctx.ReactOnRails = { * find you components for rendering. * @param components (key is component name, value is component) */ - register(components: { [id: string]: ReactComponentOrRenderFunction }): void { + register(components: Record): void { ComponentRegistry.register(components); }, - registerStore(stores: { [id: string]: StoreGenerator }): void { + registerStore(stores: Record): void { this.registerStoreGenerators(stores); }, @@ -60,7 +60,7 @@ ctx.ReactOnRails = { * the setStore API is different in that it's the actual store hydrated with props. * @param storeGenerators (keys are store names, values are the store generators) */ - registerStoreGenerators(storeGenerators: { [id: string]: StoreGenerator }): void { + registerStoreGenerators(storeGenerators: Record): void { if (!storeGenerators) { throw new Error( 'Called ReactOnRails.registerStoreGenerators with a null or undefined, rather than ' + @@ -140,7 +140,7 @@ ctx.ReactOnRails = { }, /** - * Allow directly calling the page loaded script in case the default events that trigger react + * Allow directly calling the page loaded script in case the default events that trigger React * rendering are not sufficient, such as when loading JavaScript asynchronously with TurboLinks: * More details can be found here: * https://github.com/shakacode/react_on_rails/blob/master/docs/additional-reading/turbolinks.md @@ -172,7 +172,7 @@ ctx.ReactOnRails = { * @returns {*} header */ - authenticityHeaders(otherHeaders: { [id: string]: string } = {}): AuthenticityHeaders { + authenticityHeaders(otherHeaders: Record = {}): AuthenticityHeaders { return Authenticity.authenticityHeaders(otherHeaders); }, diff --git a/node_package/src/StoreRegistry.ts b/node_package/src/StoreRegistry.ts index 19f094c77a..3129b0dbee 100644 --- a/node_package/src/StoreRegistry.ts +++ b/node_package/src/StoreRegistry.ts @@ -9,7 +9,7 @@ export default { * Register a store generator, a function that takes props and returns a store. * @param storeGenerators { name1: storeGenerator1, name2: storeGenerator2 } */ - register(storeGenerators: { [id: string]: StoreGenerator }): void { + register(storeGenerators: Record): void { Object.keys(storeGenerators).forEach((name) => { if (storeGeneratorRegistry.has(name)) { console.warn('Called registerStore for store that is already registered', name); diff --git a/node_package/src/context.ts b/node_package/src/context.ts index bd2251e626..ab9fbf7b2c 100644 --- a/node_package/src/context.ts +++ b/node_package/src/context.ts @@ -55,7 +55,7 @@ export function getContextAndRailsContext(): { context: Context | null; railsCon try { currentRailsContext = JSON.parse(el.textContent); } catch (e) { - console.error('Error parsing rails context:', e); + console.error('Error parsing Rails context:', e); return { context: null, railsContext: null }; } diff --git a/node_package/src/handleError.ts b/node_package/src/handleError.ts index 4c9f346a6f..b57d998cb6 100644 --- a/node_package/src/handleError.ts +++ b/node_package/src/handleError.ts @@ -9,7 +9,7 @@ function handleRenderFunctionIssue(options: ErrorOptions): string { if (name) { const lastLine = - 'A Render-Function takes a single arg of props (and the location for react-router) ' + + 'A Render-Function takes a single arg of props (and the location for React Router) ' + 'and returns a ReactElement.'; let shouldBeRenderFunctionError = `ERROR: ReactOnRails is incorrectly detecting Render-Function to be false. \ diff --git a/node_package/src/registerServerComponent/server.ts b/node_package/src/registerServerComponent/server.ts index 451d93765d..02c335bf42 100644 --- a/node_package/src/registerServerComponent/server.ts +++ b/node_package/src/registerServerComponent/server.ts @@ -30,7 +30,7 @@ import { ReactComponent } from '../types'; * }); * ``` */ -const registerServerComponent = (components: { [id: string]: ReactComponent }) => { +const registerServerComponent = (components: Record) => { ReactOnRails.register(components); }; diff --git a/node_package/src/types/index.ts b/node_package/src/types/index.ts index 9a961ac53c..8719117144 100644 --- a/node_package/src/types/index.ts +++ b/node_package/src/types/index.ts @@ -33,7 +33,8 @@ export interface RailsContext { httpAcceptLanguage: string; } -type AuthenticityHeaders = { [id: string]: string } & { +// not strictly what we want, see https://github.com/microsoft/TypeScript/issues/17867#issuecomment-323164375 +type AuthenticityHeaders = Record & { 'X-CSRF-Token': string | null; 'X-Requested-With': string; }; @@ -167,10 +168,10 @@ export interface Root { export type RenderReturnType = void | Element | Component | Root; export interface ReactOnRails { - register(components: { [id: string]: ReactComponentOrRenderFunction }): void; + register(components: Record): void; /** @deprecated Use registerStoreGenerators instead */ - registerStore(stores: { [id: string]: StoreGenerator }): void; - registerStoreGenerators(storeGenerators: { [id: string]: StoreGenerator }): void; + registerStore(stores: Record): void; + registerStoreGenerators(storeGenerators: Record): void; getStore(name: string, throwIfMissing?: boolean): Store | undefined; getOrWaitForStore(name: string): Promise; getOrWaitForStoreGenerator(name: string): Promise; @@ -180,7 +181,7 @@ export interface ReactOnRails { reactOnRailsComponentLoaded(domId: string): void; reactOnRailsStoreLoaded(storeName: string): void; authenticityToken(): string | null; - authenticityHeaders(otherHeaders: { [id: string]: string }): AuthenticityHeaders; + authenticityHeaders(otherHeaders: Record): AuthenticityHeaders; option(key: string): string | number | boolean | undefined; getStoreGenerator(name: string): StoreGenerator; setStore(name: string, store: Store): void; diff --git a/spec/dummy/Procfile.dev-static b/spec/dummy/Procfile.dev-static index 8111973753..5a0fd6374d 100644 --- a/spec/dummy/Procfile.dev-static +++ b/spec/dummy/Procfile.dev-static @@ -1,8 +1,8 @@ # You can run these commands in separate shells web: rails s -p 3000 -# Next line runs a watch process with webpack to compile the changed files. -# When making frequent changes to client side assets, you will prefer building webpack assets +# Next line runs a watch process with Webpack to compile the changed files. +# When making frequent changes to client side assets, you will prefer building Webpack assets # upon saving rather than when you refresh your browser page. # Note, if using React on Rails localization you will need to run # `bundle exec rake react_on_rails:locale` before you run bin/shakapacker diff --git a/spec/dummy/README.md b/spec/dummy/README.md index fe59172fbc..4b3d3e1999 100644 --- a/spec/dummy/README.md +++ b/spec/dummy/README.md @@ -1,13 +1,13 @@ -Using NPM for react_on_rails +Using NPM for React on Rails -- Use 'yalc link' to hook up the spec/dummy/client/node_modules to the top level -- Be sure to install yarn dependencies in spec/dummy/client +- Use `yalc link` to hook up the spec/dummy/client/node_modules to the top level +- Be sure to install Yarn dependencies in spec/dummy/client ## Initial setup Read [Dev Initial Setup in Tips for Contributors](/CONTRIBUTING.md#dev-initial-setup). -## Setup yalc +## Set up yalc ```sh cd react_on_rails diff --git a/spec/dummy/app/assets/javascripts/application_non_webpack.js.erb b/spec/dummy/app/assets/javascripts/application_non_webpack.js.erb index b1e2b381af..ff0fc4153e 100644 --- a/spec/dummy/app/assets/javascripts/application_non_webpack.js.erb +++ b/spec/dummy/app/assets/javascripts/application_non_webpack.js.erb @@ -1,6 +1,6 @@ -// All webpack assets in development will be loaded via webpack dev server +// All Webpack assets in development will be loaded via webpack-dev-server // It's important to include them in layout view above this asset -// b/c it exposes jQuery for turbolinks and another non-webpack JS (if any) +// because it exposes jQuery for turbolinks and other non-Webpack JS (if any) // NOTE: We've got this in the /spec/dummy app because our CI supports testing with and // without Turbolinks. diff --git a/spec/dummy/client/README.md b/spec/dummy/client/README.md index 4b9b68b62a..4c998d2e98 100644 --- a/spec/dummy/client/README.md +++ b/spec/dummy/client/README.md @@ -6,23 +6,27 @@ The `.eslintrc` file is based on the AirBnb [eslintrc](https://github.com/airbnb It also includes many eslint defaults that the AirBnb eslint does not include. -# Running linter: +# Running linter Running the linter: - yarn run lint +```bash +yarn run lint +``` or to autofix - yarn run lint -- --fix +```bash +yarn run lint -- --fix +``` # Updating Node Dependencies -``` +```bash yarn global add npm-check-updates ``` -``` +```bash # Make sure you are in the `client` directory, then run: cd client npm-check-updates -u -a @@ -31,11 +35,11 @@ yarn Another option for upgrading: -``` +```bash yarn upgrade ``` -Then confirm that the hot reload server and the rails server both work fine. You +Then confirm that the hot reload server and the Rails server both work fine. You may have to delete `node_modules`. # Adding Node Modules diff --git a/spec/dummy/client/app/startup/HelloWorldApp.jsx b/spec/dummy/client/app/startup/HelloWorldApp.jsx index cc087179fb..c6649c79d4 100644 --- a/spec/dummy/client/app/startup/HelloWorldApp.jsx +++ b/spec/dummy/client/app/startup/HelloWorldApp.jsx @@ -9,6 +9,6 @@ import HelloWorld from './HelloWorld'; * Note, this is imported as "HelloWorldApp" by "client-bundle.js" * * Note, this is a fictional example, as you'd only use a Render-Function if you wanted to run - * some extra code, such as setting up Redux and React-Router. + * some extra code, such as setting up Redux and React Router. */ export default (props) => ; diff --git a/spec/dummy/client/app/startup/RenderedHtml.client.jsx b/spec/dummy/client/app/startup/RenderedHtml.client.jsx index 25db0e30c2..a035d10736 100644 --- a/spec/dummy/client/app/startup/RenderedHtml.client.jsx +++ b/spec/dummy/client/app/startup/RenderedHtml.client.jsx @@ -10,7 +10,7 @@ import EchoProps from '../components/EchoProps'; * Note, this is imported as "HelloWorldApp" by "client-bundle.js" * * Note, this is a fictional example, as you'd only use a Render-Function if you wanted to run - * some extra code, such as setting up Redux and React-Router. + * some extra code, such as setting up Redux and React Router. */ // This will not work: diff --git a/spec/dummy/client/app/startup/RenderedHtml.server.jsx b/spec/dummy/client/app/startup/RenderedHtml.server.jsx index adf566f4c1..23070efab3 100644 --- a/spec/dummy/client/app/startup/RenderedHtml.server.jsx +++ b/spec/dummy/client/app/startup/RenderedHtml.server.jsx @@ -8,9 +8,9 @@ import EchoProps from '../components/EchoProps'; * Note, this is imported as "RenderedHtml" by "serverRegistration.jsx" * * Note, this is a fictional example, as you'd only use a Render-Function if you wanted to run - * some extra code, such as setting up Redux and React-Router. + * some extra code, such as setting up Redux and React Router. * - * And the use of renderToString would probably be done with react-router v4 + * And the use of renderToString would probably be done with React Router v4 * */ export default (props, _railsContext) => {