Rialls 5 移植 CoffeeScript 到 Webpack

升級 Rails 5 之後接著處理要把 webpack 取代了原本的 sprocket ,紀錄遇到的問題。

Rialls 5 移植 CoffeeScript 到 Webpack
Photo by JESHOOTS.COM / Unsplash

隨著 Rails 版本的演進,前端已經用 webpack 取代了原本的 sprocket ,公司的專案是從 rails 4 升級到 5 ,當時看起來是流行 CoffeeScript,這個專案從 git blame 上看到最早的程式碼已經是 7 年前,加上系統架構還有分使用者的前台與後台,本篇文章整理了遷移 jQuery 到 webpack 上的問題。

現在看起來系統的問題

  • html.erb 內混著 JavaScript / CoffeeScript 也就是俗稱的義大利麵
  • 同時有 sprocket 跟 webpack 兩隻打包出來的 js 檔
  • sprocket 與 webpack 內 jQuery 版本分別是 2 跟 3
  • 全域 function

預想解法

最初的想法是要消滅 CoffeeScript 並且把邏輯都搬去 webpack。
義大利麵很多老舊的系統一定會存在的狀況,沒什麼好批評的,其實也只要把邏輯拆出來到 webpack 打包就好。如果是獨立的套件也可以搬去 webpack 感覺起來也都滿簡單的。

好,事實上我錯了🤡 整個遷移的過程問題超多。

問題整理

好,只能說當初的人有做好分檔這些事情(大部分啦)一些客製化的邏輯其實在搬移都好測試,只要到載入的頁面測試功能是否正常就好了。剩下的就比較難處理了。

依賴 jQuery 的套件

如果是有支援 es module 的套件,只要在 webpack 內 import 就好了,沒有太大的問題。如果沒有支援沒關係,只要拉到 window 內大部分的套件都可以運作,還可以順便清理沒用的程式碼。

import Swal from 'sweetalert2/dist/sweetalert2'
import 'select2'

多 jQuery 版本問題

前面有提到 sprocket 是 jQuery 2 而 webpack 是 jQuery 3
所以在移植 sprocket 內依賴 jQuery 的套件,會碰到嚴重的問題:因為先後順序,會掛錯 jQuery 導致程式碼執行的時候會噴找不到 function。

所以真正的解決辦法就是先升級 jQuery 3,在把依賴 jQuery 的套件給移植過來,相對這個是最花時間的,也是最困難的地方。

升級 Vue3

因為都使用 webpack 了,所以索性就升級到 Vue3 了,免得到時候要再處理一次升級的問題,系統上是 Vue 1 所以同時要看兩份 migrate 來處理。要處理的像是:

  • lifecycle hook 的變更
  • filter 改用 methods 或是 computed 替代
  • v-for 順序的變更,index 跟 data 順序調換了
  • custom directive 雙向綁定的實作 Vue3 之後要自己寫
  • init 的改變

如果先前沒有使用奇淫技巧,升級起來應該還算是順利,只是要花一點時間就是了。

全域 function

這個其實就相對好解決許多,如果沒有辦法重構,就整個照搬,最簡單的方式就是全部塞進 window 內,因為被 webpack 打包之後每個檔案都是一個閉包,塞進 window 內是一個簡單又粗暴的方法,只是要小心不要撞名了。