January 28, 2024
•Last updated January 30, 2024
How to Add Live Reload to Your Rails Application
Live reload is an incredible tool for developers looking to boost their productivity. In this tutorial, I will walk you through implementing live reload in your Ruby on Rails application using esbuild.
Implementing live reload can significantly streamline your development workflow, saving you valuable time and effort. You can instantly see the results by automatically refreshing your app whenever you make changes without manually reloading the page.
To achieve this, we will leverage the power of esbuild, a cutting-edge technology for fast and efficient JavaScript bundling. By combining esbuild with Ruby on Rails, we can create a seamless live reload experience that will streamline your development process.
Table of Contents
- Introduction
- Setting Up Your Rails Project
- Installing Necessary Gems and Dependencies
- Configuring Esbuild
- Creating the Live Reload Script
- Putting It All Together
- Live reload alternatives for Ruby on Rails
- Conclusion
- Continue learning
Introduction
Live Reload automates the refresh process of your web page whenever you make changes to your code. This feature not only saves time but also enhances your overall development experience.
Setting Up Your Rails Project
Start by creating a new Rails project with Tailwind CSS and esbuild:
rails new livereload -c tailwind -j esbuild
Installing Necessary Gems and Dependencies
First, ensure you have the jsbundling-rails
gem installed. If not, add it to your Gemfile and run bundle install
.
Next, set up esbuild with Rails:
./bin/bundle exec rails javascript:install:esbuild
Add the chokidar
package for file watching:
yarn add chokidar -D
Configuring esbuild
Create and customize an esbuild.config.js
file in your project:
// esbuild.config.js
const esbuild = require("esbuild")
const chokidar = require("chokidar")
const http = require("http")
const path = require("path")
const isProduction = process.env.RAILS_ENV === "production"
const watchMode =
process.argv.includes("--watch") || process.argv.includes("--reload")
const reloadMode = process.argv.includes("--reload")
const port = 5678
// Esbuild configuration
const esbuildConfig = {
entryPoints: [path.join("app/javascript", "application.js")],
bundle: true,
minify: isProduction,
sourcemap: !isProduction,
outdir: path.join("app/assets/builds"),
}
// Start the esbuild build process
esbuild.build(esbuildConfig).catch(() => process.exit(1))
// Set up a simple HTTP server for live reload with CORS headers
const clients = []
const server = http.createServer((req, res) => {
// Set CORS headers
res.setHeader("Access-Control-Allow-Origin", "*")
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS")
res.setHeader("Access-Control-Allow-Headers", "Content-Type")
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
})
clients.push(res)
req.on("close", () => {
clients.splice(clients.indexOf(res), 1)
})
})
server.listen(5678)
// Watch for file changes
chokidar
.watch([
"app/javascript/**/*",
"app/views/**/*",
"app/assets/stylesheets/**/*",
])
.on("all", () => {
esbuild.build(esbuildConfig)
clients.forEach((client) => client.write("data: reload\n\n"))
})
console.log("Live reload server running on http://localhost:5678")
This configuration sets up esbuild
and a simple HTTP server for the live reload functionality.
Here's a simplified explanation of what the code in esbuild.config.js
is doing, hopefully, broken down into more straightforward terms:
- Setting Up Tools and Checking the Environment:
- The code starts by loading some necessary tools:
esbuild
,chokidar
, andhttp
.esbuild
helps in bundling and optimizing JavaScript files,chokidar
watches for file changes, andhttp
is used to create a server. - It checks if the Rails app is in production mode. This helps the code decide whether to optimize files for faster performance or not.
- The code starts by loading some necessary tools:
- Configuring Esbuild:
- A configuration is set for
esbuild
. This includes where to find the JavaScript files, whether to bundle them together and where to save them. It's like givingesbuild
a map and a to-do list.
- A configuration is set for
- Starting the Build Process:
esbuild
starts its job using the configuration provided. If something goes wrong, it stops the process to avoid more issues.
- Creating a Mini Server for Live Reload:
- The code sets up a small server. This server's job is to send messages to the web browser to refresh the page whenever there are changes.
- It makes sure that any browser is allowed to connect to this server (that's what CORS headers do).
- Listening for Changes:
chokidar
starts watching files in your JavaScript, views, and stylesheets directories. Whenever there's a change in these files, it tellsesbuild
to rebuild them.- After rebuilding, it notifies all connected browsers to refresh the page. This means you see the changes in your web app immediately ✨.
- Running the Server:
- Finally, the server starts, and the code tells you that it's running and ready to reload your pages automatically on
http://localhost:5678
.
- Finally, the server starts, and the code tells you that it's running and ready to reload your pages automatically on
Creating the Live Reload Script
Now, add a live_reload.js
file to app/javascript
and import it in application.js
:
// app/javascript/live_reload.js
if (process.env.NODE_ENV === "development") {
const source = new EventSource("http://localhost:5678")
source.onmessage = (event) => {
if (event.data === "reload") {
window.location.reload()
}
}
}
Update the package.json script
// package.json
"scripts": {
"build:css": "tailwindcss --postcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify",
"build": "node esbuild.config.js"
},
This script listens for the "reload" event cast from our esbuild configuration and refreshes the page. We created a new EventSource for the server created by the build
configuration.
Putting It All Together
With these configurations, your Rails app is now set up for live reloading. You can start your Rails server and begin coding. The browser automatically reloads whenever you change your JavaScript, stylesheets, or views. This ultimately saves you time and sanity during development.
Live reload Alternatives for Ruby on Rails
If you’re looking for alternatives to the esbuild-driven method I introduced in this tutorial, there are plenty of other options with Rails. Some options depend on specific technologies or front-end frameworks but accomplish similar goals.
- Guard LiveReload
- Description: Guard LiveReload automatically refreshes your browser when 'view' files are modified.
- Link: Guard LiveReload on GitHub
- Rack::LiveReload
- Description: A Rack middleware that inserts the LiveReload script into your app's responses. Works well with apps not using Webpacker.
- Link: Rack::LiveReload on GitHub
- Webpacker
- Description: Though primarily for managing JavaScript, Webpacker can be configured for hot module replacement, similar to live reloading.
- Link: Webpacker on GitHub
- BrowserSync
- Description: Not specific to Rails, BrowserSync can synchronize file changes and interactions across multiple devices, ideal for responsive testing.
- Link: BrowserSync
- React Hot Loader
- Description: React Hot Loader enables hot module replacement for a smoother development experience if you use React with Rails.
- Link: React Hot Loader on GitHub
- Vite Ruby
- Description: Vite Ruby integrates Vite.js with Ruby on Rails, offering a fast front-end build tool with features like hot module replacement.
- Link: Vite Ruby on GitHub
Conclusion
Live Reload is an awesome tool for enhancing your Rails development workflow. It reduces the time spent on manual refreshes, allowing you to focus more on development. The result is more efficient coding and better development of apps.
Continue learning
Categories
Collection
Part of the Ruby on Rails collection
Products and courses
-
Hello Hotwire
A course on Hotwire + Ruby on Rails.
-
Hello Rails
A course for newcomers to Ruby on Rails.
-
Rails UI
UI templates and components for Rails.