有意義的前端應用程序文件夾結構
對于大規(guī)模應用來說,最關鍵也最具挑戰(zhàn)性的方面之一就是良好且合理的文件夾結構。在考慮將代碼庫分解為使用微前端的多個應用之前,有一些步驟可以遵循,以在項目級別改進架構,并使過渡更加容易,如果你曾經考慮過這條路徑的話。
目標是應用某種模塊化,通過在功能之間設定邊界并最小化代碼耦合和副作用,使代碼庫更易于理解。
默認項目結構
默認情況下,當使用某個流行的前端框架搭建新項目時,組件結構是平坦的,完全不遵循任何層次結構。
圖片
- assets 目錄用于存儲整個應用程序中使用的靜態(tài)資源,如圖片、字體和CSS文件。
- components 目錄包含可重用的Vue組件,建議使用扁平化的層次結構。
- main.js 文件作為應用程序的入口點,使得 Vue 初始化和插件或附加庫的配置成為可能。
- App.vue 文件代表了我們應用程序的根組件,它充當其他組件的容器,并作為主模板提供服務。
我們已經深刻體驗到,對于大型項目來說,這種架構很快就會失控。我們需要某種模塊化,以便能夠輕松定位特定文件,設定功能之間的邊界,并避免組件之間的緊密耦合。
將應用程序分解為多個功能
任何大型應用程序都會被拆分為多個獨立的功能。識別它們并不總是容易和直接的,但隨著時間和經驗的積累,這個過程會變得更好。讓我們一起嘗試將一個流行的應用程序分解為各個部分作為練習。
圖片
推特的主頁內容豐富多彩。頁面的核心部分是時間線,周圍圍繞著許多功能,如導航、推文創(chuàng)建區(qū)域、帶有多個子組件的側邊欄、浮動消息組件等等。
圖片
將構成這些功能的所有組件放在同一個文件夾中是無法維護的,即使使用IDE的快速查找選項,要找到其中的一個也會非常困難。
一個更詳細的項目結構
根據經驗,一個更好且更全面的文件結構應該是這樣的:
圖片
- components : 所有在整個應用程序中使用的共享組件。
- composables : 所有共享的可組合部件。
- config : 應用程序配置文件。
- features : 包含所有的應用程序功能。我們希望將大部分的應用程序代碼保留在這里。
- layouts : 頁面的不同布局。
- lib : 我們應用中使用的各種第三方庫的配置。
- pages : 我們應用程序的頁面。
- services : 共享的應用服務和提供商。
- stores : 全局狀態(tài)存儲。
- test : 與測試相關的模擬、助手、實用程序和配置。
- types : 共享的 TypeScript 類型定義。
- utils : 共享的實用功能。
需要注意的三件重要事項:
- Pages 文件夾本身就已經在一定程度上實現了模塊化,無論是在上下文方面還是在像webpack或Vite這樣的構建工具會創(chuàng)建的實際塊方面。將所有頁面放在一個地方非常有幫助,但是它們內部的邏輯應該盡量簡化。
- 為了更便于維護和擴展,我們的目標是將大部分應用程序代碼保留在 features 文件夾內。每個功能文件夾應包含給定功能的特定領域代碼。
- 在理想的世界里,我們不應該有共享的組件、可組合的、存儲和服務,所有的東西都應該在相應的特性文件夾內。不幸的是,在實際的項目中,這是無法避免的,但我們應該提前規(guī)劃,并在向這些文件夾添加內容時格外小心
Features Folder 功能文件夾
正如我們之前提到的,我們的應用程序的大部分應該存在于特性文件夾中,并分割成多個子目錄。
圖片
- api : 所有的獲取邏輯都在這里,這使得API和UI解耦。
- components : 特定功能的組件。
- composables : 特定功能的可組合項。
- stores : 狀態(tài)管理代碼,我們期待并實際上鼓勵有多個子模塊。
- types : 特定功能的TypeScript類型定義。
- index.ts : 這是功能的入口點。它作為功能的公共API進行操作,只應導出應用程序的其他部分應公開的內容。
上述的 index.ts 文件作為每個功能的公共API。當從另一個領域導入某些內容時,應僅通過此文件進行。這應該可以防止循環(huán)依賴,并且也使得找到導入源更為容易。
# Bad ?? ?? ??
import { UserProfile } from '@/features/profile/components/UserProfile.vue'
# Good ? ? ?
import { UserProfile } from '@/features/profile'
我們可以通過使用 no-restricted-imports ESLint規(guī)則來執(zhí)行這種模式。
rules: {
'no-restricted-imports': [
'error',
{
patterns: ['@/features/*/*'],
},
],
'import/no-cycle': 'error',
...
}
總結
以特性為導向的架構是組織復雜項目的有效且經過實戰(zhàn)檢驗的方式。它使我們能夠將代碼解耦為獨立的模塊,并隨著應用程序變得更復雜而擴展。這將通過提高代碼庫的可預測性,減少調試時間并使新員工入職更容易,從而提升開發(fā)體驗。