12/08/2018, 16:48

Tìm hiểu về Rails Asset Pipeline

Asset pipeline cung cấp một framework cho phép kết nối, nén hay giảm bớt những tài nguyên về CSS hay JS. Nó còn cho phép chúng ta có thể viết CSS, JS bằng một số ngôn ngữ khác nữa như CoffeeScript, Sass hay ERB. Các file assets trong ứng dụng được kết nối một cách tự động cùng với những assets chứa ...

Asset pipeline cung cấp một framework cho phép kết nối, nén hay giảm bớt những tài nguyên về CSS hay JS. Nó còn cho phép chúng ta có thể viết CSS, JS bằng một số ngôn ngữ khác nữa như CoffeeScript, Sass hay ERB. Các file assets trong ứng dụng được kết nối một cách tự động cùng với những assets chứa trong gem.

Asset pipeline được thực hiện bởi gem sprockets-rails , thông thường khi khởi tạo ứng dụng rails nó sẽ mặc định được enable. Ta có thể disable bằng option khi khởi tạo ứng dụng:

rails new appname --skip-sprockets

Rails tự động thêm vào các gem sass-rails, coffee-railsuglifier được sử dụng bởi sprockets cho phép nén các asset. Ở bài viết này mình sẽ không trình bày kĩ về cơ chế nén assets, các bạn có thể tìm hiểu thêm trên rails tutorial hay các trang liên quan. Tính năng chính của Rails Assets Pipeline mình sẽ gọi tắt RAP là kết nối các assets lại với nhau cho phép giảm số lượng requests khi browser cần để render 1 trang. Bên cạnh đó RAP còn cho phép nén assets. Ví dụ như các file CSS sẽ được loại bỏ "whitespace" và "comments". Hơn thế nữa, chúng ta có thể coding assets bẵng những ngôn ngữ cao hơn như Sass, Coffee, ...

Fingerprinting là một kỹ thuật đặt tên file dựa trên nội dung của file. Khi nội dung của file thay đổi, filename cũng sẽ được thay đổi theo. Kĩ thuật này thêm vào filename một hash string. Ví dụ:

global-908e25f4bf641868d8683022a5b62f54.css

Nhờ cơ chế này ta có thể quản lý assets như các phiên bản. Filename là unique, HTTP header được set để khuyến khích lưu cache nhằm tăng hiệu năng cho ứng dụng của bạn.

Pipline asset được tổ chức trong ứng dụng bởi 1 trong 3 thứ mục sau: app/assets, lib/assets hoặc vendor/assets.

  • app/assets lưu trữ các file assets được sở hữu bởi ứng dụng như custom images, JavaScript files, stylesheets.
  • lib/assets lưu trữ các thư viện assets không chỉ trong phạm vi ứng dụng mà còn được chia sẻ giữa các ứng dụng với nhau
  • vendor/assets lưu trữ các file assets của bên thứ 3

Để truy cập asset ta sử dụng javascript_include_tagstylesheet_link_tag

<%= stylesheet_link_tag "application", media: "all" %> <%= javascript_include_tag "application" %>

Nếu sử dụng turbolinks gem, mặc định sẽ được included trong ứng dụng. Sau khi include "data-turbolinks-track" nó cho phép kiểm tra xem asset đã được update hay chưa sau đó load vào page.

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

Manifest files hiểu đơn giản là những file chứa assets. Ví dụ application.js là một Manifest file. Manifest chứa các thông tin directives, điều này giúp cho Sprockets xử lý chúng nếu cần, nối thành một file theo thứ tự và cuối cùng là nén lại thành một file css, js. Tất nhiên phải đảm bảo config Rails.application.config.assets.compress true.

app/assets/javascripts/application.js:

//= require core //= require projects //= require tickets

sẽ được generate HTML như sau:

<script src="/assets/core.js?body=1"></script> <script src="/assets/projects.js?body=1"></script> <script src="/assets/tickets.js?body=1"></script>

Đối với JavaScript files, Sprockets directives bắt đầu bằng //=. require directive sử dụng để cho thông báo cho Sprocket biết file nào sẽ được require.

require_tree

//= require_tree .

Require tree cho phép bạn include tất cả file trong thư mục với cơ chế đệ quy. Chúng ta cũng có thể require_directory directive nếu muốn include các file trong một thư mục nhất định. Tuy nhiên nên lưu ý khi sử dụng require_tree vì nó sẽ inlude các file theo thứ tự từ trên xuống dưới mà đây có thể không phải là thứ tự mà ta mong muốn

Tương tự đối với app/assets/stylesheets/application.css

/* ... *= require_self *= require_tree . */

Những thông tin trên đây được tóm tắt và trình bày dựa theo cách hiểu của mình dựa trên rails guide. Mình sẽ tiếp tục cập nhật thêm ở thời gian tới, hi vọng bài viết này có thể cũng cấp thêm kiến thức bổ ích cho các bạn.

0