Two elephants standing in the grass.

If you fire up a new Rails 7 project, you’ll probably be missing a couple of tools you should have: minification and vendor prefixing. Minification takes our JavaScript and CSS assets and squishes everything down by removing whitespace to make file sizes smaller. Adding vendor prefixes helps normalize the way our CSS renders in different browsers. Some tools allow you to perform these tasks manually, but who wants to do that?! Let’s automate them.

Starting a new Rails app

Rails has a few different ways you can create a new app, but we’re going to use esbuild for JavaScript and Sass for css in this example. Rails is now loosely coupling its CSS and JavaScript solutions, which means we need to get a little more specific when kicking off a new project.

rails new awesome-app -j esbuild -css sass

Give us something to look at

We need something to preview to make sure we’re doing things correctly. So let’s:

rails generate scaffold pages
rails db:migrate

We need a root route to examine as we’re putting things together. In config/routes.rb add:

root "pages#index"

Cool, there’s something to look at now. So far, so good.

Add some CSS

Create a new file: app/assets/stylesheets/_layout.scss. In that file, we’ll write some contrived styles that will be minified later.

body {
  background: url("https://picsum.photos/id/1019/800/600") no-repeat;
  background-size: cover;
  padding: 0;
  margin: 0;
  color: white;
}

.container {
  padding: 15px;
}

header {
  background-color: rgba(103, 149, 172, 0.5);
  height: 50px;
  color: white;
  padding: 10px;
  box-sizing: border-box;
  backdrop-filter: blur(7px) saturate(50%);
  display: flex;
  align-items: center;
}

a {
  color: lightgray;
}

Add this CSS partial to our manifest at app/assets/stylesheets/application.sass.scss:

// Entry point for your Sass build
@import "layout";

Let’s add a <header> tag to app/views/layouts/application.html.erb.

<body>
  <header>I am groot</header>
  <div class="container">
  <%= yield %>
  </div>
</body>

Start your local server with bin/dev, and you should have something like the below. If you view the source and look at your CSS, it would be just as you wrote it. So let’s start processing it.

Chrome web browser showing the progress thus far in this tutorial

Process the CSS

  1. Open package.json
  2. Find the scripts section and the flag --style=compressed to the build:css key.

    "scripts": {
      "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets",
      "build:css": "sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules --style=compressed"
    }
    
  3. Once it builds again, you’ll have minified CSS. Yay!

  4. Add two packages to your dependencies in package.json. This is going to allow us to add the browser vendor prefixes.

    npm install postcss-cli autoprefixer
    

    Now that the package is installed, we must add an additional key to our scripts: build:postcss. It essentially says take that minified file we created and add the vendor prefixes to it.

    "build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules --style=compressed",
    "build:postcss": "postcss ./app/assets/builds/application.css -o ./app/assets/builds/application.css --use autoprefixer"
    

    Once that’s been added, you need to update Profile.dev to execute this command. Your file should look something like this:

    js: yarn build --watch
    css: yarn build:css --watch
    postcss: yarn build:postcss --watch
    web: bin/rails server -p 3000
    

    Congrats! 🎉 You’ve got minified CSS with browser vendor prefixes. We can verify this is working by viewing our application's CSS file and ensuring we see a -webkit-backdrop-filter property. We didn’t manually include that when we wrote our CSS, so its presence indicates things are working.

    Now, on to JavaScript (it’s way more manageable).

Minify JavaScript

We don’t need to worry about writing any JavaScript in advance. Rails is already including some for Hotwire. So, we need to make a tiny little change to package.json.

Add the flag --minify to the build key under scripts.

    "scripts": {
        "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --minify",
        ...
    }

That’s it! Your next build will minify your JavaScript and CSS, and you’ll be a happy camper. I hope it helps you 🙂.

Make a plan to vote

If this post helped you and you’re reading this in the next couple of weeks and are from the United States, make sure you have a plan to vote in the midterms. Voting isn’t the only thing we need to do, but it’s undoubtedly one of the most important. Visit Vote Save America if you need additional info on how to register and where to vote.

Written by Matt Haliski

The First of His Name, Consumer of Tacos, Operator of Computers, Mower of Grass, Father of the Unsleeper, King of Bad Function Names, Feeder of AI Overlords.