函式庫的實作千奇百怪,要評估一款函式庫是否合適於微前端的環境運作就要確認許多細節。
確認函式庫是否內部存了「狀態」,一但函式庫有存狀態的需要,那就有無法在微前端運作的隱憂。當兩個微前端被建立,如果版本一樣倒沒有太大的問題。一但版本不同,就不能自己在函式庫內部溝通,甚至內部 API 互相不認識的問題。所以在版本更迭時就會痛又痛,你必須「一次全升」,不能單獨去升版。其實具備狀態不是問題,而是核心邏輯不能基於這個狀態去處理,在迭代過程中發生版本差異是正常的,但核心邏輯不應該隨著版本差異而改變,最終是要靠人為去管理與傳遞狀態。
我們都知道不應該任意去操作全域物件,但使用函式庫卻理所當然。最常見的是 Router 相關的功能,我們都會認為路由函式庫幫我們操作 Browser URL 是一件很正常的事,但我們卻沒有很認真管理這件事,一但有兩個路由函式庫做了對 History 的操作,那就會帶來狀態不同步的問題。相對的其實很多函式庫都有類似的問題,不單單只有 router 存在這問題。但要解決其實只要管理好資料流,不要讓兩個以上的微前端去搶同一個對象操作,這問題就可以被解決。
慢慢你可以發現微前端要注意的問題就都是那些,只要管理好這些問題,逐漸都不會是個問題。不外乎都是溝通和載入的問題,只要能處理好這兩大問題,其實在任何環境,微前端都可以很好的運作。
以 React 為例,生態圈裡有許多函式庫,最著名的 react-query
內部不帶狀態,它可以透過 queryClient 來儲存狀態,這樣就不會有版本不同步的問題。但 swr
卻是內部帶狀態,所以它需要被獨立出來,不能與其他微前端共用,或是依靠 Module Federation 去共享狀態。當然不共享只是犧牲部分效能與資源,不影響核心業務邏輯,可以等待版本更迭一致相同後再共享。
但另一款 i18next-react
卻是內部帶狀態,所以它需要被獨立出來處理多國語系,不能依靠與其他微前端共用來滿足語言切換,或是依靠 Module Federation 去共享狀態。這方面處理就不能抱持著「反正我們微前端共用」的心態,而是要認真思考每個微前端服務的狀態同步。