1. What is Asset Pipeline?
The Ruby on Rails documentation has a fairly specific definition and explanation of the Asset Pipeline as below
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.
By definition, the Asset pipeline
gives us a framework for joining, minifying, or compressing JavaScipt
and CSS
files in our project. In addition, we can also compile assets in other languages such as CoffeeScipt, Sass and ERB, it also allows us to combine the gem’s assets in the application automatically.
Usually a newly created Rails application comes with the sprockets-rails
gem. This gem has the power of 3 other gems which are sass-rails
, coffee-rails
and uglifier
, also by default is the gem that carries the implementation of the Asset pipeline in our application.
2. Features of Asset Pipeline
The first big draw of the Asset pipeline is in performance and speed, and it also offers some of the following features:
- Joining assets, or CSS files, into a separate file, reducing the number of files helps our browser to make fewer requests.
- With SHA256 fingerprints, the automatically cached files along with the fingerprint are only updated when the contents of the file change, preventing the browser from caching the old version of the assets causing some unexpected errors.
- Shrinking and compressing also helps to reduce the size of our assets files which means we will reduce a few “bytes” for each request.
- There is also support for languages like Sass, CoffeeScript and ERB.
3. Usage
In a new Rails application, we can find many places for the app’s assets, but the main thing is app/assets
. This directory contains images
paths for images
, javascript
files for JavaScript files, and finally stylesheets
containing CSS files for styling our application.
3.1. Images
To attach an image in our view, we can use the Rails view helpers, namely image_tag
1 2 | <%= image_tag "mouse.jpg", alt: "A Cat named Mouse" %> |
In the above code, we use image_tag
to attach a picture of a cat named Mouse to our view, image_tag
will default to mouse.jpg
will be in the path app/assets/images
, or we have You can add subfolders to images
to make the project layout more intuitive.
1 2 | <%= image_tag "animals/mouse.jpg", alt: "A Cat named Mouse" %> |
CSS files will be a little different, normally if we want to get an image as the background for an element, in CSS we will write the following.
1 2 3 4 | body { background-image: url('/assets/images/mouse.jpg'); } |
Unfortunately, this won’t work. Instead, we’ll need to use a helper again to find the image in the assets, which is image_url
. We will write the following
1 2 3 4 | body { background-image: image-url('mouse.jpg'); } |
This way we don’t need to add a path either, right!
3.2. Stylesheets
In the path app/assets/stylesheets
we will see that there is an application.css
file. This is the source that contains the CSS for your application that is not stored in the vender
or lib
(there are also 2 other places that may contain assets). Alternatively, we can also change the .css
extension to .scss
order to take advantage of SCSS
, the sass-rails
gem will work in this case.
A default application.css
file will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* 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 */ |
Here, the *=require_tree
syntax looks like a comment but it is actually responsible for rendering all the files in app/assets/stylesheets
and automatically attaching them here, this way we won’t need it. must be manually attached again. *= require_self
used to attach itself, which means it will apply any css
written here before any css
. We can also add any css
file and require it here for use in our application.
Use the assets in the website layout as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!-- 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> |
3.3. JavaScript
Similar to CSS / SCSS, the same rule applies to the JavaScript in the Assets pipeline but the syntax will be slightly different.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // 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 //= require custom //= require_tree . |
In the above file, //=require custom
used to attach the custom.js file just created in app/assets/javascripts
manually to our layout. This process will help us to reduce the file size, the size of the request as well as increase the speed of the application. In a local environment it won’t make much of a difference, but if going to production, these minifications will provide a lot of performance value.
Above are the basics of Assets Pipeline in Ruby on Rails.
Reference links