鼬~~哩賀,我是寫程式的山姆老弟,昨天跟大家一起做一個 webpacker 打包各種靜態資源的實驗練習,今天來看看在 Rails 6 被拋棄的 Asset Pipeline
, 雖然被拋棄了,但經過昨天的實驗發現,Asset Pipeline
還是有它的用處的,跟 webpacker
的定位不太一樣,而且是兩者能夠共存的,那既然這樣,就還是要瞭解清楚,夠夠~
就是把各種資源檔打包用,你可能會有疑問,什麼是打包?打包哪些東西?為什麼要打包?打包有什麼好處?不打包又會怎樣?OKOK,我們一個一個問題來回答 XD
講這兩個問題前,你需要理解「網頁是怎麼運作的?」,當你使用瀏覽器打開一個網頁,假如是 google.com 好了,你的瀏覽器會傳送一個 請求(Request)
給 google.com,Google 收到請求之後,Google 的 網頁伺服器(Web Server)
會根據你的請求,經過一系列的判斷與運算後,會將處理好的網頁內容(html+js+css+images+fonts)
透過網路傳到你的瀏覽器,你的瀏覽器收到各種內容之後,將內容 渲染(Render)
呈現給你看。
理解網頁運作之後,就可以回答以上的問題:
什麼是打包?
所謂的打包,就是將 網頁內容(html+js+css+images+fonts)
所需要用到的檔案處理後並壓縮
打包哪些東西?
把 網頁內容(html+js+css+images+fonts)
的各個類型檔案,都分別壓縮成 application.js
, application.css
等等壓縮過的資源檔案
為什麼要打包?
你瀏覽的那一個網頁頁面,可能需要 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 框架的好處就是比較好寫、開發比較快速方便
第三個需要打包的原因,打包的過程中,會把不重要的空白、換行、註解刪掉,減少檔案大小,讓網頁傳輸更快、網頁打開的速度也更快
打包有什麼好處?
減少網頁請求數量、降低伺服器負擔、方便工程師開發
不打包又會怎樣?
造成網頁的請求數量多、網頁伺服器的負擔也就相對變重
底層由 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)
,都會有自己的暫存機制,如果你網頁內容沒有改變,當使用者下次瀏覽同一個網頁時,或許使用者的瀏覽器就有保存這個網頁的內容,不需要再到網頁伺服器重新拿一模一樣的網頁內容回來,這樣就可以大大節省網頁的讀取時間,這也就是為什麼通常已經瀏覽過的網頁,開啟的速度會比較快的原因。
require_tree
vs. require_directory
在 app/assets/javascripts/application.js
和 app/assets/stylesheets/application.css
都有出現 require_tree .
的字眼
require_tree .
require_tree
:代表的是 sprocket 會 遞迴 把指定的資料夾 (以 require_tree .
來說,指定的資料夾就是 app/assets/javascripts
) 底下的所有 js 檔都 include 進去require_directory
:代表的是不遞迴,只針對指定的資料夾的 js 檔來 includeCSS Preprocessing
sass-rails
這個 gem 處理,處理後再作為 css 檔案傳給瀏覽器public/assets
在開發環境下的調整
如果想要在「找不到資源檔時報錯」
config.assets.unknown_asset_fallback = false
相反,如果設為 true,當找不到資源檔時,不會報錯,只會顯示找不到圖片,這個選項預設為 false。
我在試的時候,發現這個選項已經被 Deprecated 了,所以參考就好吧
Asset Pipeline 可與 CDN host 聯動
其實這篇 RailsGuide 花蠻多篇幅在講這一塊的,只是目前我還沒自己動手接過 CDN,就先不著墨在這邊,有需要的時候再來研究
這篇在看的時候,比較沒有像之前那麼不知道在做什麼,畢竟之前還是有碰過 Asset Pipeline
一點的,看完 Webpacker
和 Asset Pipeline
之後,我發覺我比較喜歡 webpacker
打包後的樣子,不過之後 Rails7 又換了一種打包方式,不知道是長怎樣,也不確定比 webpacker
好在哪裡,晚點再來做點研究,今天就先這樣拉,我們明天見~
Rails7 的importmap 也不主流。还存在一些浏览器支持的问题。这里有篇文章可以看一下。
感謝支援~