rails
The 3 Vite plugins I use on every new Rails project
Autoprefixer, rollup-plugin-gzip, and vite-plugin-full-reload, plus some honorable mentions
I’ve completely switched away from Sprockets and Webpacker and am using Vite for my current Rails projects. Here are the three plugins I like to add on top of the standard Vite-Rails setup.
1. Autoprefixer
The CSS language is a moving target, and browser support for properties changes all the time. Sometimes properties require browser-specific prefixes, like -moz
or -webkit
.
For example, as of June 2023, if you want to use the box-decoration-break
property, you’ll need to specify it twice to get it to work across all browsers:
code {
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}
box-decoration-break
, but Chrome, Safari, and Edge currently require the -webkit
prefix.
Thankfully, Autoprefixer means I don’t have to worry about all of this. As the name implies, it will automatically add the necessary prefixes for me.
code {
box-decoration-break: clone;
}
Adding autoprefixer to a Vite-Rails project
If you are using Sprockets, you have the autoprefixer-rails gem. Vite, on the other hand, uses PostCSS under the hood. That means adding a CSS enhancement like autoprefixer doesn’t require a special gem wrapper. Instead, you can use autoprefixer directly by specifying it in a postcss.config.js
file.
Here’s how it works. First, add autoprefixer to your package.json
dependencies:
$ yarn add autoprefixer
npm install
if your project uses NPM.
Then, create a PostCSS config with the following:
module.exports = {
plugins: [require("autoprefixer")],
};
Vite will detect and use this config when it processes CSS files in your project.
2. rollup-plugin-gzip
I’ve always been taught to compress CSS and JavaScript files before sending them to browser, especially over slower cellular data connections. However, compression has a computational cost. That’s why Rails frontend build systems like Sprockets and Webpacker create compressed versions of assets up front, at compile time.
I was surprised to discover that this functionality is not provided by Vite-Rails by default (as of June 2023). Enabling it requires a plugin.
Enabling compression in Vite-Rails
Vite uses Rollup for asset compilation. That means that you can use Rollup plugins to customize Vite’s production build pipeline.
To enable compressed assets, add rollup-plugin-gzip
, like this:
$ yarn add rollup-plugin-gzip
And update the Vite configuration:
import gzipPlugin from "rollup-plugin-gzip";
// ...
export default defineConfig({
plugins: [
// ...
gzipPlugin()
]
});
Import
rollup-plugin-gzip
and insert it into the list of Vite plugins.
3. vite-plugin-full-reload
I’ll take any chance I can get to shorten the feedback cycle between the code I’m writing and the effects I see in the browser. Vite is already great at doing this out of the box: it hot-reloads CSS and JavaScript changes, and does so incredibly fast. But when I am working in Rails, I really want my browser to reload when I change ERB files as well.
The vite-plugin-full-reload package does exactly that: when you modify an ERB file, it refreshes the browser. Just add it to your project:
$ yarn add vite-plugin-full-reload
And update the Vite configuration:
import FullReload from "vite-plugin-full-reload";
// ...
export default defineConfig({
plugins: [
// ...
FullReload(["app/views/**/*.erb"])
]
});
The
FullReload
plugin takes an array of glob expressions. Vite will refresh the browser whenever a matching file is modified.
An all-in-one solution: vite-plugin-rails (almost)
A new package called vite-plugin-rails combines rollup-plugin-gzip
, vite-plugin-full-reload
and a few more Rails-related “greatest hits” into a single plugin. This is nice, because by adding vite-plugin-rails
to your project, you’ll get all of these plugins without having to install and configure them individually:
- rollup-plugin-gzip
- vite-plugin-ruby
- vite-plugin-environment
- vite-plugin-full-reload
- vite-plugin-stimulus-hmr
- vite-plugin-manifest-sri
To add it to your project, first install the package:
$ yarn add vite-plugin-rails
And then use it in the Vite config:
import { defineConfig } from "vite";
import ViteRails from "vite-plugin-rails";
export default defineConfig({
plugins: [ViteRails()]
});
ViteRails
initializes RubyPlugin
, gzipPlugin
, and FullReload
behind the scenes, so a typical Vite config for a Rails project gets simplified down to a single plugin. Neat!
According to the README, the Vite-Rails installer might automatically install vite-plugin-rails
at some point in the future, which sounds great.
However, it’s worth noting that PostCSS plugins like autoprefixer are not included, so that will still require the separate installation described above.
Honorable mentions
Here are a couple more plugins that I’ve found come in handy for some Vite-Rails projects:
- vite-plugin-sass-glob-import enables Sprockets-like wildcard imports in
.scss
files - postcss-custom-media lets you use CSS variables inside
@media
queries
Further reading
- Inline SVGs with Rails and Vite
- Configuring Rails and Vite to use HTTPS in local development
- Why Vite (Official Vite docs)
- PostCSS Support (Official Vite docs)
- Rollup Plugin Compatibility (Official Vite docs)
- Rails Integration (Official Vite Ruby docs)
- ElMassimo/vite_ruby (GitHub monorepo containing the official Vite-Ruby/Rails libraries)
To apply the Vite configurations in this article to your next Rails project, you can use mattbrictson/rails-template with the --javascript vite
option.