鼬~~哩賀,我是寫程式的山姆老弟,昨天跟大家一起試試用 ActionCable
做一個簡易的即時聊天室,今天來看看在 Rails 7 被拋棄的 webpacker
, 雖然被拋棄了,但我就不太懂 webpacker
,所以還是要懂一下,夠夠~
Webpacker
是個 Rails 對 webpack 包裝過的 gem,提供對 Rails 友善的前端資源打包工具
webpack 是著名的前端打包工具,在許多前端框架中都有使用,而 Rails 因為是個全端框架,其中也包含了前端的部分,所以 Rails 在 6.x.x 版本開始,由官方支援 webpack 打包,官方也做了一個適合 Rails 使用的 webpack 版本,就叫做 webpacker
打包就是把散落的一堆 js, css, 圖片, 字型等等的檔案,組合起來,變成一大個檔案叫做 application.js
、application.css
這樣
這樣在 html 引用時,只需要引用一個 application.js
, application.css
就好,不需要一個一個檔案來分別引用,是方便取向
再來,Rails 還有機制是載入一次即可,不需要每次重整頁面都重新下載一堆 js 和 css 檔案,節省網路流量、加快載入頁面的速度,雖然也引起不少問題就是了,但設計的本意是好的
也就是 Rails 5.x.x 版本以前,Rails 是使用 Asset Pipeline 來進行前端資源的打包,這個 Asset Pipeline 是由 sprockets-rails 這個 gem 為基礎,至於詳細的 Asset Pipeline 我想要另外一天來看看 Asset Pipeline 的運作,畢竟 Rails 都出到 7.x.x 版了,官方的文件上還有放著 Asset Pipeline,應該還是有點重要的吧(?
然後現在 Rails 7 主打的是用 jsbundling-rails 來取代 webpacker,目前在 Rails Guide 還沒有看到關於 jsbundling 的文章,之後再來爬文,看有沒有關於 Rails 7 打包前端資源的標準用法。
方法一:創新專案的時候
$ rails new --webpack your_project_name
方法二:在現有專案換成 webpacker
在 Gemfile 加入 webpacker
gem 'webpacker'
$ bundle install
$ rails webpacker:install
安裝 webpacker 會產生以下檔案
app/javascript
config/webpacker.yml
:webpacker 的 yaml 設定檔babel.config.js
:Babel 的設定檔,Babel 是個 JS compiler,目前我還不知道 Babel 在 Rails 裡是怎麼運作的 QQpostcss.config.js
:postcss 的設定檔.browserslistrc
:這個也不知道幹嘛的,裡面寫了 default
,應該是針對不同瀏覽器有不同的設定?Webpacker 能打包的有 js
, css
, 靜態檔案
(如圖片、字型),Webpacker 對於每種資源有各自預設的路徑,只要你把檔案放在符合這些預設的路徑,Webpacker 就能幫你把這些檔案包得好好的~
官方建議的檔案結構為下圖
javascript 就放在 app/javascript/src
底下,以及透過 app/javascript/packs
的 application.js
來 import app/javascript/src
的 js 檔案
css 則是放在 app/javascript/stylesheets
底下,透過 app/javascript/packs/application.css
來 import app/stylesheets
的 css 檔案
圖片則是放在 app/javascript/images
底下
如果你是 Rails 6 的專案的話,可以選擇 JS 由 webpacker 打包、CSS 由 asset pipeline 打包,這樣你只需要把 js 放在 app/javascript/
底下,css 繼續放在 app/assets/stylesheets
底下,目前我的專案就是這樣子做的,然後你的 app/views/layouts/application.html.erb
也要做相對應的調整,用 asset pipeline 打包的 css,需要使用 stylesheet_link_tag
;用 webpacker 打包的 javascript,需要使用 javascript_pack_tag
<!DOCTYPE html>
<html>
<head>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
如果是使用 stylesheet_link_tag
的 helper method 來引用 asset pipeline 打包的 css 資源的話,那麼在 html 的引用路徑,就會是 /assets/application-xxx.css
,是 assets 開頭,打包後的 css 會放在 Rails 目錄的 public/assets/application-xxx.css
如果是使用 javascript_pack_tag
的 helper method 來引用 webpacker 打包的 js 資源的話,那麼在 html 的引用路徑,就會是 /packs/js/application-xxx.js
,是 packs 開頭,打包後的 js 會放在 Rails 目錄的 public/packs/js/application-xxx.js
<!-- 用 stylesheet_link_tag 'application' 的 helper method,在 html 會產生出 /assets/application-xxx.css 的引用路徑 -->
<link rel="stylesheet" media="all" href="/assets/application-8d1a5411f99551f9fb40abdc9af842ca3fa76b08310ce466f384a8a9378e01fd.css" data-turbolinks-track="reload">
<!-- 用 javascript_pack_tag 'application' 的 helper method,在 html 會產生出 /packs/js/application-xxx.js 的引用路徑 -->
<script src="/packs/js/application-110a59da79ecc9179fbf.js" data-turbolinks-track="reload"></script>
看到這裡是不是已經暈了呢 XD?,別怕,等你要部署給 production 使用的 fullstack web app 的時候,你才是真的要害怕 XDDD,被各種打包出現的狀況給搞死,都是很正常的,更何況真實的 production 環境中,你還要處理 docker, nginx 等設定問題,那該死的 assets 取不到,就需要一層一層找答案,上線的 deadline 絕對會讓你想盡辦法搞懂這些該死的玩意兒~
在這邊建議大家都私下開新的專案,分別搞懂 css、js 和 靜態資源的打包、引用,來一步一步搞懂這些底層的運作,記得要用 production 環境來部署看看,才會知道打包後的問題在哪,沒錯,這句話就是對我自己講的 XD,這邊真的要耐住性子一步步實驗才能搞懂
什麼 javascript_include_tag
、javascript_pack_tag
、stylesheet_link_tag
、stylesheet_pack_tag
,到底這些排列組合有什麼差別,如果你心裡也有這些疑問的話,那上面這張表應該能多少解決一點疑問
官方有附上兩者的比較,可以用這個來判斷你的專案的 css 和 js 的打包方式,分別是 Sprockets 還是 Webpacker
今天看了很多、然後有用舊專案來驗證,不過舊專案只有用 webpacker 包 js 而已,明天來做點實驗看看用 webpacker 包 css + js + 其他資源檔,我們明天見~