Understanding the Asset Pipeline in Ruby on Rails
Tags: rails, ruby, tutorial
Published: 2019-03-22 14:44:09

---
title: Understanding the Asset Pipeline in Ruby on Rails
published: true
tags: rails, ruby, tutorial
canonical_url: https://web-crunch.com/understanding-asset-pipeline-ruby-on-rails/
---

The asset pipeline has been a game changer for a number of years in the Ruby on Rails community. This article & video is an overview of what the asset pipeline is, how it’s used, and the benefits of such a tool.

{% youtube kgEcdBGpr54 %}

### What is the asset pipeline?

The Ruby on Rails documentation does a great job explaining the “what”.

> The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages and pre-processors such as CoffeeScript, Sass, and ERB. It allows assets in your application to be automatically combined with assets from other gems.

A brand new rails application comes stock with the `sprockets-rails` gem. This gem combines the power of three other gems (`sass-rails`, `coffee-rails` and `uglifier`) with its own to make assets in your app a breeze to work with. With a little know-how, you can add `CSS`, add `JavaScript`, reference images, and more inside a given Ruby on Rails application using the asset pipeline.

#### What about Rails 6 coming around the corner?

It’s true that Rails 6 is very close to being released. It will feature a different take on adding JavaScript to your app that is more node.js driven. This harnesses the power of the `webpacker` gem to allow modern JavaScript and more to be included inside your ruby on rails application. This happens outside of the asset pipeline entirely. For now, it’s advised to keep using the asset pipeline for images and CSS/SCSS and server JavaScript from the new webpacker `app/javascript` directory.

### Main Features

A generalized perk of using the Asset Pipeline is for performance and speed. Among those generalized gains we get the following:

- **File concatenation** – serving fewer files means fewer requests your browser has to make.
- **SHA256 fingerprint** – Cache files automatically with fingerprints. Update only the files that need to be.
- **Minification / Compression** – Minification means smaller file sizes and less “bytes” to serve per request.

