跳至內容

原則

本頁說明構成 Tuist 設計與開發核心的原則。這些原則會隨著專案演進,旨在確保成長可持續,並與專案基礎保持一致。

預設採用約定#

Tuist 存在的原因之一,在於 Xcode 在約定方面較弱,導致專案變得複雜、難以擴展與維護。因此,Tuist 採取不同的做法:預設採用簡單且經過精心設計的約定。開發者可以選擇不遵循這些約定,但這是一項需要刻意做出的決定,且感覺並不自然。

例如,有一項約定是透過提供的公開介面來定義目標之間的相依性。如此一來,Tuist 能確保產生的專案具備正確的設定,使連結順利運作。開發者也可以選擇透過建置設定來定義相依性,但這樣做屬於隱式行為,因而會破壞依賴這些約定的 Tuist 功能,例如 tuist graph 或 tuist cache。

我們之所以預設採用約定,是因為我們能替開發者做出的決策越多,他們就能越專注於為應用程式打造功能。當像許多專案那樣缺乏約定時,我們就必須做出與其他決策不一致的決定,進而產生難以管理的意外複雜性。

Manifest 檔案為單一事實來源#

若存在多層設定以及彼此間的契約,會導致專案設定難以理解與維護。試想一個典型的專案:專案定義位於 .xcodeproj 目錄中,CLI 邏輯位於腳本(例如 Fastfiles)中,而 CI 邏輯則位於管線中。這是三個需要維護且彼此存在契約的層次。你是否曾遇過修改專案內容後,過了一週才發現發布腳本出錯的情況?

我們可以透過單一事實來源(即 manifest 檔案)來簡化這一點。這些檔案提供 Tuist 生成 Xcode 專案所需的資訊,讓開發者能用來編輯檔案。此外,它也支援從本機或 CI 環境執行標準的專案建置指令。

Tuist 應承擔複雜性,並提供簡單、安全且令人愉悅的介面,盡可能以明確的方式描述專案。

將隱式行為轉為明確#

Xcode 支援隱式設定。一個很好的例子是推斷隱式定義的相依性。雖然在設定簡單的小型專案中,隱式行為尚可接受,但隨著專案規模擴大,可能會導致速度變慢或出現異常行為。

Tuist 應為隱式的 Xcode 行為提供明確的 API。它也應支援定義 Xcode 的隱式行為,但以鼓勵開發者採用明確做法的方式實作。支援 Xcode 的隱式行為與細節有助於團隊採用 Tuist,之後團隊可以再花時間逐步消除隱式行為。

相依性的定義就是一個很好的例子。雖然開發者可以透過建置設定與階段來定義相依性,但 Tuist 提供了優雅的 API,鼓勵大家採用。

將 API 設計為明確,讓 Tuist 能夠對專案執行一些原本無法進行的檢查與最佳化。 此外,它也啟用了诸如 tuist graph(匯出相依圖的表示)或 tuist cache(將所有目標快取為二進位檔)等功能。

Tip

我們應將每一次從 Xcode 移植功能的需求,視為以簡單且明確的 API 簡化概念的機會。

保持簡單#

擴展 Xcode 專案時的主要挑戰之一,來自於Xcode 向使用者暴露了大量複雜性。 因此,團隊的關鍵人員風險較高,只有少數人了解專案以及建置系統拋出的錯誤。這對團隊來說是不利的狀況,因為團隊過度依賴少數人。

Xcode 是個強大的工具,但多年的改進、新平台與程式語言都反映在其表面上,使其難以保持簡單。

Tuist 應把握機會保持簡單,因為處理簡單的事物既有趣又能激勵我們。沒有人希望花時間去除錯編譯過程最後階段發生的錯誤,或搞懂為何無法在裝置上執行應用程式。Xcode 將任務委派給底層的建置系統,而在某些情況下,它在將錯誤轉換為可執行的建議方面表現不佳。你是否曾遇到 「找不到 framework X」 的錯誤卻不知如何處理?想像一下,如果我們能提供一份潛在根本原因的清單,情況會有多大的改善。

從開發者體驗出發#

Xcode 周邊缺乏創新(或者換句話說,不像其他程式設計環境那樣充滿創新)的部分原因,在於我們經常從現有解決方案出發來分析問題。 結果是,如今大多數解決方案都圍繞著相同的想法與工作流程。雖然將現有解決方案納入考量是好事,但不應讓它們限制我們的創造力。

我們喜歡像Tom Preston在這集 Podcast中所說的那樣思考:「只要在大宇宙的約束範圍內可行,大多數事情都能實現;你腦中的想法,通常都能透過程式碼達成。」 如果我們想像理想的開發者體驗應該是什麼樣子,實現它只是時間問題——從開發者體驗出發分析問題,能賦予我們獨特的視角,引導我們打造出使用者喜愛的解決方案。

我們可能會忍不住跟隨大眾的做法,即使這意味著要忍受大家持續抱怨的不便。讓我們別這麼做。我期望如何封存我的應用程式?我希望程式碼簽署的流程是什麼樣子?我能用 Tuist 協助簡化哪些流程?例如,加入對Fastlane的支援是某個問題的解決方案,但我們需要先理解該問題。透過不斷追問「為什麼」,我們可以找出問題的根本原因。一旦釐清動機來源,我們就能思考 Tuist 如何提供最佳協助。也許解決方案是與 Fastlane 整合,但在做出取捨之前,重要的是不要忽視其他同樣可行的方案。

錯誤確實會發生#

我們開發者天生容易忽視錯誤發生的可能性。結果,我們在設計和測試軟體時,往往只考慮理想情境。

Swift、其型別系統以及架構良好的程式碼有助於防止某些錯誤,但無法防止所有錯誤,因為有些因素超出我們的控制範圍。我們不能假設使用者永遠擁有網路連線,或系統指令一定會成功執行。Tuist 執行的環境並非我們能完全控制的沙箱,因此我們需要努力了解這些環境可能如何變化並影響 Tuist。

處理不當的錯誤會導致糟糕的使用者體驗,使用者可能會因此對專案失去信任。我們希望使用者享受 Tuist 的每一個環節,包括我們呈現錯誤的方式。

我們應該換位思考,想像自己期望錯誤訊息告訴我們什麼。如果程式語言是錯誤傳遞的溝通管道,而使用者是錯誤的接收端,那麼錯誤訊息就應該以目標對象(使用者)熟悉的語言撰寫。它們應包含足夠的資訊讓使用者了解發生了什麼事,並隱藏不相關的資訊。此外,錯誤訊息應具備可操作性,告知使用者可以採取哪些步驟來恢復正常。

最後同樣重要的是,我們的測試案例應涵蓋失敗情境。這不僅能確保我們按照預期處理錯誤,也能防止未來的開發者破壞這項邏輯。