file

每次我只要埋頭苦幹做新專案就會有好一陣子沒寫文章,不過還是要稍微督促自己停一下腳步來寫點心得,才不會過程中的收穫過不了多久就又還回去了。這次來分享一下我這次做的新專案,是網頁版的 ReferenceFinder。

內容目錄

專案背景

ReferenceFinder 最初是由摺紙大師 Robert J. Lang 用 C++ 撰寫的開源桌機應用程式,其功能是讓使用者輸入摺紙設計當中的一個參考點(或線)、然後程式會找出一個可以很快摺出該點(或線)的高度近似摺法 1

Lang 在 2007 年釋出 v4.0.1 的最終版之後就結束該程式的開發了,但畢竟該版本的功能已經非常健全,且他當年編譯好的執行檔直到現在也都還是可以在最新的作業系統上正常跑,所以他結束開發這件事並不是什麼問題。

直到進入了智慧型手機的時代之後,開始就有一些聲音希望可以把各種既有的摺紙相關應用程式移植到手機上頭來、以便隨時隨地都可以使用。然而,也不確定究竟是什麼緣故、ReferenceFinder 在很長的一段時間當中並沒有人試圖去移植它過。

一直到 2018 年,我認識的一個老友 Maya Kraft(原名 Robby Kraft)才開發出了網頁版的 ReferenceFinder。他採用的架構其實跟原本的桌機版很不一樣:原版是在啟動的時候快速地運算出一個資料庫來查找所有的參考,而 Kraft 的作法則是事先把資料庫準備好放在雲端上,然後前端程式再打 API 過去請 Node.js 的後端查找資料庫。他這樣做的好處在於不會消耗前端的算力、也不會有初始化時可能需要的等待,但是相對地,因為是事先生成好的資料庫,就不像原版那樣可以自訂資料庫的生成選項(例如無法自訂紙張的長寬比,只能使用預設的 1:1)。除此之外,因為它這樣一來會需要一個能跑後端的環境來佈署,作為免費的程式、他在經營上的選項就有點受限了。原本他是佈署在 Heroku 的免費方案當中,但是隨著 Heroku 在 2022 年底取消該方案之後,他的這個版本也就跟著無法使用了。

好笑的是,我自己因為主要研究的是箱形摺的緣故,甚少有需要查找參考點的需求,所以一直到了今年初、我才發現原來他這個網頁版早就不能用了。這我當然不禁覺得有點可惜,因為 ReferenceFinder 在我看來是一個寫得很出色的工具,應該是要設法繼續延續它的生命才對。於是,我就開始考慮重新讓網頁版復活的各種可能。由於之前我在開發 FEN Tool(改天再分享)的時候已經有過很多整合 WebAssembly 的經驗,我於是就想說可以試著把原本的 C++ 原始碼直接編譯成 WASM 來跑,而且非常幸運地,Lang 的原始碼架構把核心的部份跟桌面 UI 的部份區分得很清楚(這當然也是為了方便他能撰寫多種平台的 UI),於是我很快地就成功將核心的部份抽離出來編譯、並且可以用文字命令的方式在網頁當中執行了。

React

再來欠缺的就只是 UI。原本我想說看看能不能沿用 Kraft 既有的前端,但是剛好那陣子他在改名字而換了信箱、使得我沒有立刻聯絡上他,且他的前端部份並沒有放在 GitHub 上頭(他只放了後端的部份),我因為也不確定到底能不能聯絡得上他,就想說乾脆自己重做一個 UI 算了。反正自己做的話,未來要維護與增加新功能也會比較順手。

本來,通常我自己做應用程式的時候我是偏好用 Vue 的,但是這一回我決定故意改用 React。畢竟,雖然我並不喜歡 React、它卻也毋庸置疑是最大宗的前端框架,過去我對它的理解一直都只停留在紙上談兵、而從來沒有實務經驗,藉著這個乍看規模並不是很大的 app 來練功一下正好 2。就結果來說,跟 Vue 比起來我還是一樣不喜歡 React,但是我並不後悔當初採用 React 的這項決定就是了,起碼我現在更加了解兩者之間的優缺點比較。