Note: Right around 20:08 I try and require “log.js”. It turns out you don’t even need to require it thanks to the “require\_tree . ” declaration below it in the same file. I also spelled “require” wrong. ![🤦🏼‍♂️](https://s.w.org/images/core/emoji/11.2.0/72x72/1f926-1f3fc-200d-2642-fe0f.png) I just wanted to clear that up!

### Usage

In a brand new Rails application, you should find several places to house your assets. The main one tied your app is `app/assets`. Within that folder is a `images`, `javascripts`, and `stylesheets` directory.

#### Images

Images are relatively self-explanatory but come with some conventions to remember when rendering them in your views or CSS files.

Including an image in a view happens by way of rails helpers

```erb
<%= image_tag "cat.jpg", alt: "Black Cat" %>

```

Here we include an image. The `image_tag` helper expects the image to be located at `app/assets/images` within the app. You can add subfolders within `images` and reference an image that way as well.

```erb
<%= image_tag "marketing/animals/cat.jpg", alt: "black cat" %>

```

Adding background images in your `CSS` files comes with a gotchya as well.

```css
body {
  background-image: url('/assets/images/cat.jpg');
}

```

You might think the above code would work but unfortunately, it does not. Instead, we harness another helper to find the image.

```css
body {
  background-image: image-url('cat.jpg');
}

```

Notice the `image-url` helper and the fact that I don’t need to declare any relative path. Pretty cool!

#### Stylesheets

Inside your `app/assets/stylesheets` directory you’ll see an `application.css` file. This is the source of truth for your apps CSS that isn’t already in the `vendor` or `lib` directories (2 other places you can house assets). At any time you can change `application.css` to `application.scss` and gain the benefits of writing `SCSS` in lieu of `CSS`. The `sass-rails` gem I mentioned prior gets put to work here.

A default `application.css` file might look like the following:

```css
/* app/assets/stylesheets/application.css */

/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */

```

The `*= require_tree .` syntax might look like a comment but it’s actually responsible for rendering all the files within `app/assets/stylesheets` and automatically including them here. That way you never have to include them manually. The `*= require_self` comment requires the file itself which is what ends up in our main layout template. You can add any CSS file you like and require it here if it’s not already inside the `app/assets/stylesheets` directory. You might do this from the `vendor` directory or if by chance you installed a gem that had some associated styles you needed to harness.

Linking to those assets looks like this.

```erb
<!-- app/views/layouts/application.html.erb -->

<!DOCTYPE html>
<html>
  <head>
    <title>Asset Pipeline</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>

```

Above you’ll see some handy Rails helpers give us a hand including both our `application.css` stylesheet and an `application.js` JavaScript file found in `app/assets/javascripts`

Notice we only render the `application.css` and `application.js` files and nothing else. If I were to create a new `global.css` file within `app/assets/stylesheets` it would be included in the page automatically.

#### JavaScript

Like CSS/SCSS, the same principle applies for JavaScript but we use a slightly different syntax.

```javascript
// app/assets/javascripts/application.js

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= requre log
//= require_tree .

```

The `//= require log` I added as an example. I created a new file called `log.js` and added it to `app/assets/javascripts`. Then I require it in `application.js` so it gets automatically injected to our layout. The perk of this locally isn’t as grand as it is in production where all of your files get compiled down into one. This process saves on file size, request size, and speed which is the whole point (plus how easy it is).

### Configuration and Adding new JavaScript and CSS

Say you want to add new files to the mix? In my video I added Bootstrap for grins. This meant adding a `bootstrap.css` file and a `bootstrap.js` file to our `vendor` folder since it’s code we’ll utilize but not modify. You’ll want your vendor folder to have an `assets` directory and within that directory a `stylesheets` directory and `javascripts` directory.

That structure ends up looking like this:

```bash
vendor
└── assets
    ├── javascripts
    │   └── bootstrap.js
    └── stylesheets
        └── bootstrap.css

```

Simply adding those files to `vendor` won’t suffice. We need to tell our app about them.

The `sprockets-rails` gem comes with a handy `manifest.js` file within `app/assets/config/`. That file too has its own way of including assets. My file ended up like the following:

```javascript
// app/assets/config/manifest.js

//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css

//= link bootstrap.js
//= link bootstrap.css

```

The top three lines come by default. The bottom two I added which in return will reference the newly added files in `vendor`. Notice the `link_tree` declaration. This means all files within a folder and subfolders. The `link_directory` declarations mean only the files within the named directory.

We’re still not 100% done. The application doesn’t quite know about these two new additions. Let’s fix that.

```ruby
# config/initializers/assets.rb

# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
Rails.application.config.assets.precompile = ["manifest.js"]

```

Above I made a change to an `assets.rb` initializer file within our `config` directory. The last line sets a configuration to look for the `manifest.js` file within `app/assets/` to find what new assets to precompile for use in-app. After saving this you will want to restart your rails server if it already running.

One last piece of the puzzle is to include those new files in our view. I didn’t want these files to compile down into the `application.js` file though they could if we wanted. Instead, I render them as different files like the following:

```erb
<!DOCTYPE html>
<html>
  <head>
    <title>Pipeline</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= javascript_include_tag 'https://code.jquery.com/jquery-3.3.1.slim.min.js' %>
    <%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js' %>

    <%= stylesheet_link_tag 'bootstrap', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'bootstrap', 'data-turbolinks-track': 'reload' %>

    <%= javascript_include_tag 'bootstrap', media: 'all', 'data-turbolinks-track': 'reload' %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>

```

Bootstrap comes with `jQuery` and `popper.js` as dependencies so I needed to add those as well. Rather than including them like we did Bootstrap I simply linked to their CDN files. I wouldn’t recommend trusting CDNs in production though.

A final refresh should get your Bootstrap!

### Is the Asset Pipeline still relevant?

I absolutely think so. Right now, with Rails 6 on the horizon, we’ll start to see JavaScript live elsewhere but images, CSS, fonts, and more can live well inside the asset pipeline. It comes with a few conventions to learn but after some continued use you’ll learn to appreciate the magic behind the asset pipeline in Ruby on Rails.

### Shameless Plug!

If you liked this post, I have more videos on [YouTube](https://youtube.com/c/webcrunch) and here on my [blog](https://web-crunch.com). Want more content like this in your inbox? [Subscribe to my newsletter](https://web-crunch.com/subcribe) and get it automatically.

#### Check out my course

[  
 ![https://i2.wp.com/i.imgur.com/KIaaJEB.jpg?ssl=1](https://i2.wp.com/i.imgur.com/KIaaJEB.jpg?ssl=1)  
](https://hellorails.io)

![☝](https://s.w.org/images/core/emoji/11.2.0/72x72/261d.png) Want to learn Ruby on Rails from the ground up? Check out my upcoming course called [Hello Rails](https://hellorails.io).

The post [Understanding the Asset Pipeline in Ruby on Rails](https://web-crunch.com/understanding-asset-pipeline-ruby-on-rails/) appeared first on [Web-Crunch](https://web-crunch.com).