上禮拜終於開了我們的Discord社群
在錄音的當下總共有145人
吸引了很多不同程度以及經驗的人
有在國外工作的
在努力轉職中
經驗豐富的team lead
在COSCOP演講而且聽眾爆滿的
也有對前端有興趣的工程師
所以不管你是對前端有興趣想多瞭解或是喜歡我的發文的內容都歡迎你加入這裡
不管有任何想分享或是問題想問的都歡迎在社群裡面發問
也不要怕說是不是問問題很蠢
群裡面有各式各樣的人可能都走過你走過的路
可以給你些答案和不一樣的看法給你思考
是一個大家一起成長的過程
我會把Discord連結放在shownotes裡面
這集分享一下我們公司在project中常用的幾個library
每次開新的project時候總是第一個會先想到這些library
但我們一個季裡面會有一些比較technical ticket比如看看哪些library更好或是什麼樣的做事方式會不會解決我們現在的什麼問題所以這些library常常過一段時間就會替換掉
但今天講的是我們用一段時間了然後塞了一個最近特別喜歡的
我雖然前面說是我們公司但其實是我們的組
其他組也有他們喜歡的library但有些我沒接觸過我就不多提了
Zustand是個state management library
state management是個管理application data的過程
component設計中你一定會想到當我拆分這些component時候我的data要存放在哪裡
假設今天只有list 和 list item兩個component
那你可能只要用props的方式把你的state傳下去
假如今天你有很多個component需要同一個state而且他們不是直接的parent child relationship
這時候有個state management library就會方便很多
比如有個global state像是user data在很多components都要用到
有的也在很深的地方
React中有個問題叫做props drilling 其他的框架應該也有類似的概念
當你第一層和第五層component需要同樣的data
我們可以透過第一層傳到第二層然後到第五層
it works 但就很奇怪
這些component莫名其妙的綁在一起了而且中間這幾層根本不需要這個props
這對維護性和refactor體驗變得很糟糕
所以產生了state management這類的idea
除了一開始大家熟悉的Redux後來的Recoil或是Context API
現在有個Zustand
不像其他的library Zustand不需要Provider
想要裡面的state只要import你做好的Zustand store就行了
和Context API不一樣的是
你的component會直接subscribe到那個state就像是你有個useState一樣
那個state更新了只有用到這個state的component才會re-render
寫法方面我自己覺得Zustand更直覺而且官方也有寫一系列的blog posts講解best practices和一些可能常用的案例分享
看名字大概就知道這就是用React hook寫的form library
form有很多個elements input select checkbox
簡單的我們或許手寫就行了
但稍微複雜一點時候就會希望有個library
比如validate這些input的data是不是正確的包括要string不要number
最少應該要有幾個字
顯示error message
如果要在form裡面把既有的data放進去要怎麼把data放回form裡面
submit之後要把data拿出來也是挺頭痛的
這些都不難就是form複雜一點的話就會煩
react hook form把這些都處理好了
還加上一些常用的property和method
比如有個isValid 假設你想要的submit button只有在form都完整填好之後才可以點擊submit你就可以用isValid
submit之後要提取這些data也很容易
不需要特別從event target 裡面去拿
他都已經幫你做好了
而且如果你用TypeScript的話那你拿到的data也都是已經type好了
你如果還需要特別要求資料長度或是確定input只能是數字
可以和其他的schema validation library做整合
TypeScript是在寫code時候和build time告訴你什麼type可能沒對到會報錯
Zod這類的schema validation library是在runtime時候告訴你
可以設定這個state一定要是最少六個字長
或是這個日期一定要是在這個range中間
這個object一定要有name和age但phone number 是非必要的
這搭配前面的react hook form會讓你的form function更完整而且確保你拿到的資料是你想要的shape
如果不是的話 react hook form就會根據你寫的schema來顯示相對應的error message
如果有人沒有勾說他看過terms and conditions
設定說這個form就不能submit且顯示error請使用者一定要勾
其他用途可能有在API server上確認API request的data是不是我們要的
或是確認我們的環境變數每個variable都在
聽說最近冒出一個只要0.7 kb的schema validation library叫Valibot
基本功能都有而且API長得很像TypeScript所以應該很容易上手
但還沒有和其他library做整合
等做整合了比如剛才提的react hook form或許可以試試
bundle size越小對效能來說肯定越好
Apollo Client是我們用來發query和mutation的library
也是Apollo官方發布用來做這件事的library
他跟react query用起來感覺會有點像
加上這個自己也會有一個有一個cache
很多人會直接拿這個作為他們的state management
也不是不行 個人來說那個type policy真的不是說特別好用
範例不多加上沒有特別type的樣子有時候都不知道這樣寫對不對
有時候就是邊寫邊console log確定讀到的cache是對的
有用過GraphQL的人知道GraphQL schema有個format我們要先寫好
比如我今天要一個query我的field和variable要先設定好
通常會寫在gql檔案或是一個string裡面
然後當我們叫apollo client的query method時候再把剛才寫好的query放進去
理論上到這邊就可以動了
但缺點是因為都寫在string裡面 Apollo Client 和 TypeScript都沒法知道這些其實是object
剛才提到的graphql-codegen就能很好的幫助我們type這些request和response和其他datatype
甚至需要的話也會全部用hook打包好
個人覺得非常方便尤其是全部type好
你的application也可以重新使用這些type
缺點個人覺得應該是documentation我覺得沒有特別好讀
沒有特別好的example而且有時候也找不到東西
只能多找一些別人的template來改
我們也不是每次抓資料都是從公司的GraphQL server抓
有時候也會需要從第三方抓比如google或是mapbox這類和地圖有關的資料
我們是用React Query來做這件事
它幫我abstract了很多我們可能會需要的status和data
比如有isLoading, error, data等等
而且這也有自己的cache layer所以如果同一個endpoint和parameters被重複叫了
會根據你設定的cache policy回傳給你cache或是再叫server一次
好玩的是React Query並不是針對API做的
它的useQuery function是可以pass任何Promise的
只是最常見的use case是fetch API
最近官方放出了一個package給nextjs用的
這可以讓我們直接在server上面做useQuery帶suspense
因為Nextjs app router變成default後
慢慢的很多library都在更新自己的package
Apollo之前也做了一樣的事情而我們現在就在用
另一個React Query很像的library叫SWR但這我不熟所以這邊我就不多說了
最後一個是最近才開始用然後開始懷疑以前怎麼做project的
我們組目前感覺上分兩個part
一個是微前端module federation時代 利用webpack module federation來share共用的code也利用這個可以決定使用者可以看到什麼app
但當初感覺執行的不好現在看多很多缺點
所以另一個part是利用nginx做rerouting來區分不同的app
最大的好處是 我覺得是好處啦有些人覺得是壞處
我們可以用自己想要的tech stack寫我們的application
今天這個team想用Next Vue Svelte Qwik 等等都沒有限制
之前我們大家都是用MUI來寫我們的component
對不需要做太多改動的使用者我覺得挺好用的
但如果要常常做更動的話這些component有時候挺confusing的
不過如果你們設計剛好是material ui設計那這應該還是挺不錯的
在我們新的Next app中我們選擇了shadcn ui library
這是基於Radix UI和 tailwind的library
用tailwind來寫styling讓我們回歸於傳統CSS設計
Radix UI因為構造設計讓我們很方便的寫我們自己的design library
他們比較focus在accessibility和可用性
shadcn方面幫助我們寫出很多common components
比如我最驚嘆的大概是它的form
我之前要先把react hook form搞定
然後把Zod schema寫好
然後再把每一個form element比如input select autocomplete這類的寫好
然後這個form才算是完整
shadcn一鍵把這些都搞定了