The asset pipeline
Asset Pipeline 有三個特性:
- asset directories
- manifest files
- preprocessor engines
詳情可以參考這篇:Rails Guides entry on the asset pipeline
Asset directories
在 Rails 3.0 以及之前的版本,Asset 靜態檔案放 public/ 目錄底下:
- public/stylesheets
- public/javascripts
- public/images
這些檔案透過 http://example.com/stylesheets 等網址直接發送給瀏覽器。Rails 3.0 之後的版本也會這麼做。
在最新的 Rails 版本中,Asset 靜態檔案放在三個標準的目錄底下,各有各的用途:
- app/assets: 給 application 用的檔案
- lib/assets: 自己開發的檔案
- vendor/assets: 第三方程式的檔案
這三個目錄底下,還有幾個針對不同類型檔案的子目錄:
$ ls app/assets/
images/ javascripts/ stylesheets/
所以剛剛的 custom.css.sass 放在 app/assets/stylesheets 裡面,因為它只在 application 中使用。
Manifest files
把 Asset 檔案放在適當的目錄底下之後,可以使用 manifest files 告訴 Rails:「嘿!幫我把這些 Asset 檔案合併成一個單一檔案!」(透過 Sprockets gem 實作,只能合併 CSS 和 JavaScript 檔案,圖片無法合併)。
可以看一下 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,
* vendor/assets/stylesheets, or vendor/assets/stylesheets of plugins, if any,
* 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 styles defined in the other CSS/SCSS
* files in this directory. It is generally better to create a new file per
* style scope.
*
*= require_tree .
*= require_self
*/
最重要的其實是下面的 CSS 註解,其實是透過 Sprockets 來匯入正確的檔案:
/*
.
.
.
*= require_tree .
*= require_self
*/
其中這行:
*= require_tree .
意思是確認在 app/assets/stylesheets 目錄底下的所有 CSS 檔案(包括子目錄的檔案)都會匯入到 application.css。
然後這行:
*= require_self
表示會把 application.css 本身有的 CSS 也一起匯入。
Preprocessor engines
準備好 Asset 檔案之後,Rails 會使用 preprocessor engines 來處理檔案,再透過 manifest files 合併檔案,最後發送給瀏覽器。
透過副檔名,可以讓 Rails 知道該用什麼 preprocessor engines 處理檔案。最常用的是:
- Sass 檔案的
.scss - CoffeeScript 檔案的
.coffee - ERb 檔案的
.erb
關於 CoffeeScript 可以看這篇文章:RailsCast on CoffeeScript basics
preprocessor engines 可以串接在一起,以下只會使用 CoffeeScript processor:
foobar.js.coffee
這行則會同時使用 CoffeeScript 和 ERb processor:
foobar.js.erb.coffee
preprocessor engines 的副檔名會從右到左處理,所以 CoffeeScript processor 會先被執行。
Efficiency in production
Asset Pipeline 最棒的地方是會自動幫你優化檔案,這樣在正式上線的環境中(production)就可以增進應用程式的效率。以前的方法都是會把 CSS 或 JavaScript 按照功能需求,拆分成好幾個檔案,同時還會使用很多縮排,這對開發者來說很方便,但在 production 中卻降低效益。
當你的檔案很多的時候,反而會加重網頁載入的時間,結果影響使用者的瀏覽體驗。
Asset Pipeline 在 production 環境中,會合併所有 CSS 並匯入到一個 CSS 檔案裡(application.css),也會合併所有 JavaScript 然後匯入到一個 JavaScript 檔案裡(application.js),同時也會壓縮檔案,把空白刪除,降低檔案大小。
這樣就可以在開發環境中使用格式化的檔案,到了正式上線環境使用優化過的檔案。