TypeScript - Modulele înnădite sunt rele în Angular?


Este ceva ce mă întreb despre module. Am început Angular 2 acum ceva timp, așa că am căutat prea multe subiecte, dar încă nu am găsit niciun răspuns satisfăcător.

Când creăm o aplicație Angular 2, folosim cu siguranță module. De asemenea, folosim moduluri înrudite, bineînțeles. Câte module înrudite putem folosi? Este acest lucru realizabil sau există o limită pentru modulele înrudite?

De exemplu, să spunem că am o aplicație de dashboard pentru administratori. Putem construi astfel?

app.module.ts
|
 --dashboard
    |
    --dashboard.module.ts
      |
      --login
        |
        --login.module.ts
        .
        .
        .

Putem structura în acest fel cu siguranță. Dar să zicem că avem 5 sau mai multe module imbricate, este în regulă pentru o aplicație Angular? Poate cauza vreo problemă sau poate cauza probleme de performanță? Sau ar trebui să păstrăm lucrurile simple (maxim 3 module imbricate etc.) ca practică?

De asemenea, cum se comportă tsc atunci când modulele și componentele sunt imbricate, atât timp cât crește?

Pentru a rezuma care sunt avantajele, dezavantajele modulelor încorporate etc. și care este cea mai bună practică pentru structurarea modulelor încorporate?

Răspuns #1

A fi cuprins sau a nu fi cuprins nu este o situație alb-negru. Din păcate, ca în majoritatea dezvoltării de software, „depinde.”

Totuși, te-aș îndemna să iei în considerare acest lucru - scopul NgModule (pe lângă motivația tehnică de a permite AOT) este de a oferi o „unitate” de nivel superior pentru aplicația ta. Cu alte cuvinte, poți grupa componente/servicii/pipes individuale în grupuri distincte care îți permit să tratezi acel grup ca o unitate unică care oferă o anumită funcționalitate. În majoritatea cazurilor, acest lucru este folosit pentru a furniza funcționalități în aplicația ta (așa-numitele „module de caracteristici”), dar sistemul NgModule este folosit, de asemenea, pentru a furniza și alte tipuri de preocupări transversale. De fapt, devine ușor pentru autorii de biblioteci să își distribuie biblioteca ca un singur NgModule, încapsulând toată funcționalitatea pe care o oferă. (Exemple includ biblioteci încorporate precum HttpModule și FormsModule, dar și MaterialModule, FlexLayoutModule etc.)

Acest caz de utilizare al gândirii la NgModule ca un container de distribuție mă ajută să mă gândesc cum ar trebui să grupez componentele/serviciile/sobele mele - nu este întotdeauna posibil, dar încerc să gândesc că pot lua un folder care conține definiția modulului și diferitele sale părți și ar trebui să pot să pun acel folder în orice altă aplicație și ar trebui să funcționeze în principiu (presupunând prezența dependențelor sale externe). Gândirea în acest fel mă ajută să mă concentrez asupra nivelului de granularitate pe care ar trebui să-l aibă NgModule-ul. Aceasta nu înseamnă că nu încorporez foldere în interiorul acelui NgModule, dar doar pentru că există un folder încorporat nu înseamnă automat că creez un NgModule - cu excepția cazului în care elementele au sens ca un fel de container de distribuție, nu mă voi deranja să creez NgModule-uri încorporate doar pentru a corespunde structurii folderului.

Pentru a rezuma, structura folderelor tale nu înseamnă automat că trebuie să creezi NgModules pentru folderele profund imbricate - și, astfel, probabil că nu este necesar un setup NgModule profund imbricat.

Răspunsul #2

Pentru mine, scopul principal al utilizării NgModule-urilor este încărcarea leneșă; nu sunt fan al structurării logice/după funcționalitate în Angular. Dacă nu ar exista încărcarea leneșă în Angular, probabil că aș structura codul astfel:

components/
services/
pipes/
models/
...

În ceea ce privește încărcarea leneșă, cuplarea modulelor vs. necuplarea lor nu face nicio diferență. Și probabil decid care cod este încărcat împreună în funcție de care cod se află pe aceeași pagină. De exemplu, chiar dacă 2 componente par să aparțină aceleiași funcționalități, dar se află pe pagini diferite, aș vrea să fie în modulele paginilor respective pentru o încărcare leneșă mai bună.

Deci, în prezent îmi structurez codul în felul următor:

app
|
 --services/
   |
    -- the services module called `CoreModule` in angular docs.
 --shared/
   |
    -- the shared module described in angular docs. Has models as well.
 --pages/
   |
    -- page1/
       |
        -- a module for page1/feature1 that I'll use in lazy-loaded manner (but may not do so if found unsuitable).
    -- page2/
       |
        -- a module for page2/feature2 that ...

Deci, răspunzând la întrebarea ta specific despre încuibare:

  • Încapsularea modulelor este de fapt doar o structură de foldere; nu există niciun efect comparativ cu non-testarea din punct de vedere Angular. Un modul încapsulat este la fel ca un modul de nivel superior. De exemplu, poți importa login.module.ts într-un modul alături de dashboard.
  • Deoarece este o structură de dosare, nu există nicio limită privind nivelurile de imbricare din perspectiva Angular.
  • Totuși, de obicei în modulele imbricate, ai un modul X care importă un modul Y care importă un modul Z, ... etc. În acest punct, nu știu dacă are efect asupra performanței sau nu, dar nu mă aștept să aibă. În special că aceeași situație există în dependențele bibliotecilor: imaginați-vă folosind un component/modul Angular dintr-un pachet npm care folosește un alt component/modul Angular dintr-un alt pachet npm, ... etc.
  • Pentru opinia mea despre modul în care se cuibăresc modulele și structura codului în general, am schițat-o mai sus.

Ca sursă pentru evitarea imbricării, vezi principiul "Menține o structură de foldere plată cât mai mult posibil" din Ghidul Oficial de Stil al Angular. În general, Ghidul de Stil pare un loc bun pentru întrebări similare (tocmai l-am descoperit!).