A Deep Dive into Propshaft and Importmaps in Ruby on Rails 8
What is the difference between Propshaft and Importmaps?
Photo by insung yoon on Unsplash
Ruby on Rails, the popular web application framework, continues to evolve, and with the release of Rails 8 beta in Sep 2024, two powerful tools—Propshaft and Importmaps—have taken center stage in asset management.
These tools provide developers with new and exciting ways to manage assets, bringing modernity and simplicity to an essential part of Rails applications.
In this article, we will explore Propshaft and Importmaps in detail. We'll introduce their purpose, provide practical examples, and compare their strengths and weaknesses.
By the end, you'll have a clear understanding of when and how to use each tool for asset management in your Rails projects.
1. Introduction to Propshaft and Importmaps
What is Propshaft?
Propshaft is the new asset pipeline in Rails 8 that replaces the traditional Sprockets. Propshaft is simpler, faster, and more lightweight compared to Sprockets. Its primary goal is to manage static assets such as images, stylesheets, and JavaScript files.
While Sprockets supported advanced preprocessing features like transpiling and concatenation, Propshaft emphasizes a more straightforward and performant approach by treating assets as plain files and directories without requiring additional compilation steps.
Propshaft is ideal for modern applications that rely on JavaScript bundlers like ESBuild or Webpack for JavaScript handling. It assumes your front-end workflow exists independently from your asset pipeline, letting Propshaft focus on static asset management.
What is Importmaps?
Importmaps, introduced in Rails 7 and further improved in Rails 8, allow you to manage your JavaScript dependencies without requiring a traditional bundler like Webpack or ESBuild.
With Importmaps, Rails applications can import JavaScript packages directly from a Content Delivery Network (CDN) via <script>
tags and the browser’s native ES module support.
Importmaps provide a lightweight alternative to traditional JavaScript package managers by eliminating the need to bundle and transpile JavaScript code. This approach is especially beneficial for smaller applications that don't need heavy front-end frameworks but still want to leverage modern JavaScript modules.
2. Understanding Propshaft in Rails 8
Propshaft simplifies asset management by focusing on the basics: serving static files efficiently and using fingerprinting to ensure that assets are cache-friendly. Propshaft relies on HTTP/2 features to serve assets quickly without requiring them to be bundled or compiled.
Key Features of Propshaft
Simplicity: Propshaft assumes your front-end tools (like ESBuild or Webpack) will handle JavaScript bundling. It only focuses on serving static assets.
Fingerprinted URLs: Propshaft generates URLs for assets with cache-busting fingerprints, ensuring that browsers always request the latest version of an asset after changes.
No preprocessing: Propshaft doesn't provide built-in support for preprocessors like CoffeeScript or Sass. You'll need to rely on separate tools for that.
Setting Up Propshaft in Rails 8
Rails 8 apps use Propshaft by default, however, if you are upgrading a Rails 7 app to Rails 8 then setting up Propshaft is straightforward.
Here's how you can configure it in your Rails 8 application.
Step 1: Add Propshaft to Your Gemfile
gem 'propshaft'
Run bundle install
to install the gem.
Step 2: Configure Propshaft
Propshaft is integrated with Rails 8 by default, so you don’t need to make any special configuration changes. Rails will automatically use Propshaft to handle asset paths and cache busting.
To serve your assets, simply place them in the app/assets
folder:
app/assets/images
app/assets/stylesheets
app/assets/javascripts
For example, to include an image in your view, you can use the Rails asset_path
helper, which will generate the correct path with a fingerprint:
<%= image_tag asset_path('logo.png') %>
This ensures that the browser will load the versioned (fingerprinted) asset:
<img src="/assets/logo-12345.png" alt="Logo">
Step 3: Managing Stylesheets and JavaScript
For CSS and JavaScript files, you can place them in their respective folders under app/assets/
and link them in your layouts:
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>
These tags will ensure that your stylesheets and JavaScript files are served with fingerprints, ensuring proper caching.
3. Understanding Importmaps in Rails 8
Importmaps allow you to manage JavaScript dependencies without a traditional bundler, leveraging the native ES module system in modern browsers. With Importmaps, you specify the URLs of JavaScript libraries, and the browser loads them directly from a CDN.
Key Features of Importmaps
No Bundling: Importmaps remove the need for bundling tools like Webpack or ESBuild, making JavaScript dependencies as simple as referencing CDN-hosted files.
On-Demand Loading: JavaScript modules are loaded on demand, and browsers automatically handle dependency resolution.
Lightweight: Since no bundling is required, this approach is ideal for smaller apps that don’t need the complexity of a full JavaScript build toolchain.
Setting Up Importmaps in Rails 8
Rails 8 apps use Importmaps by default, however, if you are upgrading a Rails 7 app to Rails 8 then setting up Importmaps is straightforward.
To configure Importmaps in a Rails 8 project, follow these steps:
Step 1: Add Importmaps to Your Gemfile
gem 'importmap-rails'
Run bundle install
to install the gem.
Step 2: Configure Importmap
Once the gem is installed, Rails provides an easy way to manage your JavaScript imports. By default, the config/importmap.rb
file will be created, where you can define your module imports.
For example, to import the Stimulus JavaScript library, modify config/importmap.rb
like this:
pin "application"
pin "stimulus", to: "https://ga.jspm.io/npm:stimulus@3.1.0/dist/stimulus.es.js"
This maps the Stimulus library to its CDN location.
Step 3: Use Importmaps in Your Views
In your application.js
, you can import the libraries defined in config/importmap.rb
:
import { Application } from "stimulus"
const application = Application.start()
Rails will generate the necessary HTML tags to load the modules from the CDN:
<script type="module" src="/assets/application.js"></script>
<script type="module">
import { Application } from "https://ga.jspm.io/npm:stimulus@3.1.0/dist/stimulus.es.js";
const application = Application.start();
</script>
Example of Importmaps in Action
Let’s say you want to include the popular lodash
library using Importmaps. You can add it to your config/importmap.rb
like so:
pin "lodash", to: "https://cdn.skypack.dev/lodash"
In your application.js
, you can now use it as follows:
import _ from "lodash"
console.log(_.chunk(['a', 'b', 'c', 'd'], 2))
// Output: [['a', 'b'], ['c', 'd']]
The browser will load the lodash
module from the specified CDN when the page is accessed, without requiring any bundling.
4. Comparing Propshaft and Importmaps
While both Propshaft and Importmaps simplify asset management in Rails 8, they serve different purposes and are suited for different types of applications. Here’s how they compare:
Purpose
Propshaft is focused on managing static assets (e.g., images, stylesheets, plain JavaScript files) without dealing with module loading or bundling. It’s designed to handle assets that don’t need preprocessing and works best alongside modern JavaScript bundlers like ESBuild or Webpack.
Importmaps focus solely on JavaScript dependencies, allowing you to use modern ES modules without the need for bundling or transpiling. This makes it ideal for applications that want to avoid complex build tools but still leverage external JavaScript libraries.
Simplicity
Propshaft offers simplicity by sticking to serving static assets without complex preprocessing.
Importmaps provide a lightweight alternative to bundlers, removing the need for tools like Webpack and simplifying JavaScript dependency management.
Performance
Propshaft improves performance by serving fingerprinted assets and allowing HTTP/2 multiplexing to speed up asset delivery.
Importmaps leverage the browser’s native module loader, reducing the need for local JavaScript bundling and allowing on-demand loading from CDNs, which can be faster for small, modular apps.
Use Case
Use Propshaft when your application requires efficient serving of static assets but relies on separate tools for JavaScript bundling and preprocessing.
Use Importmaps when you want to manage JavaScript dependencies without a build step and prefer a CDN-based, ES-module approach.
Conclusion
Propshaft and Importmaps are two powerful tools in Rails 8 that cater to different aspects of asset management. Propshaft excels at serving static assets efficiently, while Importmaps offer a lightweight, modern solution for JavaScript dependency management without bundling.
For developers looking to simplify their Rails asset pipeline, understanding the strengths and limitations of Propshaft and Importmaps is key to optimizing performance and maintainability in your Rails 8 applications.