iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Modern Web

Rails,我要進來囉系列 第 11

第十一天:關於 Webpacker 打包那回事

  • 分享至 

  • xImage
  •  

開場白

鼬~~哩賀,我是寫程式的山姆老弟,昨天跟大家一起試試用 ActionCable 做一個簡易的即時聊天室,今天來看看在 Rails 7 被拋棄的 webpacker, 雖然被拋棄了,但我就不太懂 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/day11-1.png

Webpacker 在幹嘛用的?

Webpacker 是個 Rails 對 webpack 包裝過的 gem,提供對 Rails 友善的前端資源打包工具

webpack 是著名的前端打包工具,在許多前端框架中都有使用,而 Rails 因為是個全端框架,其中也包含了前端的部分,所以 Rails 在 6.x.x 版本開始,由官方支援 webpack 打包,官方也做了一個適合 Rails 使用的 webpack 版本,就叫做 webpacker

什麼是打包?

打包就是把散落的一堆 js, css, 圖片, 字型等等的檔案,組合起來,變成一大個檔案叫做 application.jsapplication.css 這樣

為什麼要打包?

這樣在 html 引用時,只需要引用一個 application.js, application.css 就好,不需要一個一個檔案來分別引用,是方便取向

再來,Rails 還有機制是載入一次即可,不需要每次重整頁面都重新下載一堆 js 和 css 檔案,節省網路流量、加快載入頁面的速度,雖然也引起不少問題就是了,但設計的本意是好的

在 Webpacker 出現之前

也就是 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 打包前端資源的標準用法。

Webpacker 的安裝方法

方法一:創新專案的時候

$ rails new --webpack your_project_name

方法二:在現有專案換成 webpacker

  1. 在 Gemfile 加入 webpacker

    gem 'webpacker'
    
  2. $ bundle install

  3. $ rails webpacker:install

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/day11-2.png

安裝 webpacker 會產生以下檔案

  1. app/javascript
  2. config/webpacker.ymlwebpacker 的 yaml 設定檔
  3. babel.config.jsBabel 的設定檔,Babel 是個 JS compiler,目前我還不知道 Babel 在 Rails 裡是怎麼運作的 QQ
  4. postcss.config.js:postcss 的設定檔
  5. .browserslistrc:這個也不知道幹嘛的,裡面寫了 default,應該是針對不同瀏覽器有不同的設定?

Webpacker 的運作方式

Webpacker 能打包的有 js, css, 靜態檔案(如圖片、字型),Webpacker 對於每種資源有各自預設的路徑,只要你把檔案放在符合這些預設的路徑,Webpacker 就能幫你把這些檔案包得好好的~

官方建議的檔案結構為下圖

  1. javascript 就放在 app/javascript/src 底下,以及透過 app/javascript/packsapplication.js 來 import app/javascript/src 的 js 檔案

  2. css 則是放在 app/javascript/stylesheets 底下,透過 app/javascript/packs/application.css 來 import app/stylesheets 的 css 檔案

  3. 圖片則是放在 app/javascript/images 底下

    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/day11-3.png

如果你是 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,這邊真的要耐住性子一步步實驗才能搞懂

Webpacker 和 Asset Pipeline(Sprockets) 的 helper methods 比較

什麼 javascript_include_tagjavascript_pack_tagstylesheet_link_tagstylesheet_pack_tag,到底這些排列組合有什麼差別,如果你心裡也有這些疑問的話,那上面這張表應該能多少解決一點疑問

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/day11-4.png

官方有附上兩者的比較,可以用這個來判斷你的專案的 css 和 js 的打包方式,分別是 Sprockets 還是 Webpacker

總結

今天看了很多、然後有用舊專案來驗證,不過舊專案只有用 webpacker 包 js 而已,明天來做點實驗看看用 webpacker 包 css + js + 其他資源檔,我們明天見~


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

尚未有邦友留言

立即登入留言