|
| 1 | +--- |
| 2 | +title: use modules to define features |
| 3 | +author: |
| 4 | + name: Billy Lando |
| 5 | + url: https://github.com/billyjov |
| 6 | +--- |
| 7 | + |
| 8 | +# Problem |
| 9 | + |
| 10 | +As an app scales, the root module starts growing and declaring a vast number of components increases the start time as well as affects the application's performance. Additionally, the more components we add to the root module, the harder it gets to understand the application's structure, and therefore making it hard to maintain. |
| 11 | + |
| 12 | +# Solution |
| 13 | + |
| 14 | +Using an `NgModule` to define features in Angular allows lazy loading, isolation and portability of this features. The purpose of feature modules is to organize relevant code into cohesive blocks. This helps to apply clear boundaries between features or application domains. |
| 15 | + |
| 16 | +Another benefit of `NgModules` is that they allow us to lazy load each feature module in order to boost the performance of our app, especially time to **first meaningful paint** (FMP). Furthermore, feature encapsulation using modules allow us to replace each module without (or with small changes) affecting other modules. |
| 17 | + |
| 18 | +Here's an example: |
| 19 | + |
| 20 | +```ts |
| 21 | + |
| 22 | +@Component({ ... }) |
| 23 | +export class AddPeopleComponent implements OnInit { |
| 24 | + ... |
| 25 | +} |
| 26 | + |
| 27 | +@Component({...}) |
| 28 | +export class ListPeopleComponent implements OnInit { |
| 29 | + ... |
| 30 | +} |
| 31 | + |
| 32 | +@NgModule({ |
| 33 | + ... |
| 34 | + imports: [] |
| 35 | + declarations: [ |
| 36 | + AddPeopleComponent, |
| 37 | + ListPeopleComponent |
| 38 | + // other components |
| 39 | + ], |
| 40 | + ... |
| 41 | +}) |
| 42 | +export class AppModule {} |
| 43 | +``` |
| 44 | + |
| 45 | +The above can be refactored to: |
| 46 | + |
| 47 | + |
| 48 | +```ts |
| 49 | + |
| 50 | +@Component({ ... }) |
| 51 | +export class AddPeopleComponent implements OnInit { |
| 52 | + ... |
| 53 | +} |
| 54 | + |
| 55 | +@Component({ ... }) |
| 56 | +export class ListPeopleComponent implements OnInit { |
| 57 | + ... |
| 58 | +} |
| 59 | + |
| 60 | +// introduce a new feature module |
| 61 | +@NgModule({ |
| 62 | + imports: [ |
| 63 | + CommonModule |
| 64 | + ] |
| 65 | + declarations: [ |
| 66 | + AddPeopleComponent, |
| 67 | + ListPeopleComponent |
| 68 | + ] |
| 69 | +}) |
| 70 | +export class PeopleModule {} |
| 71 | + |
| 72 | + |
| 73 | +@NgModule({ |
| 74 | + ... |
| 75 | + imports: [ |
| 76 | + // import our new feature module |
| 77 | + PeopleModule |
| 78 | + ] |
| 79 | + declarations: [ |
| 80 | + // other components |
| 81 | + ], |
| 82 | + ... |
| 83 | +}) |
| 84 | +export class AppModule {} |
| 85 | +``` |
| 86 | + |
| 87 | +Alternatively, we can use lazy loading as described [here](/default/checklist/router/Z165VzV). |
| 88 | + |
| 89 | +## What if something needs to be reused elsewhere? |
| 90 | + |
| 91 | +In this case, using a `SharedModule` helps to organize reusable parts into its own module. We can put commonly used directives, pipes, and components into one module and then import the `SharedModule` wherever we need it in other parts of our application. |
| 92 | +But we aware of possibly multiple service instances. For more information check [this item](/default/checklist/architecture/Z1ohpIo). |
| 93 | + |
| 94 | +# Resources |
| 95 | + |
| 96 | +- [Avoiding common confusions with modules in Angular](https://blog.angularindepth.com/avoiding-common-confusions-with-modules-in-angular-ada070e6891f) by Max Koretskyi |
| 97 | +- [Module vs Module](https://www.youtube.com/watch?v=ntJ-P-Cvo7o) by Deborah Kurata |
| 98 | +- [Angular documentation for Feature Modules](https://angular.io/guide/feature-modules) |
0 commit comments