DEV Community

Hungmi
Hungmi

Posted on • Edited on

2 1

忘了 webpacker,舊版 Rails app 升級 jsbundling-rails + Hotwire

本篇升級方式的好處

  1. 降低了現存的 Rails 4 項目升級門檻,不需要 webpacker 就能開心的使用 node packages。
  2. 若想放棄 jQuery,新頁面將不需要再導入相關依賴。
  3. 享受 Hotwire + Turbo 帶來的效率及速度優化。 希望能幫到像我一樣正在穩定開發但又想升級項目的朋友們!

先升級至 Rails 6

因為 jsbundling-railshotwire-rails 本身就限制至少 Rails 6,因此必須升級,但不需要安裝 webpacker,因此不會動到 JS & CSS 大幅降低了升級工作量,以我個人而言,從「太難了我放棄」到「兩天完成升級」🚀
Rails 的升級步驟可參考 t27duck 撰寫的 How I upgrade Ruby on Rails,其中特別注意 Step 6 Update the Default Configuration and Framework Files


本篇文章的 Sample Code 在此,建議可以看我分開 commit 的結果比較清楚✌️,也可使用 git checkout 回溯測試看看!

首先我 rails new rails_6_with_jsbundling_rails --skip-javascript 新建一個沒有任何 js 的新項目,當然,也沒裝 webpacker。

然後加入一些 JS 以及 Admin 區塊用來代表項目中已存在的功能。

接著很單純的安裝 jsbundling-rails

bundle add jsbundling-rails
rails javascript:install:esbuild
Enter fullscreen mode Exit fullscreen mode

可以看到我已經有了 package.json,表示我可以透過 yarn add 安裝所有 node packages👍。

重點

  1. 上面安裝 jsbundling-rails 的同時也裝了 foreman,因此請改用 foreman start -f Procfile.dev 開啟 Rails server + yarn build。
  2. 進到 http://localhost:3000/ 會發現舊的 JS 已經全炸了💥,而且layout 裡面載入了兩次 application.js
<head>
...
<%= javascript_include_tag 'application' %>
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
...
</head>
Enter fullscreen mode Exit fullscreen mode

application-thisisalonghash.js 原始碼卻是空白的,這是因為現在的 JS entry point 已經改用 app/javascript/application.js 了。

而我們需要做的就是將舊的 application.js 改名,並且微調 manifest.js 及相關的 javascript_include_tag,就可以讓新舊程式同時運作。

到這邊,我已經可以安裝 hotwire-rails

bundle add hotwire-rails
rails hotwire:install
Enter fullscreen mode Exit fullscreen mode

然後測試一下 Turbo & Stimulus 都跟舊的 JS 一起運作。

以上。


其他

雖然升級很難,但不用 webpacker 好嗎?

jsbundling-rails 也支援 webpack,而且更好
另外,未來 Rails 的主軸將會擺在 importmapjsbundling-railsDHH 也詳述了背後的原因

幹嘛要用 Hotwire?

其實繼續使用 Rails < 6 的開發方式並沒有太大的問題,例如 Stimulus 也有提供不需編譯的安裝方式,安裝之後就可以避免掉許多 SJR 替換 HTML 後需要重新初始化 JS 功能的情境。

雖然我對前端生態並不熟悉,甚至不知道將 JS 模組化的好處,但在目前的開發流程中,我發現比起 Stimulus 搭配 SJR 的組合技,使用 Hotwire 不只減少了請求數,並且維護性更佳。

幹嘛不用 CDN 安裝 hotwire 而要用 hotwire-rails gem?

雖然 Hotwire 的 Custom HTML Element <turbo-frame> 只是 plain HTML,但不使用 gem 的話,Rails controller 無法 respond_to format.turbo_stream,甚至在 *.turbo_stream.erb 的使用也會受限。

為何不用 importmap-rails?

其實我有安裝過 importmap-rails 了,也不難使用,但因為要等 Rails 7 才能使用 ActiveStorage/ActionText/ActionCable ,而我的項目暫時無法升級,所以只好放棄。
等未來 Rails 7 正式釋出時,我會考慮升級並轉換到 importmap-rails。

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay