# Angular modules

NOTE: see [this article](https://blog.upstate.agency/3-types-of-route-loading-in-angular-explained-in-500ish-words-f22976e1f60b) for a brief explanation of modules load strategy. See also [this article](https://www.concretepage.com/angular-2/angular-module-loading-eager-lazy-and-preloading), recommended reading with examples!

In an Angular app, its very common to create some feature modules (apart from `Core`and `Shared`) to group together logically related app features. Modules can have one of 3 loading strategies:

* eager-loaded
* preladed
* lazy-loaded

## Eager-loaded modules (default loading strategy)

Eager-loaded modules are loaded on app startup. It is advisable to eager-load a module only if the app won't be able to start without it, since it will add some time to the startup phase. To eager-load a module:

* Add it to the `imports` metadata of the main module `@NgModule`decorator.
* You don't have to use any particular attention for routing configuration.

## Lazy-loaded modules

Lazy-loaded modules are loaded when a specific route is hit. These kind of modules are very common, since they are loaded only when they are needed. To lazy load a module:

* **Do not** add module to `imports` metadata of the main module `@NgModule`decorator.
* Use the `loadChildren`property in route configuration to specify the module to lazy-load. The format to use is: &#x20;

  `'{{modulePath}}#{{moduleClassName}}'`

## Preloaded modules

Preloaded modules are modules loaded after the main module in the background, for a possible faster access than lazy-loaded ones. A module can be lazy-loaded or preloaded, not both. Angular offers only a `PreloadAllModules` strategy, which actually preloads all modules specified in `loadChildren`of route configs, but also custom preload strategies can be used. To preload a module:

* **Do not** add module to `imports` metadata of the main module `@NgModule`decorator.
* Use the `loadChildren`property in route configuration to specify the module to preload. The format to use is:\
  `'{{modulePath}}#{{moduleClassName}}'`(same as lazy-load).
* Add a preload strategy to`preloadingStrategy`property in`RouterModule.forRoot`(e.g. `PreloadAllModules` by Angular core, or a custom one by implementing Angular`PreloadingStrategy`).

## Lazy/Pre loaded feature modules structure

A quick note on lazy and preloaded feature modules. Do not try to inject components from lazy-loaded modules into router outlets defined in upper modules (e.g. eager-loaded ones), this is very tricky and can lead to unexpected behaviour. For example, if you have some feature modules which require different layouts, the best thing to do is:

* Put all non-changing layout elements inside the main app component, and define a single router outlet (unnamed) where the feature modules will inject their components.
* In each feature module, create an entry component (we could call it **appshell**) which define the layout for that feature module, along with all router outlets needed for that module. The appshell will be injected in the main, unnamed router outlet of the main app component.
* The router outlets of each feature module can then be handled by the module itself, without any problems.
