# Angular Modules

## Why Angular Modules

* All Angular applications have a root module that gets bootstrapped
* Break application into logical areas
* Organizes and simplifies our applications
* Lazy Load application modules to improve performance
* Hide/Encapsulate functionality and expose only those components and services desired

{% hint style="danger" %}
What about ES6 Modules?  ES6 modules require all classes in the module to be defined in one file, which doesn't support html and css files.
{% endhint %}

## Built-In Modules

Angular has lots of existing modules that we common import into our projects.

* BrowserModule
* CommonModule
* FormsModule
* HttpModule
* RouterModule

{% hint style="info" %}
BrowserModule vs CommonModule

BrowserModule imports and re-exports CommonModule and should only be imported in your root Module (AppModule). CommonModule should be used everywhere else. [more](https://angular.io/guide/ngmodule-faq#should-i-import-browsermodule-or-commonmodule).
{% endhint %}

## Root Module

Every application has a root module and Angular CLI generates a app.module.ts file that is used to bootstrap the application with.  It is responsible for importing the app.component which begins the application layout.

{% code title="app.module.ts" %}

```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { CoreModule } from './core/core.module';

import { AppComponent } from './app.component';
import { UserService } from './user.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [BrowserModule, CoreModule],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule {}
```

{% endcode %}

## Feature Modules

Feature modules allow us to break our application into smaller "chunks" which could be lazy loaded later.  Common feature modules might include an AuthenticationModule, DashboardModule, AdminModule, etc. &#x20;

* Same structure as a root module
* Extend application functionality - cohesive blocks of functionality
* Can contain components, services, pipes, directives, etc.
* Based on feature area, app business domain, workflow, or common collection of utilities
* Can be loaded eagerly or lazy loaded as needed.

## Creating Modules

```
ng g m admin --routing  // to create a module
ng g c admin/users .    // create a users component
ng g p admin/ellipses  // create a pipe
```

Created the following artifacts:

* admin folder
* admin.module.ts
* admin-routing.module.ts
* A users component
* A pipe for ellipses
* Everything was added to the admin.module declarations

{% code title="admin.module.ts" %}

```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AdminRoutingModule } from './admin-routing.module';
import { UsersComponent } from './users/users.component';
import { EllipsesPipe } from './ellipses.pipe';

@NgModule({
  imports: [
    CommonModule,
    AdminRoutingModule
  ],
  declarations: [UsersComponent, EllipsesPipe]
})
export class AdminModule { }
```

{% endcode %}

{% hint style="warning" %}
Modules should be self contained otherwise we will lose out on the benefits later.
{% endhint %}

## NgModule Decorator Properties

* Declares which components, directives, and pipes are in the module
* Can make components, directives, and pipes public for other modules to use
* Imports other modules with components, directives, and pipes to be used by it's components
* Provides services to be used by application components

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-11?file=src%2Fapp%2Fadmin%2Fadmin.module.ts&view=editor>" %}

This module imports the CommonModule and AdminRoutingModule (contains the routes for the admin feature module).  The UsersComponent and EllipsesPipe are declared so they can be used in other components within this module.  It exports UsersComponents to be used in other modules, but the EllipsesPipe would not be available to other modules.

{% hint style="danger" %}
BrowserModule is imported in the root module in most applications,  it should not be imported by any feature modules.
{% endhint %}

## Lazy Loaded Modules

When loading large enterprise applications, the JavaScript payloads can get large and slow down the initial loading performance.  If modules are planned and designed properly, Angular can delay loading feature modules until they are needed.

* Modules that are imported directly or indirectly from the root module will be loaded eagerly
* Modules that aren't referenced directly or indirectly by the root module can be lazy loaded by the router as requested.
* Module definitions are exactly the same

{% hint style="info" %}
Feature Module planning is very important with large applications for performance reasons.  Verify that the build is creating separate javascript bundles for each feature module, otherwise you may have a direct or indirect import that is preventing lazy loading.
{% endhint %}

## Organizing Modules Strategies

* Move page views and related non-shared components into feature modules
* Move root module definitions into a core module to reduce clutter
  * This is a good place for shared service providers
  * The CoreModule could then be imported by the RootModule
* Create a SharedModule for for components, pipes, and directives that are used across multiple modules

{% code title="shared.modiule.ts" %}

```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { HighlightDirective } from './highlight.directive';
import { UnlessDirective } from './unless.directive';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [HighlightDirective, UnlessDirective],
  exports: [HighlightDirective, UnlessDirective]
})
export class SharedModule { }
```

{% endcode %}

{% code title="core.module.ts" %}

```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SharedModule } from '../shared/shared.module';

@NgModule({
  imports: [CommonModule, FormsModule, ReactiveFormsModule, SharedModule],
  declarations: []
})
export class CoreModule {}
```

{% endcode %}

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-11?file=src%2Fapp%2Fapp.module.ts&view=editor>" %}

## Summary

* Why Angular Modules
* Built in Modules
* Root Module
* Purpose of Feature modules
* Defining Modules
* Lazy Loading Modules
* Module Strategies
