iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Modern Web

Rails,我要進來囉系列 第 13

第十三天:關於 Asset Pipeline 打包那回事

  • 分享至 

  • xImage
  •  

開場白

鼬~~哩賀,我是寫程式的山姆老弟,昨天跟大家一起做一個 webpacker 打包各種靜態資源的實驗練習,今天來看看在 Rails 6 被拋棄的 Asset Pipeline, 雖然被拋棄了,但經過昨天的實驗發現,Asset Pipeline 還是有它的用處的,跟 webpacker 的定位不太一樣,而且是兩者能夠共存的,那既然這樣,就還是要瞭解清楚,夠夠~

https://raw.githubusercontent.com/shrimp509/my-img-host/master/relacs-studio/Rails%E6%88%91%E8%A6%81%E9%80%B2%E4%BE%86%E5%9B%89/day13-1.png

Asset Pipeline 在幹嘛用的?

就是把各種資源檔打包用,你可能會有疑問,什麼是打包?打包哪些東西?為什麼要打包?打包有什麼好處?不打包又會怎樣?OKOK,我們一個一個問題來回答 XD

什麼是打包?打包哪些東西?

講這兩個問題前,你需要理解「網頁是怎麼運作的?」,當你使用瀏覽器打開一個網頁,假如是 google.com 好了,你的瀏覽器會傳送一個 請求(Request) 給 google.com,Google 收到請求之後,Google 的 網頁伺服器(Web Server) 會根據你的請求,經過一系列的判斷與運算後,會將處理好的網頁內容(html+js+css+images+fonts) 透過網路傳到你的瀏覽器,你的瀏覽器收到各種內容之後,將內容 渲染(Render) 呈現給你看。

理解網頁運作之後,就可以回答以上的問題:

  1. 什麼是打包?

    所謂的打包,就是將 網頁內容(html+js+css+images+fonts) 所需要用到的檔案處理後並壓縮

  2. 打包哪些東西?

    網頁內容(html+js+css+images+fonts) 的各個類型檔案,都分別壓縮成 application.js, application.css 等等壓縮過的資源檔案

為什麼要打包?打包有什麼好處?不打包又會怎樣?

  1. 為什麼要打包?

    你瀏覽的那一個網頁頁面,可能需要 aaa.js + bbb.js + ccc.js,以及 ddd.css + eee.css,還有 fff.png + ggg.jpg 這些檔案,如果照上面的理論,那麼你光是瀏覽那一個網頁,瀏覽器就要等待 aaa ~ ggg 七個檔案分別從對方網頁伺服器傳到你的瀏覽器,造成網頁的請求數量多、網頁伺服器的負擔也就相對變重

    打包後的檔案,可能會變成 application.js, application.css,原本多個 js 和多個 css 檔案,就減少成一個檔案

    第二個需要打包的原因,專案中可能會使用 scss, sass 等其他 css 框架,打包的過程中,會將其他框架的內容,轉換成原生 css 內容,使用其他 css 框架的好處就是比較好寫、開發比較快速方便

    第三個需要打包的原因,打包的過程中,會把不重要的空白、換行、註解刪掉,減少檔案大小,讓網頁傳輸更快、網頁打開的速度也更快

  2. 打包有什麼好處?

    減少網頁請求數量、降低伺服器負擔、方便工程師開發

  3. 不打包又會怎樣?

    造成網頁的請求數量多、網頁伺服器的負擔也就相對變重

Asset Pipeline 的運作方式

底層由 sprockets-rails gem 實作,一直到 Rails 7 的 CSS 都還是預設讓 Asset Pipeline 處理

放在 app/assets, lib/assets, vendor/assets 路徑下的檔案,都會被 Asset Pipeline 處理,而他們三個位置有什麼差別呢?

  • app/assets: 跟這個 web app 直接相關的 js 或 css 檔
  • lib/assets: 自己開發的 library,且非直接跟這個 web app 相關的 js 或 css 檔
  • vendor/assets: 第三方開發的 library,像是 js plugins、css framework 等等