整理起來的話,我現在覺得 React 跟 Vue 比起來是這樣的:

  • React 真的很麻煩!
    React 的設計使得它不管要做什麼事情都比 Vue 要麻煩。沒有雙向綁定使得狀態的操作既困難又容易發生各種離奇的錯誤 3,元件要宣告 TypeScript 屬性超煩,全域狀態管理還要另外引用程式庫,HTML 屬性的 classfor 還要改寫成 classNamehtmlFor(這到底是哪個智障設計出來的?),元件的樣式表難以像 SFC 那樣直接以原本的語法寫在同一個檔案當中……這些它通通輸 Vue,而我完全沒看到任何它在設計上贏過 Vue 的東西。
  • JSX 的可讀性實在不行
    眾周知的「if 要改寫成 && 或是三元運算子」、「for 要改寫成 Array.map() 方法」的這些 JSX 語法特性使得寫出來的東西實在是沒有 v-ifv-for 等等來得直覺好閱讀。
  • 表面上看起來叫作「生態系豐富」,實際上是「亂七八糟」
    React 最常被提到的一點就是它的社群遠比 Vue 要大、相關套件眾多,但是其實應該說「太多」才對:同樣的一個課題往往都有一大堆的套件在競爭,這不但浪費我的時間去理解它們的優劣比較才好做決策、社群的開發焦點被太過分散也導致了一堆套件的爛尾棄坑,所以地雖大但卻滿目瘡痍、難以行走。這個問題並不是說 Vue 就沒有,但是相對沒那麼嚴重。
  • 第三方程式庫相對不好串
    React 的一些設計上的麻煩之處、連帶地使得程式庫也要多做很多事情才能跟其它部份搭配好,這使得我每一個程式庫都要花比 Vue 的程式庫更多的時間閱讀文件、才能清楚該如何正確使用。
  • 打包大小比較大
    這個也是大家都知道,Vue 打包之後的大小比 React 要小不少。當然一定會有一些新興框架的擁護者跳出來說「我們更小!」,是是,也許我下一個專案會給那些框架機會吧。
  • 是有個 React Native 沒錯……
    但我又用不到。我是個標準寫 web app 的人,有提供那個東西對我沒啥幫助。

所以,整體來說,我並不覺得我以後別的個人專案還有再次使用 React 的可能性。就像我上面提到的,就算我突然想換口味不用 Vue 了,大概也會用 Svelte 或 Solid 之類的東西看看吧。

我對 React 的初體驗評分如下:

文件清楚:⭐⭐⭐⭐⭐
設置容易:⭐⭐
概念易懂:⭐⭐⭐

這個系列開頭第一篇就先講到這邊,後面可以分享的東西還很多,陸續再寫。


  1. 也就是說,摺出來的參考點線未必剛好與指定的目標吻合、但是與之非常地接近。乍聽之下或許會有些困惑:為什麼是近似摺法而非精確摺法?首先,不見得任何參考點都存在幾何上來說完全精確的摺法(透過摺紙,最多只能解三次方程,所以沒有辦法透過三次方程的組合表達的參考點座標就不可能存在精確的摺法);其次,就算精確摺法存在,步驟也可能非常多,摺疊過程會讓紙張上留下很多的摺痕,這不見得是好事。相對地,近似摺法雖然摺出來的未必是我們真正指定的參考點,但是實務上其誤差是可以被忽略、而不會影響到後續摺紙操作的,而且它可以用相對很少的步驟就摺出,也減少對紙張的負擔。 

  2. 雖然後來其實隨著新功能的開發、它的規模也變大到超出我原本預期的程度,但這也剛好可以順便漸進地練習 React 的專案管理。 

  3. 肯定會有 React 的擁護者覺得我這個說法很奇怪:React 提供的是較為低階的單向資料流,其行為不是應該比較容易預測才對嗎?非也。現實中並不是真的那麼簡單的「低階的 API 一定比高階的要不易出錯」。高階的 API 當然有一個問題在於黑箱做掉很多事情、不容易釐清一些實作細節以及它們的長遠影響如何,但是反過來,低階的東西則是需要使用的人非常清楚整個框架的思維、不然如果沒有照著正確地作法去用,其錯誤反而會比高階的東西用錯了還要更加誇張。 


分享此頁至:
最後修改日期: 2024/05/27

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。您的留言可能會在審核之後才出現在頁面上。