Angular 4 folders-by-feature structure practice
註:未來 AngularJS (1.x) 後的版本統稱 Angular,不過為了方便理解暫且稱為 Angular 4,而且現在 Google "Angular" 的資訊也大多還是在講 AngualrJS
雖然字面上是甘苦談,但就是苦談的意思。之後可能會變成系列文,當作開發過程中的心得整理。
寫 AngularJS (以下簡稱 A1) 習慣之後,現在寫 Angular 4 (以下簡稱 A4) 有種打掉重練的感覺。尤其看著寫過 VueJS 的夥伴 Eric Yip 迅速寫完一堆 A4 的 component 和 service ,更加充滿徬徨。
寫過 Angular 1 的朋友們,一定懂 A1 directive 和 A4 Component 之間的大鴻溝,一開始只能稍微抓到 Component 可實現降低相依性、內部可獨立運作不影響外界邏輯。但真的實作起來,碰到了第一個難題:資料夾怎麼分?
文件告訴我們用 feature 來分。
feature 是甚麼……
shared 資料夾 ??? (腦中只有新垣結衣在吶喊シェア的畫面)
明明當前端工程師兩年,此刻的我感到自己是如此的新鮮:D
於是大腦自行產生了 一切都是幻覺嚇不了我的 精神勝利法,第一版我們參考 AngularClass/angular-starter 切出來長這樣:
註:由於是開發 CRM 系統,customer-list 代表顯示 user 的客戶列表。另外只列出少部分的資料夾當範例解說。
app
--view
----home // home page
----customer-list // customer list page
----no-content // 404 not found page
--component // all the contents in page
----customer-profile // single customer component
----header
----nav
哇 component 和 view 平行了喔好棒棒~~~?
前輩:feature 完全沒分出來啊 = = 要用服務本身的特性來區隔,一個 feature 底下可以有很多 component 和 service,他們一起完成某樣同質性的任務。
我:可是假設現在有三個 feature,
1. profile feature: 專門產生個人資料頁面
2. business-card feature: 專門產生個人名片頁面
3. user feature: 專門處理個人資料相關的服務
而 1,2 的 feature 都要用到 3 提供的資料才能完成任務。這樣感覺 3 的地位和 1,2 不一樣,不該視為平行的 feature 阿?
前輩:那 user feature 就放到 shared 裡面阿!
我:!!!(⊙o⊙)
前輩:然後 feature 底下也可以有自己的 shared 資料夾,給 sub feature 使用,所有的 feature 都要盡可能平行,減少相依性 (減少 parent-child 的關係)。
我:!!!(⊙o⊙)
前輩一點醒,頓時如醍醐灌頂。原來 shared 的意思是,同樣層級的 feature 可共享的內容!第二版打版成果:
app
--core // for one-time loading components/services
----header
----nav
--home
--customer
----customer-list // customer list
----customer-profile // single customer profile
----shared // share with all thing under customer feature
--shared
----no-content
使用 feature 所切出來的版,可以整理為幾項重點:
- 使用 feature 來管理權限和作用的區域:一般預設 feature 要盡可能平行,當某 feature 底下需細分管理,則代表限制了它的作用不會影響到父層。
譬如customer-list
不可 import home component,但home
可以 import customer-list。 app/customer/shared
裡面的內容只能在customer
底下被使用,若在未來home
也需要用到某支app/customer/shared
的內容,則他應該要搬家搬到 更上層的app/shared
裡面。- 目前這一點還未實作,不過我推測未來若
customer-list
畫面需要和customer-profile
同步,customer-list
不可直接 ngRepeatcustomer-profile.component
,而是要在app/customer/shared
裡面添增一筆單筆客戶資料的 component,由customer-list
和customer-profile
各自去 import 來用。因為萬一哪天customer-profile
頁面改了,才不會影響到customer-list
顯示的結果。
雖然才剛開始寫 component,有點懵懂抽象的概念,但實作成功就可以免除了每次維護都要尋找哪些元件有相依性、改一個元件結果頁面都要一起修正的地獄。現在新生之犢不畏虎,希望在 Angular 的世界可以殺出一條血路!