Coder Social home page Coder Social logo

shakacode / react_on_rails_demo_ssr_hmr Goto Github PK

View Code? Open in Web Editor NEW
86.0 20.0 22.0 2.29 MB

react_on_rails tutorial demonstrating SSR, HMR fast refresh, and Typescript based on the rails/webpacker webpack setup

License: MIT License

Ruby 66.41% JavaScript 18.42% CSS 1.78% TypeScript 3.23% HTML 9.90% MDX 0.26%
ruby rails react reactjs tutorial webpack webpacker webpacker-gem ruby-on-rails react-on-rails

react_on_rails_demo_ssr_hmr's Introduction

React on Rails Demo With SSR, HMR fast refresh, and TypeScript

Each commit demonstrates a step in the React on Rails Tutorial.

UPDATE May 7, 2023: This repo is updated to the latest shakapacker gem and package v6.6.0 and React on Rails v13.3.2 releases!


Please ⭐️ this repo if you find this useful.

See the commit history.

Key features

  1. shakpacker v6! (see explanation of the switch at rails/webpacker).
  2. Server-Side Rendering (SSR) of React using a separate server bundle.
  3. Webpack configuration for the server bundle is based on the rails/webpacker configuration for the client files.
  4. HMR is provided by react-refresh-webpack-plugin.
  5. TypeScript
  6. CSS Modules

Installation

Setup

git clone [email protected]: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

  1. Procfile.dev: Uses the webpack-dev-server. This will proxy asset requests to the webpack-dev-server except for a few files: the manifest.json and the server-bundle.js which are in the standard public/webpack/development folder.
  2. Procfile.dev-static: Uses the standard files in the public/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

  1. Start app using either bin/dev or bin/dev-static (or run Procfile.dev or Procfile.dev-static with your favorit process manager like overmind or foreman).
  2. Visit page http://localhost:3000/hello_world.
    1. 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.
    2. Type into the input box and notice the label above change.
  3. Edit React file app/javascript/bundles/HelloWorld/components/HelloWorld.tsx, like changing some text in the React code, and save the file.
    1. With HMR enabled, you'll see a message on the browser console and the page will update automatically.
    2. With static compilation, you'll need to refresh the page to see the update.
  4. 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.
    1. 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.
      

Checking the production build

  1. RAILS_ENV=production rake assets:precompile
  2. rails s -e production

Debugging the webpack setup

  1. Uncomment the debugger line at the end of file config/webpack/webpack.config.js
  2. 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.

  1. Rails new: rails new --skip-sprockets -J --skip-turbolinks test-react-on-rails-v12-ssr-v2

  2. Add webpacker gem: bundle add webpacker

  3. Add React on Rails gem: bundle add react_on_rails.

  4. Set React on Rails version to be exact: Edit the Gemfile and run bundle.

  5. Install webpacker: bundle exec rails webpacker:install

  6. Install webpacker React: bundle exec rails webpacker:install:react

  7. Install React on Rails: rails generate react_on_rails:install

  8. 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 in webpacker.yml. After this change, you can:

    1. Run: foreman start -f Procfile.dev-hmr
    2. Edit a JSX file and save and see the React change and the component state was preserved.
  9. rails/webpacker installs TypeScript into webpack: bundle exec rails webpacker:install:typescript

  10. Convert demo screen and ReactOnRails registration to Typescript

  11. 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.

  12. Switch to separate bundle for server-side rendering Convert to separate bundles for server vs. client rendering with HMR

    1. Turned back on hmr and inline in webpacker.yml to support HMR.
    2. Change config/initializers/react_on_rails.rb to have the correct server bundle name
    3. 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
  13. Upgrade to rails/webpacker v6

Client only rendering versus Server-Side Rendering

Client Only Rendering

2020-08-02_17-14-33

Server-Side Rendering

2020-08-02_17-10-16

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, [email protected], maintainer of React on Rails, for more information.

Click to join React + Rails Slack.

ShakaCode is hiring! Check out our open positions.

react_on_rails_demo_ssr_hmr's People

Contributors

ahangarha avatar hanaffi avatar jrmhaig avatar judahmeek avatar justin808 avatar mrtnzlml avatar wwahammy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react_on_rails_demo_ssr_hmr's Issues

How do images work in this repo?

Warning: Prop `src` did not match. Server: "/Users/amirsharif/Projects/sendapostcardonline/public/packsmedia/images/letter-599b40cf9aba6c364ac2bfb054d291d7.png" Client: "/packs/media/images/letter-599b40cf9aba6c364ac2bfb054d291d7.png"
    in img (created by CompleteAddressForm)
    in div (created by CompleteAddressForm)
    in div (created by CompleteAddressForm)
    in CompleteAddressForm (created by Connect(CompleteAddressForm))
    in Connect(CompleteAddressForm)
    in Provider
    in Unknown

I'm getting this error.
Where is packsmedia coming from?
Why the disconnect between client and server?

(I am using almost all the same files as this repo)

// assets.js (loader)

const { env, publicPath } = require('../configuration.js')

module.exports = {
  test: /\.(jpg|jpeg|png|gif|svg|eot|ttf|woff|woff2)$/i,
  use: [{
    loader: 'file-loader',
    options: {
      publicPath,
      name: env.NODE_ENV === 'production' ? '[name]-[hash].[ext]' : '[name].[ext]'
    }
  }]
}

devDependencies vs dependencies

I don't understand the logic of why some packages are in devDependencies and others are in dependencies.

My understanding, which has been confirmed by a NodeJS developer, is that devDependencies should contain packages that are used to build code (so babel, typescript, etc) while dependencies should contain packages used at run-time, such as React. I'm scratching my head at the organization here. Please consider cleaning this up.

Need to update readme for HMR

I ran into an issue on step 8. HMR was not enabled by default in webpacker.yml for my dev server so when I tried to add fast refresh I was getting some strange errors.

I would add a note in Step 8 such as:

  • Note: Ensure HMR is enabled for the dev server. hmr: true in webpacker.yml

How do i include scss-modules with this tutorial?

Hi Shakacode, thanks for the wonderful tutorial.

Sorry for the noob question, I'm currently stuck at importing a scss module in my JSX component. May i know how do i include a scss-module in my component? Thanks!

Encountered error: "Error: Cannot find module './styles.scss'"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.