Rails Asset Pipeline Simple Guide
Using Rails is full of magic. Asset pipeline is one of the magical features from Rails. But, it’s always let user confused and not sure how it work. This guide aims to provide the simple way to explain how asset pipeline works and how you can using it with your Rails application.
4 Purposes for using Asset Pipeline
1. Precompile
It is precompiled CoffeeScript to Javascript and SASS to CSS Stylesheet.
2. Concatenate
It’s concatenated multiple javascript files to application.js and concatenate multiple stylesheet files to application.css. This process will help to reduce the numbers of http request and speed up the page loading.
3. Minify
It’s minified both javascript and stylesheet files by removing whitespace and comments. This process will help to reduce the size of assets and speed up the page loading as well.
4. Fingerprinting
For each file update, a new hash string will be appended at the end of each asset file name. This process can force the browser to request the new updated files and eliminate browser caching the old asset issue.
Asset Paths
Before asset pipeline starts to precompile your asset files, it will look for following default asset load paths to find those files.
app/assets
This folder should contain all your application related assets such as javascripts, stylesheets, images, fonts and so on. All assets not included javascripts and stylesheets will automatically add in asset precompile. So to simplify your assets management, I highly recommend you to put all assets in this folder.
lib/assets
If you have your own libraries’ assets which shared across multiple applications, you can put those assets in this folder. Beware those assets will not be automatically included in asset precompile.
vendor/assets
For third party assets not owned by you. You can put those assets in this folder. Beware those assets will not be automatically included in asset precompile.
Usually, the assets folders structure will be organised as following structure:
The first subfolder often arranged as asset file type. However, you are not restricted to organised your asset in this way. You can use any folder name for this first subfolder. For example, you can name the folder like app/assets/abc and put your asset either fonts, images, javascripts and stylesheets inside this folder.
Asset pipeline will ignore these first subfolders and directly go inside these folders for searching the asset files.
Beware video file type may not be suitable for using asset pipeline. You need to put the video files in public/videos to bypass the asset pipeline.
How asset pipeline precompile work?
You can manually start asset pipeline precompile by executing the following command:
bundle exec rake assets:precompile
After that, all asset files will be precompiled and stored in public/assets/ folder.
However, you may wonder how asset pipeline know which asset files should precompile?
There are two methods to let asset pipeline know which assets need to include for precompiling.
1. Manifest files
application.css
This manifest file tells asset pipeline which css or scss files should be required or included for precompiling.
application.js
This manifest file tells asset pipeline which js or coffee files should be required or included for precompiling.
Directive
We use directive with asset path argument to define which asset files should be required or included for precompiling.
- require [path] — inserts the contents of the asset source file specified by path. If the file is required multiple times, it will appear in the bundle only once.
- include [path] — works like require, but inserts the contents of the specified source file even if it has already been included or required.
- require_directory [path] — requires all source files of the same format in the directory specified by path. Files are required in the alphabetical order.
- require_tree [path] — works like require_directory, but operates recursively to require all files in all subdirectories of the directory specified by path.
- require_self — tells Sprockets to insert the body of the current source file before any subsequent require or include directives.
- depend_on [path] — declares a dependency on the given path without including it in the bundle. This is useful when you need to expire an asset’s cache in response to a change in another file.
- depend_on_asset [path] — works like depend_on, but operates recursively reading the file and following the directives found.
- stub [path] — allows dependency to be excluded from the asset bundle. The path must be a valid asset and may or may not already be part of the bundle. Once stubbed, it is blacklisted and can’t be brought back by any other require.
2. Assets initializer config file
This config file is located at config/initializers/assets.rb.
To add additional asset files for precompiling, uncomment the following line and add the asset file name in the array:
Rails.application.config.assets.precompile += %w( search.js )
Use cases
So, you may wonder this method is suitable for which cases?
- For instance, if you have javascript or stylesheet files which didn’t specify from manifest files, and you want to add those asset files to asset pipeline. Then you will need to add it in assets initializer config file.
- Another case, if you have non-JS/CSS files which didn’t store under app/assets/ folder, and you want to add those asset files to asset pipeline. Then you will need to add it in assets initializer config file as well.
Usage
After asset files have precompiled, it will be stored in public/assets/ folder. You can use multiple helper methods to access the files.
Helper methods for ERB file
asset_path(“application.js”) # => /assets/application.jsasset_url(“application.js”) # => http://example.com/assets/application.jsaudio_path("horse.wav") # => /audios/horse.wavaudio_tag("sound”) # => <audio src="/audios/sound">font_path("font.ttf") # => /fonts/font.ttfimage_path("edit.png") # => "/assets/edit.png"image_tag("icon.png") # => <img src="/assets/icon.png" alt="Icon" data-no-retina="true">video_path("hd.avi") # => /videos/hd.avivideo_tag("trailer.ogg") # => <video src="/videos/trailer.ogg"></video></audio>
Helper methods for SASS file
asset-data-uri("image.jpg”) # => url(data:image/jpeg;base64,...)asset-path("image.jpg") # => /assets/image.jpgasset-path("image.jpg", $digest: true) # => /assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpgasset-url("image.jpg") # => url("/assets/image.jpg")asset-url("image.jpg", $digest: true) # => url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg")font-path("font.ttf") # => /assets/font.ttffont-path("font.ttf", $digest: true) # => /assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttffont-url("font.ttf") # => url("/assets/font.ttf")font-url("image.jpg", $digest: true) # => url("/assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttf")image-path("image.jpg") # => /assets/image.jpgimage-path("image.jpg", $digest: true) # => /assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpgimage-url("image.jpg") # => url("/assets/image.jpg")image-url("image.jpg", $digest: true) # => url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg")
Further Reading
- For official Guide, please visit http://guides.rubyonrails.org/asset_pipeline.html
- David Khourshid wrote an awesome post Aesthetic Sass 1: Architecture and Style Organization. I recommend reading it to get a better understanding of Sass organization. Thanks @mchlfhr suggest this post.
Footnote
This is the first simple guide from UiReady. If you find anything in the above, that is incorrect or have feedback for this guide. Please don’t hesitate and leave your comment below.
If this help, just click ♥ to let more people find it too!
Struggle on building frontend components and integrate to Ruby on Rails? Be sure to check out UiReady — Bootstrap theme marketplaces dedicated for Rails developers.