研發與設計專欄
Angular 切版實戰:如何在 Angular 專案裡切模組 Figure out and divide Angular module in project
前往目錄
要如何學習 React 元件特性,將 Angular 元件相依性降到最低、資料達成單一來源,不要讓 JS 資料指來指去,變成折騰人的環節之一

隨著叡揚資訊雲端服務發展,產品持續長大, 光 shared feature 已擁有 40 多支的元件,到處 import、export,才發現 Angular 處境有點尷尬。 雖是模仿 React 的 component 概念,但 React 目前更活躍、元件更好寫,framework 方面 AngularJS 社群較成熟、套件多,反觀 Angular 資源真的不多。

 
要如何學習 React 元件特性,將 Angular 元件相 依性降到最低、資料達成單一來源,不要讓 JS 資料指來指去,變成折騰人的環節之一。
 

Angular 成員

首先介紹 Angular 常用的成員:module、component、directive、service。
● module:需執行某特定任務的功能區塊。
● component:呈現在 html 中的元件。
● directive:可彈性綁在 Component 身上的功能需求。
● service:inject 後可執行的某功能需求。
 
App 以 app.module 為進入點開始運行之後,依照不同的頁面需求,可藉由切換 module 或是 import 不同的 module 來決定此頁面要載入多少資源來完成工作。module 層級最高,可載入其他 module、定義 component、inject service 等等。以我們專案的 HomeModule(Home 畫面所需的模組)最初的版本為例:
 
 

Module 參數

參考 Angular 文件,各 module 設定參數可為:
● imports:此模組需要載入的模組資源(只有 module 能被載入)。
● declarations:此模組使用到的 component、directive。
● providers:此模組使用到的 service(子模組也一樣可使用,providers 作用域比較廣,不像 imports 的資源只有自己本身可使用。用起來感覺很像新增一支 JS 檔案。)
● exports:此模組輸出的資源(意即其他模 組若載入此模組,能使用的所有資源), 輸出的資源必須是 imports、declarations裡面定義過的項目。
 
在 home 的子 module — DashboardModule (dashboard 頁面)試圖加入 TooltipDirective 的時候,得到了 Angular “xxx is part of the declarations of 2 modules" 的回應。Angular 規定 一個 component 只能附屬在一個 module 底下。所以為了讓不同模組可以共用元件, 我們在第二版中創了個 SharedModule,包山包海 import 一堆 module 再 export 一堆 module、component、directive,每次有新頁面要使用共用元件,就只能 import 一大包 SharedModule,造成龐大負擔。於是切分 Module 是必要的。
 

切分 Module

在第三版切出 UISharedModule(放置所有 UI 相關功能的模組):
還有 DataPipeModule、LayoutSharedModule
 
等等其他功能性的模組區塊,並整理出以下特性:
● component / directive / pipe 等元件只能定義在一個 module 底下,因此只要有通用的元件,就要分類到某個 module 麾下, 才能被多個 module 給 import 使用。
● exports 僅含 declaration 裡面的元件,儘量不要 export module,避免 module 相依性、減輕 module 重量。
● Module 分越細,每個新頁面負擔越小, 不會單一 import 就很重,但需要import的 項目數量也會更多,需自行拿捏。
 
其中第二點提到的不要 export module,是因為避免在 import module 的時候,載入了非預期的 module。譬如之前因為 TagModule 與 TagSharedModule 常常被一起使用,如下圖: 原本是方便載入 TagModule 時可以連
 
 
TagSharedModule 一起使用。卻導致原本只想使用 TagComponent 的 module 被迫載入 TagSharedModule。所以即使兩者常常被一起使用,TagModule 也還是不要 exports TagSharedModule 才好,需要兩者的時候再分別 imports:
 
 
不得不說 Angaulr 這種分層架構,對一切講求扁平的 component 世代很不利,但對團隊開發與理解是有幫助的。