Awesome
React on Rails Demo With SSR, HMR fast refresh, and TypeScript
Each commit demonstrates a step in the React on Rails Tutorial.
UPDATE July 2, 2024: This repo is updated to the latest shakapacker gem and package v8.0.0 and React on Rails v14.0.3 releases!
Please ⭐️ this repo if you find this useful.
See the commit history.
Key features
shakpacker
v8! (see explanation of the switch at rails/webpacker).- Server-Side Rendering (SSR) of React using a separate server bundle.
- Webpack configuration for the server bundle is based on the rails/webpacker configuration for the client files.
- HMR is provided by react-refresh-webpack-plugin.
- TypeScript
- CSS Modules
Installation
Setup
git clone git@github.com:shakacode/react_on_rails_demo_ssr_hmr.git
bundle install
yarn install
Use the provided Procfiles to run webpack and rails together, like overmind start -f Procfile.dev
Procfile.dev
: Uses the webpack-dev-server. This will proxy asset requests to the webpack-dev-server except for a few files: themanifest.json
and theserver-bundle.js
which are in the standardpublic/webpack/development
folder.Procfile.dev-static
: Uses the standard files in thepublic/webpack/development
folder. Note, the standard webpack config in/config/webpack
outputs an array which builds both the client and server bundles.
Running with HMR
bin/dev
# or
overmind start -f Procfile.dev
Running without HMR, statically creating the bundles
bin/dev-static
# or
overmind start -f Procfile.dev-static
Running with SWC
Starting from Shakapacker 6.1.1, it is possible to use SWC in projects. See demo-branch-swc-loader branch for a demonstration of SWC usage.
Please check out Shakapacker - Using SWC Loader documentation for more information about this feature.
Testing Functionality of SSR and HMR
- Start app using either
bin/dev
orbin/dev-static
(or runProcfile.dev
orProcfile.dev-static
with your favorit process manager like overmind or foreman). - Visit page http://localhost:3000/hello_world.
- Inspect the page for no errors and view the console. With HMR (non-static), you'll see a browser console message:
[webpack-dev-server] Hot Module Replacement enabled.
- Type into the input box and notice the label above change.
- Inspect the page for no errors and view the console. With HMR (non-static), you'll see a browser console message:
- Edit React file
app/javascript/bundles/HelloWorld/components/HelloWorld.tsx
, like changing some text in the React code, and save the file.- With HMR enabled, you'll see a message on the browser console and the page will update automatically.
- With static compilation, you'll need to refresh the page to see the update.
- Edit the CSS module file
app/javascript/bundles/HelloWorld/components/HelloWorld.module.css
and change the color. You will either see an instant update to the webpage with HMR, or you will need to refresh the page.- With HMR enabled, you'll see a message on the browser console and the page will update automatically. You'll see browser console messages:
[webpack-dev-server] App updated. Recompiling... index.js:519 [webpack-dev-server] App hot update... log.js:24 [HMR] Checking for updates on the server... log.js:24 [HMR] Updated modules: log.js:16 [HMR] - ./app/javascript/bundles/HelloWorld/components/HelloWorld.module.css log.js:24 [HMR] App is up to date.
- With HMR enabled, you'll see a message on the browser console and the page will update automatically. You'll see browser console messages:
Checking the production build
RAILS_ENV=production rake assets:precompile
rails s -e production
Debugging the webpack setup
- Uncomment the debugger line at the end of file
config/webpack/webpack.config.js
- Set your preferred environment values and run
NODE_ENV=production RAILS_ENV=production bin/webpacker --debug-webpacker
Descriptive Commits
Note, this repo started with rails/webpacker v5 and an older version of React on Rails. These are for example purposes only. They are not a set of tutorial steps if you want to be on the current versions.
-
Rails new:
rails new --skip-sprockets -J --skip-turbolinks test-react-on-rails-v12-ssr-v2
-
Add webpacker gem:
bundle add webpacker
-
Add React on Rails gem:
bundle add react_on_rails
. -
Set React on Rails version to be exact: Edit the Gemfile and run
bundle
. -
Install webpacker:
bundle exec rails webpacker:install
-
Install webpacker React:
bundle exec rails webpacker:install:react
-
Install React on Rails:
rails generate react_on_rails:install
-
Add HMR and Fast Refresh Leverages the react-refresh-webpack-plugin to have Fast Refresh working with Webpack v4. Note, ensure HMR is enabled for the dev server:
hmr: true
inwebpacker.yml
. After this change, you can:- Run:
foreman start -f Procfile.dev-hmr
- Edit a JSX file and save and see the React change and the component state was preserved.
- Run:
-
rails/webpacker installs TypeScript into webpack:
bundle exec rails webpacker:install:typescript
-
Convert demo screen and ReactOnRails registration to Typescript
-
Enable simple Server-Side Rendering (SSR) for Hello World using the same bundle for client and server rendering. This is the simple, but imperfect way to turn on SSR using the same bundle for the server and client. HMR is not available.
-
Switch to separate bundle for server-side rendering Convert to separate bundles for server vs. client rendering with HMR
- Turned back on hmr and inline in webpacker.yml to support HMR.
- Change config/initializers/react_on_rails.rb to have the correct server bundle name
- Follow the flow from config/webpack/development.js to webpackConfig.js and consider uncommenting the debug line to see what happens when you run bin/webpacker --debug
Client only rendering versus Server-Side Rendering
Client Only Rendering
Server-Side Rendering
About
This project is sponsored by the software consulting firm ShakaCode. We focus on React front-ends, often with Ruby on Rails or Gatsby, using TypeScript or ReasonML. The best way to see what we do is to see the details of our recent work.
Interested in optimizing your webpack setup for React on Rails including code splitting with react-router, and loadable-components with server-side rendering? We just did this for Popmenu, lowering Heroku costs 20-25% while getting a 73% decrease in average response times.
Feel free to contact Justin Gordon, justin@shakacode.com, maintainer of React on Rails, for more information.
Click to join React + Rails Slack.
ShakaCode is hiring! Check out our open positions.