除了這三個路徑之外,任何放在 app/assets 資料夾底下的資源檔,都會被 Asset Pipeline 搜尋

打包後的 application-xxx.js 的 xxx 是代表什麼意思?

打包後的 js, css 和其他靜態資源檔,都會帶上一段看似亂碼的名字接在原檔名後面,這代表的是一串唯一的 fingerprint (指紋(?)),只要資源檔的內容有改變, fingerprint 也會跟著改變,代表你目前的內容只會對應到唯一的一串指紋。

這樣的做法有什麼好處呢?

當內容和指紋相符並且唯一,那麼就容易被暫存 (Cache),在網頁內容透過網路的傳送過程當中,有許多節點 (Node),都會有自己的暫存機制,如果你網頁內容沒有改變,當使用者下次瀏覽同一個網頁時,或許使用者的瀏覽器就有保存這個網頁的內容,不需要再到網頁伺服器重新拿一模一樣的網頁內容回來,這樣就可以大大節省網頁的讀取時間,這也就是為什麼通常已經瀏覽過的網頁,開啟的速度會比較快的原因。

其他值得一提的細節

  1. require_tree vs. require_directory

    app/assets/javascripts/application.jsapp/assets/stylesheets/application.css 都有出現 require_tree . 的字眼

    require_tree .
    
    • require_tree:代表的是 sprocket 會 遞迴 把指定的資料夾 (以 require_tree . 來說,指定的資料夾就是 app/assets/javascripts) 底下的所有 js 檔都 include 進去
    • require_directory:代表的是不遞迴,只針對指定的資料夾的 js 檔來 include
  2. CSS Preprocessing

    • 如果沒有啟用 Asset Pipeline 或是 development 環境,scss 檔案就會是由 sass-rails 這個 gem 處理,處理後再作為 css 檔案傳給瀏覽器
    • 如果有啟用 Asset Pipeline 的話,就會事先預處理,並把處理後的檔案放到 public/assets
    • 同理也適用 coffee script
  3. 在開發環境下的調整

    • 如果想要在「找不到資源檔時報錯」

      config.assets.unknown_asset_fallback = false
      

      相反,如果設為 true,當找不到資源檔時,不會報錯,只會顯示找不到圖片,這個選項預設為 false。

      我在試的時候,發現這個選項已經被 Deprecated 了,所以參考就好吧

      https://raw.githubusercontent.com/shrimp509/my-img-host/master/relacs-studio/Rails%E6%88%91%E8%A6%81%E9%80%B2%E4%BE%86%E5%9B%89/day13-2.png

  4. Asset Pipeline 可與 CDN host 聯動

    其實這篇 RailsGuide 花蠻多篇幅在講這一塊的,只是目前我還沒自己動手接過 CDN,就先不著墨在這邊,有需要的時候再來研究

總結

這篇在看的時候,比較沒有像之前那麼不知道在做什麼,畢竟之前還是有碰過 Asset Pipeline 一點的,看完 WebpackerAsset Pipeline 之後,我發覺我比較喜歡 webpacker 打包後的樣子,不過之後 Rails7 又換了一種打包方式,不知道是長怎樣,也不確定比 webpacker 好在哪裡,晚點再來做點研究,今天就先這樣拉,我們明天見~


上一篇
第十二天:實驗用 webpacker 打包 js+css+font+image 資源檔
下一篇
第十四天:實驗用 Asset Pipeline 打包 js+css+font+image 資源檔
系列文
Rails,我要進來囉30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
一半一半
iT邦新手 5 級 ‧ 2022-09-28 22:07:26

Rails7 的importmap 也不主流。还存在一些浏览器支持的问题。这里有篇文章可以看一下。

点击查看1楼采纳回答

Sam iT邦新手 4 級 ‧ 2022-09-29 09:29:29 檢舉

感謝支援~

我要留言

立即登入留言