iT邦幫忙

2023 iThome 鐵人賽

DAY 27
1
Modern Web

轉職三年 web 仔:不僅是代碼,更是人生的重構系列 第 27

人生重構 Day27:再戰新產品—又見 Monorepo

  • 分享至 

  • xImage
  •  

我發現我越努力工作,似乎就越幸運。

—— Thomas Jefferson

當一個人在任何事物上都很努力學習時,即使他當前遇到的不是他最需要的事物,這個事物也會在將來帶來好處,所以越是努力,在將來就會看起來越幸運,因為當需要時,他已經有了相關知識了。


回顧 Day26

Day26 中,我分享了我是如何解析一個問題,到找出原因,並且也展現我是如何實作的思考流程,最終達到了把產品從狀態不是很好,修改到一個更可以持續開發下去的產品。而這篇就要來分享我在這間公司在開發新產品線上遇到的狀況。

從零到一開始開發新產品

背景

隨著疫情逐漸趨緩,我們公司面臨一個現實:指揮中心可能即將解散,意味著我們的主要收入來源將減少。為了持續發展,公司決定開發一個全新的產品,目標是應用於不同的醫院和診所,協助他們進行遠端看診。

對新產品的期望

新產品的目標是具有廣泛的適用性,其中有一個挑戰是希望某些功能,可以針對性的只應開放給不同的醫療機構。這引發了一個問題:如何在不浪費網路資源和增加開發複雜度的情況下,實現這種功能的靈活開放。

常見解決方案的不足

最常見的方式,通常會用設定檔來控制哪些功能是開放的。這種方法有幾個明顯的缺點:

  1. 我們需要將所有功能的程式碼都提供給客戶,即使其中一部分是被遮蔽的,這無疑增加了不必要的網路頻寬使用。
  2. 如果遮蔽機制設計不完善,客戶可能會會很輕易的看到不屬於他們使用的功能。
  3. 開發過程變得更加複雜,因為不同功能之間可能存在相互影響,這增加了開發和維護的困難度。

解決方案

在公司內部討論這個問題後,在更多討論時,我預感到公司可能會採用 Monorepo 結構,然後我就特別推薦了名為 NxJS 的 Monorepo 框架,這是我之前研究過並認為非常優秀的一個解決方案。我在 人生重構 Day19:全新挑戰—初見 Monorepo 架構 的文章中也有提到這個主題。

最終,經過評估,公司決定正式採用 Monorepo 結構,並以 NxJS 作為主要開發框架。只讓人覺得有時候命運就是這麼有趣,因為我在當時是對於 NxJS 這套完整解決方案非常有興趣。

monorepo 的優勢:

模組化:
Monorepo 結構允許我們將各個功能模組化,獨立開發成為各自的工具庫(Library)。這不僅使代碼更具模組化和可重用性,而且也減少了不必要的資源打包。

代碼共享:
Monorepo 的設計便於不同專案共用同一套代碼庫,從而節省了開發時間和資源,並減少了重複工作。這也有助於促進團隊成員間的協作和代碼共享。

版本控制:
所有功能模組和工具庫都存放在同一代碼庫中,這使得版本控制更為便捷。我們能夠更容易地確保各模組之間的相容性,並有效追蹤代碼變更。

測試和部署:
Monorepo 提供了一個統一的測試和部署流程,有助於確保系統的整體穩定性和可靠性。這也大大提高了測試和部署的效率。

這種新的開發模式不僅使我們能更靈活和高效地滿足客戶需求,還解決了許多傳統開發模式中的問題。這一轉變為我們新產品的開發創造了有利條件,並有望帶來更大的成功。

全端經驗的優勢

予以重責

在公司採用了 Monorepo 的架構後,資深工程師主導了整體的前後端大局跟 Monorepo 的結構規劃。對於更微觀的部分,像是 Web 架構,由於我在先前工作中以初級工程師的身份被負起資深工程師級的責任(詳情可參考 Day20),因此主管決定讓我負責規劃 Web 方面的架構。

這樣的安排讓我負責多個 Web 架構的決策,不僅讓我感到自己的專業技能得到了充分的肯定,也為我提供了更多發揮空間。

展現全端經驗

在過去的經驗中,我曾擔任全端工程師,當時的後端使用了 Expressjs 配合 TypeScript,而目前這個項目後端則使用 Nestjs(基於 Expressjs),前端使用 Nextjs。這使我能夠迅速理解後端程式碼。

在深入研究後端 API 的過程中,我發現後端使用了 DTO(Data Transfer Object)的概念,但前端卻自行定義了 API 回傳的格式。

public listData(): Promise<string[]> {
  return axios.get('url', this.token)
}

DTO(Data Transfer Object)是用於在不同模組或層級間進行數據傳輸的物件。其主要目的是確保數據的一致性和完整性。

所以在這邊我們就沒有善用 Monorepo 跟 TypeScript 的型別優勢了,發現這個問題點,我因此提出了改進建議,並嘗試如下的實作:

public listData(): Promise<DataFindManyResponseDto> {
  return axios.get('url', this.token)
}

採用這種方式使得後端的 DTO (Data Transfer Object) 可以與 app 和 web 共用。使用 monorepo 的好處立刻展現出來,我們可以在前後端共用 DTO,可以保證資料的正確性。

這讓我感覺一切的機緣安排的非常的巧妙,過去看似無關緊要的經驗,實則為我後來的工作提供了非常好的幫助。

結語

寫到這裡,我回顧自己過去的學習路程,發現一切努力都未白費。我在 Monorepo 結構中成功應用了 DTO 統一了前後端的資料型別,這一個方法,連公司的其他工程師都未曾注意到。在以前的職位中,DTO 僅被視為後端用於定義型別的工具。儘管我過去未曾在 Monorepo 環境下使用這種方法,但我卻能夠在這裡將兩者連接起來。

這種「靈光乍現」來自於我對於事物深入研究的好習慣。當時,為了更加了解 DTO 是什麼,我不僅瀏覽了維基百科,我也針對一些我想到的疑問去透過 Stack Overflow 和百度等網站去找出解答,使得我能深入了解 DTO 是什麼,以及他的概念,設計原理等等

這些累積的知識使得我在實際工作中的可以有跟其他人不同的見解。這些看似當時「無用」的知識,其實都在為我的未來鋪路。一些人可能會說這是「幸運」,但我認為這完全是過去持續學習和努力的結果。

下一篇文章,我將進一步探討這個新專案中的技術選型和我所解決的各種問題。


文章就說到這,有什麼想法或問題,歡迎隨時找我聊聊!

這篇文章也會同步發在 medium 上,如果有興趣歡迎追蹤我。

medium: https://medium.com/@hugh-program-learning-diary-js
email: u88803494@gmail.com


上一篇
人生重構 Day26:深入前端—決戰產品優化升級
下一篇
人生重構 Day28:再戰新產品—規劃 Web 架構
系列文
轉職三年 web 仔:不僅是代碼,更是人生的重構40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言