Enabling Hot Module Replacement for React on Rails

Carlos Santana
The Mindbody Dev Report
2 min readApr 12, 2019

NOTE: This article assumes you already have an application running on React on Rails.

My name is Carlos Santana, I’m a Senior React Developer at MINDBODY and author of the books React Cookbook and React Design Patterns and Best Practices — Second Edition.

Finding useful information about how to enable the Hot Module Replacement (HMR) in React on Rails was challenging since most of the information is from 2017.

In this post, I’ll summarize all the steps you need to follow to enable the HMR in your React on Rails application.

If you are not familiar with HMR, basically it’s a way to refresh our browser every time we change our code, so we don’t need to do it manually.

Webpack Dev Server

Webpack Dev Server serves a Webpack application and updates the browser every time it detects a change.

We need to install it with the command:

npm install — save-dev webpack-dev-server

In your webpack.config.js file, you need to add the devServer node only when you’re on the development environment.

const isDevelopment = process.env.NODE_ENV === 'development';const webpackConfig = {
// Your webpack configuration goes here...
};
if (isDevelopment) {
webpackConfig.devServer = {
contentBase: ['../public/webpack/development'],
inline: true,
port: 3500,
hot: true
};
}

HotModuleReplacementPlugin

Enable the HotModuleReplacementPlugin by adding it in your Webpack plugins like this:

if (isDevelopment) {
webpackConfig.plugins = [
new webpack.HotModuleReplacementPlugin()
];
}

Changing the asset_host

After enabling the HMR in Webpack, you need to change the asset_host in your config/development/development.rb file to change the base URL for the Webpack bundles.

At the end of the file, add:

Rails.application.configure do
# All your Configuration goes here...

config.action_controller.asset_host = 'http://localhost:3500'
end

Webpacker

Finally, in the Webpacker (I’m using the version 4.0.2), add this to your Gemfile:

gem 'webpacker', '>= 4.x'

The webpacker.yml should look like this:

default: &default
manifest: manifest.json
extract_css: true
development:
<<: *default
public_output_path: webpack/development
dev_server:
host: localhost
port: 3500
hmr: true
test:
<<: *default
public_output_path: webpack/test
production:
<<: *default
public_output_path: webpack/production

As you see in our dev_server we are specifying the host, the port (3500) which is the same we defined in our Webpack file, and then we enable the hmr.

Finally, in your layout file, you have to include the Webpack bundles. I split my bundles into two; one for vendors, and one for the app.

<!DOCTYPE html>
<html>
<head>

<%= stylesheet_pack_tag 'app' %>
</head>
<body>

<%= yield %>
<%= javascript_pack_tag 'vendor' %>
<%= javascript_pack_tag 'app' %>
</body>
</html>

I hope you find this post useful. If you have any questions, post a comment and I’ll respond to it ASAP.

--

--