block includes
  include ../_util-fns

// TODO
  Images

:marked
  **Angular Modules** help organize an application into cohesive blocks of functionality.

  An Angular Module is a _class_ adorned with the **@NgModule** decorator function.
  `@NgModule` takes a metadata object that tells Angular how to compile and run module code. 
  It identifies the module's _own_ components, directives and pipes, 
  making some of them public so external components can use them. 
  It may add service providers to the application dependency injectors. 
  And there are more options covered here. 

  This page explains how to **create** `NgModule` classes and how to load them, 
  either immediately when the application launches or later, as needed, via the [Router](router.html).  

  ## Table of Contents
  * [Angular modularity](#angular-modularity "Add structure to the app with NgModule")
  * [The application root module](#root-module "The startup module that every app requires")
  * [Bootstrap](#bootstrap "Launch the app in a browser with the root module as the entry point") the root module
  * [Declarations](#declarations "Declare the components, directives, and pipes that belong to a module")
  * [Providers](#providers "Extend the app with additional services")
  * [Imports](#imports "Import components, directives, and pipes for use in component templates")
  * [Resolve conflicts](#resolve-conflicts "When two directives have the same selector ...")
  * [Feature modules](#feature-modules "Partition the app into feature modules")
  * [Lazy loaded modules](#lazy-load "Load modules asynchronously") with the Router
  * [Shared modules](#shared-module "Create modules for commonly used components, directives, and pipes") 
  * [The Core module](#core-module "Create a core module with app-wide singleton services and single-use components") 
  * [Configure core services with _forRoot_](#core-for-root "Configure providers during module import")
  * [Prevent reimport of the _CoreModule_](#prevent-reimport "because bad things happen if a lazy loaded module imports Core")
  * [NgModule metadata properties](#ngmodule-properties "A technical summary of the @NgModule metadata properties")

  ### Live examples
  This page explains Angular Modules through a progression of improvements to a sample with a "Tour of Heroes" theme.
  Here's an index to live examples at key moments in the evolution of that sample:

  * <live-example plnkr="minimal.0">A minimal NgModule app</live-example>
  * <live-example plnkr="contact.1b">The first contact module</live-example>
  * <live-example plnkr="contact.2">The revised contact module</live-example>
  * <live-example plnkr="pre-shared.3">Just before adding _SharedModule_</live-example> 
  * <live-example>The final version</live-example>

  ### Frequently Asked Questions (FAQs)

  This page covers Angular Module concepts in a tutorial fashion.

  The companion [Angular Module FAQs](../cookbook/ngmodule-faq.html "Angular Module FAQs") cookbook
  offers ready answers to specific design and implementation questions.
  Read this page first before hopping over to those FAQs.

.l-hr

a#angular-modularity  
.l-main-section
:marked
  ## Angular Modularity
  
  Modules are a great way to organize the application and extend it with capabilities from external libraries.
  
  Many Angular libraries are modules (e.g, `FormsModule`, `HttpModule`, `RouterModule`). 
  Many third party libraries are available as Angular modules (e.g., 
  <a href="https://material.angular.io/" target="_blank">Material Design</a>,
  <a href="http://ionicframework.com/" target="_blank">Ionic</a>,
  <a href="https://github.com/angular/angularfire2" target="_blank">AngularFire2</a>).

  Angular modules consolidate components, directives and pipes into
  cohesive blocks of functionality, each focused on a 
  feature area, application business domain, workflow, or common collection of utilities.
  
  Modules can also add services to the application.
  Such services might be internally-developed such as the application logger.
  They can come from outside sources such as the Angular router and Http client.

  Modules can be loaded eagerly when the application starts.
  They can also be _lazy loaded_ asynchronously by the router.
  
  An Angular module is a class decorated with `@NgModule` metadata. The metadata:

  * declare which components, directives and pipes  _belong_ to the module.
  * make some of those classes public so that other component templates can use them.
  * import other modules with the components, directives and pipes needed by the components in _this_ module.
  * provide services at the application level that any application component can use.

  Every Angular app has at least one module class, the _root module_. 
  We bootstrap that module to launch the application.

  The _root module_ is all we need in a simple application with a few components.
  As the app grows, we refactor the _root module_ into **feature modules** 
  that represent collections of related functionality. 
  We then import these modules into the _root module_.

  We'll see how later in the page. Let's start with the _root module_.

a#root_module 
.l-main-section
:marked
  ## _AppModule_ - the application root module
  
  Every Angular app has a **root module** class. 
  By convention it's a class called `AppModule` in a file named `app.module.ts`.

  This `AppModule` is about as minimal as it gets:
+makeExample('ngmodule/ts/app/app.module.0.ts', '', 'app/app.module.ts (minimal)')(format=".")
:marked
  The `@NgModule` decorator defines the metadata for the module. 
  We'll take an intuitive approach to understanding the metadata and fill in details as we go.

  This metadata imports a single helper module, `BrowserModule`, the module every browser app must import.
  
  `BrowserModule` registers critical application service providers.
  It also includes common directives like `NgIf` and `NgFor` which become immediately visible and usable
  in any of this modules component templates. 
  
  The `declarations` list identifies the application's only component, 
  the _root component_, the top of this app's rather bare component tree.

  The example `AppComponent` simply displays a data-bound title:
+makeExample('ngmodule/ts/app/app.component.0.ts', '', 'app/app.component.ts (minimal)')(format=".")
:marked
  Lastly, the `@NgModule.bootstrap` property identifies this `AppComponent` as the _bootstrap component_. 
  When Angular launches the app, it places the HTML rendering of `AppComponent` in the DOM,
  inside the `<my-app>` element tags of the `index.html`

a#bootstrap
.l-main-section
:marked
  ## Bootstrapping in _main.ts_
  We launch the application by bootstrapping the `AppModule` in the `main.ts` file.
  
  Angular offers a variety of bootstrapping options, targeting multiple platforms. 
  In this page we consider two options, both targeting the browser.

  ### Dynamic bootstrapping with the Just-In-Time (JIT) compiler
  In the first, _dynamic_ option, the [Angular compiler](../cookbook/ngmodule-faq.html#q-angular-compiler "About the Angular Compiler") 
  compiles the application in the browser and then launches the app.

+makeExample('ngmodule/ts/app/main.ts', '', 'app/main.ts (dynamic)')(format=".")
:marked
  The samples in this page demonstrate the dynamic bootstrapping approach. 

  <live-example embedded plnkr="minimal.0" img="devguide/ngmodule/minimal-plunker.png">Try the live example.</live-example>
  

  ### Static bootstrapping with the Ahead-Of-Time (AOT) compiler

  Consider the static alternative which can produce a much smaller application that
  launches faster, especially on mobile devices and high latency networks.

  In the _static_ option, the Angular compiler runs ahead of time as part of the build process,
  producing a collection of class factories in their own files. 
  Among them is the `AppModuleNgFactory`.

  The syntax for bootstrapping the pre-compiled `AppModuleNgFactory` is similar to 
  the dynamic version that bootstraps the `AppModule` class.

+makeExample('ngmodule/ts/app/main-static.ts', '', 'app/main.ts (static)')(format=".")
:marked
  Because the entire application was pre-compiled, 
  we don't ship the _Angular Compiler_ to the browser and we don't compile in the browser.
  
  The application code downloaded to the browser is much smaller than the dynamic equivalent
  and it is ready to execute immediately. The performance boost can be significant.

  Both the JIT and AOT compilers generate an `AppModuleNgFactory` class from the same `AppModule` source code.
  The JIT compiler creates that factory class on the fly, in memory, in the browser.
  The AOT compiler outputs the factory to a physical file
  that we're importing here in the static version of `main.ts`.

  In general, the `AppModule` should neither know nor care how it is bootstrapped.

  Although the `AppModule` evolves as the app grows, the bootstrap code in `main.ts` doesn't change.
  This is the last time we'll look at `main.ts`.

.l-hr

a#declarations
.l-main-section
:marked
  ## Declare directives and components
  The app evolves. 
  The first addition is a `HighlightDirective`, an [attribute directive](attribute-directives.html)
  that sets the background color of the attached element.
+makeExample('ngmodule/ts/app/highlight.directive.ts', '', 'app/highlight.directive.ts')(format=".")
:marked
  We update the `AppComponent` template to attach the directive to the title:
+makeExample('ngmodule/ts/app/app.component.1.ts', 'template')(format=".")
:marked
  If we ran the app now, Angular would not recognize the `highlight` attribute and would ignore it. 
  We must declare the directive in `AppModule`.

  Import the `HighlightDirective` class and add it to the module's `declarations` like this:
+makeExample('ngmodule/ts/app/app.module.1.ts', 'directive')(format=".")

:marked
  ### Add a component

  We decide to refactor the title into its own `TitleComponent`. 
  The component's template binds to the component's `title` and `subtitle` properties like this:
+makeExample('ngmodule/ts/app/title.component.html', 'v1', 'app/title.component.html')(format=".")

+makeExample('ngmodule/ts/app/title.component.ts', 'v1', 'app/title.component.ts')(format=".")

:marked
  We rewrite the `AppComponent` to display the new `TitleComponent` in the `<app-title>` element,
  using an input binding to set the `subtitle`.
+makeExample('ngmodule/ts/app/app.component.1.ts', '', 'app/app.component.ts (v1)')(format=".")
:marked
  Angular won't recognize the `<app-title>` tag until we declare it in `AppModule`. 
  Import the `TitleComponent` class and add it to the module's `declarations`:
+makeExample('ngmodule/ts/app/app.module.1.ts', 'component')(format=".")

a#providers
.l-main-section
:marked
  ## Service Providers

  Modules are a great way to provide services for all of the module's components.

  The [Dependency Injection](dependency-injection.html) page describes
  the Angular hierarchical dependency injection system and how to configure that system
  with [providers](dependency-injection.html#providers) at different levels of the
  application's component tree.

  A module can add providers to the application's root dependency injector, making those services
  available everywhere in the application.

  Many applications capture information about the currently logged-in user and make that information 
  accessible through a user service. 
  This sample application has a dummy implementation of such a `UserService`.

+makeExample('ngmodule/ts/app/user.service.ts', '', 'app/user.service.ts')(format=".")
:marked
  The sample application should display a welcome message to the logged in user just below the application title.
  Update the `TitleComponent` template to show the welcome message below the application title.
+makeExample('ngmodule/ts/app/title.component.html', '', 'app/title.component.html')(format=".")
:marked
  Update the `TitleComponent` class with a constructor that injects the `UserService`
  and sets the component's `user` property from the service.
+makeExample('ngmodule/ts/app/title.component.ts', '', 'app/title.component.ts')(format=".")
:marked
  We've _defined_ and _used_ the service. Now we _provide_ it for all components to use by
  adding it to a `providers` property in the `AppModule` metadata:
+makeExample('ngmodule/ts/app/app.module.1.ts', 'providers', 'app/app.module.ts (providers)')(format=".")

a#imports
.l-main-section
:marked
  ## Import supporting modules

  The app shouldn't welcome a user if there is no user.
  
  Notice in the revised `TitleComponent` that an `*ngIf` directive guards the message.
  There is no message if there is no user.
+makeExample('ngmodule/ts/app/title.component.html', 'ngIf', 'app/title.component.html (ngIf)')(format=".")
:marked
  Although `AppModule` doesn't declare `NgIf`, the application still compiles and runs.
  How can that be? The Angular compiler should either ignore or complain about unrecognized HTML.
  
  Angular _does_ recognize `NgIf` because we imported it earlier. 
  The initial version of `AppModule` imports `BrowserModule`.
+makeExample('ngmodule/ts/app/app.module.0.ts', 'imports', 'app/app.module.ts (imports)')(format=".")
:marked
  Importing `BrowserModule` made all of its public components, directives and pipes visible 
  to the component templates in `AppModule`. They are ready to use without further ado.
.l-sub-section
  :marked
    More accurately, `NgIf` is declared in `CommonModule` from `@angular/common`.

    `CommonModule` contributes many of the common directives that applications need including `ngIf` and `ngFor`.
    
    `BrowserModule` imports `CommonModule` and [_re-exports_](../cookbook/ngmodule-faq.html#q-re-export) it.
    The net effect is that an importer of `BrowserModule` gets `CommonModule` directives automatically.
:marked
  Many familiar Angular directives do not belong to`CommonModule`. 
  For example,  `NgModel` and `RouterLink` belong to Angular's `FormsModule` and `RouterModule` respectively.
  We must _import_ those modules before we can use their directives.

  To illustrate this point, we extend the sample app with `ContactComponent`, 
  a form component that imports form support from the Angular `FormsModule`.

  ### Add the _ContactComponent_

  [Angular Forms](forms.html) are a great way to manage user data entry.

  The `ContactComponent` presents a "contact editor", 
  implemented with _Angular Forms_ in the [_template-driven form_](forms.html) style.

.l-sub-section
  :marked
    #### Angular Form Styles
    
    We write Angular form components in either the
    [_template-driven form_](forms.html) style or 
    the [_reactive form_](../cookbook/dynamic-form.html) style.

    This sample is about to import the `FormsModule` from `@angular/forms` because
    the `ContactComponent` is written in the _template-driven_ style.
    Modules with components written in the _reactive_ style,
    should import the `ReactiveFormsModule` instead.

:marked
  The `ContactComponent` selector matches an element named `<app-contact>`. 
  Add an element with that name to the `AppComponent` template just below the `<app-title>`:
+makeExample('ngmodule/ts/app/app.component.1b.ts', 'template', 'app/app.component.ts (template)')(format=".")

:marked
  The `ContactComponent` has a lot going on. 
  Form components are often complex anyway and this one has its own `ContactService`, 
  its own [custom pipe](#pipes.html#custom-pipes) called `Awesome`,
  and an alternative version of the `HighlightDirective`.

  To make it manageable, we place all contact-related material in an `app/contact` folder
  and break the component into three constituent HTML, TypeScript, and css files:
+makeTabs(
  `ngmodule/ts/app/contact/contact.component.html,
  ngmodule/ts/app/contact/contact.component.3.ts,
  ngmodule/ts/app/contact/contact.component.css,
  ngmodule/ts/app/contact/contact.service.ts,
  ngmodule/ts/app/contact/awesome.pipe.ts,
  ngmodule/ts/app/contact/highlight.directive.ts
  `, 
  null,
  `app/contact/contact.component.html,
  app/contact/contact.component.ts,
  app/contact/contact.component.css,
  app/contact/contact.service.ts,
  app/contact/awesome.pipe.ts,
  app/contact/highlight.directive.ts
  `)
:marked
  Focus on the component template.
  Notice the two-way data binding `[(ngModel)]` in the middle of the template.
  `ngModel` is the selector for the `NgModel` directive.

  Although `NgModel` is an Angular directive, the _Angular Compiler_ won't recognize it
  because (a) `AppModule` doesn't declare it and (b) it wasn't imported via `BrowserModule`.

  Less obviously, even if Angular somehow recognized `ngModel`,
  this `ContactComponent` would not behave like an Angular form because
  form features such as validation are not yet available.

  ### Import the FormsModule

  Add the `FormsModule` to the `AppModule` metadata's `imports` list.
+makeExample('ngmodule/ts/app/app.module.1.ts', 'imports')(format=".")
:marked
  Now `[(ngModel)]` binding will work and the user input will be validated by Angular Forms, 
  once we declare our new component, pipe and directive.

.alert.is-critical
  :marked
    **Do not** add `NgModel` &mdash; or the `FORMS_DIRECTIVES` &mdash; 
    to the `AppModule` metadata's declarations!

    These directives belong to the `FormsModule`.
    Components, directives and pipes belong to one module &mdash; and _one module only_.

    **Never re-declare classes that belong to another module.**

a#declare-pipe
:marked
  ### Declare the contact component, directive and pipe

  The application fails to compile until we declare the contact component, directive and pipe.
  Update the `declarations` in the  `AppModule` accordingly:
+makeExample('ngmodule/ts/app/app.module.1.ts', 'declarations', 'app/app.module.ts (declarations)')(format=".")

a#import-name-conflict
.l-sub-section
  :marked
    There are two directives with the same name, both called `HighlightDirective`.

    We work around it by creating an alias for the second, contact version using the `as` JavaScript import keyword:
  +makeExample('ngmodule/ts/app/app.module.1b.ts', 'import-alias')(format=".")
  :marked
    This solves the immediate problem of referencing both directive _types_ in the same file but 
    leaves another problem unresoved as we discuss [below](#resolve-conflicts).

:marked
  ### Provide the _ContactService_
  The `ContactComponent` displays contacts retrieved by the `ContactService`
  which Angular injects into its constructor. 
  
  We have to provide that service somewhere.
  The `ContactComponent` _could_ provide it. 
  But then it would be scoped to this component _only_. 
  We want to share this service with other contact-related components that we will surely add later.

  In this app we chose to add `ContactService` to the `AppModule` metadata's `providers` list:
+makeExample('ngmodule/ts/app/app.module.1b.ts', 'providers', 'app/app.module.ts (providers)')(format=".")
:marked
  Now `ContactService` (like `UserService`) can be injected into any component in the application.

a#application-scoped-providers
.l-sub-section
  :marked
    #### Application-scoped Providers
      The `ContactService` provider is _application_-scoped because Angular 
      registers a module's `providers` with the application's **root injector**.

      Architecturally, the `ContactService` belongs to the Contact business domain. 
      Classes in _other_ domains don't need the `ContactService` and shouldn't inject it.
      
      We might expect Angular to offer a _module_-scoping mechanism to enforce this design.
      It doesn't. Angular module instances, unlike components, do not have their own injectors
      so they can't have their own provider scopes.

      This omission is intentional. 
      Angular modules are designed primarily to extend an application, 
      to enrich the entire app with the module's capabilities.
      
      Service scoping is rarely a problem in practice.
      Non-contact components can't inject the `ContactService` by accident.
      To inject `ContactService`, you must first import its _type_.
      Only Contact components should import the `ContactService` _type_.

      See the [FAQ that pursues this issue](../cookbook/ngmodule-faq.html#q-component-scoped-providers) 
      and its mitigations in greater detail.

:marked
  ### Run the app
  Everything is now in place to run the application with its contact editor.

  The app file structure looks like this:
.filetree
  .file app
  .children
    .file app.component.ts
    .file app.module.ts
    .file highlight.directive.ts
    .file main.ts
    .file title.component.(html|ts)
    .file user.service.ts
    .file contact
    .children
      .file awesome.pipe.ts
      .file contact.component.(css|html|ts)
      .file contact.service.ts
      .file highlight.directive.ts

:marked
  Try the example:
  <live-example embedded plnkr="contact.1b" img="devguide/ngmodule/contact-1b-plunker.png"></live-example>
  
a#resolve-conflicts
.l-main-section 
:marked
  ## Resolve directive conflicts

  We ran into trouble [above](#import-name-conflict) when we declared the contact's `HighlightDirective` because
  we already had a `HighlightDirective` class at the application level.

  That both directives have the same name smells of trouble.

  A look at their selectors reveals that they both highlight the attached element with a different color.
+makeTabs(
  `ngmodule/ts/app/highlight.directive.ts,
   ngmodule/ts/app/contact/highlight.directive.ts`,
   '',
  `app/highlight.directive.ts,
   app/contact/highlight.directive.ts`)

:marked
  Will Angular use only one of them? No. 
  Both directives are declared in this module so _both directives are active_.
  
  When the two directives compete to color the same element, 
  the directive declared later wins because its DOM changes overwrite the first.
  In this case, the contact's `HighlightDirective` colors the application title text blue
  when it should stay gold.

.l-sub-section
  :marked
    The real problem is that there are _two different classes_ trying to do the same thing.

    It's OK to import the _same_ directive class multiple times. 
    Angular removes duplicate classes and only registers one of them.

    But these are actually two different classes, defined in different files, that happen to have the same name.

    They're not duplicates from Angular's perspective. Angular keeps both directives and
    they take turns modifying the same HTML element.

:marked
  At least the app still compiles. 
  If we define two different component classes with the same selector specifying the same element tag, 
  the compiler reports an error. It can't insert two components in the same DOM location.

  What a mess! 
  
  We can eliminate component and directive conflicts by creating feature modules
  that insulate the declarations in one module from the declarations in another.

a#feature-modules
.l-main-section
:marked
  ## Feature Modules

  This application isn't big yet. But it's already suffering structural problems.

  * The root `AppModule` grows larger with each new application class and shows no signs of stopping.

  * We have conflicting directives. 
  The `HighlightDirective` in contact is re-coloring the work done by the `HighlightDirective` declared in `AppModule`.
  And it's coloring the application title text when it should only color the `ContactComponent`.

  * The app lacks clear boundaries between contact functionality and other application features.
  That lack of clarity makes it harder to assign development responsibilities to different teams.

  We mitigate these problems with _feature modules_.

  ### _Feature Module_

  A _feature module_ is a class adorned by the `@NgModule` decorator and its metadata,
  just like a root module. 
  Feature module metadata have the same properties as the metadata for a root module.

  The root module and the feature module share the same execution context.
  They share the same dependency injector which means the services in one module
  are available to all.

  There are two significant technical differences:

  1. We _boot_ the root module to _launch_ the app;
  we _import_ a feature module to _extend_ the app.

  2. A feature module can expose or hide its implementation from other modules.

  Otherwise, a feature module is distinguished primarily by its intent.

  A feature module delivers a cohesive set of functionality
  focused on an application business domain, a user workflow, a facility (forms, http, routing), 
  or a collection of related utilities.
  
  While we can do everything within the root module,
  feature modules help us partition the app into areas of specific interest and purpose.

  A feature module collaborates with the root module and with other modules 
  through the services it provides and 
  the components, directives, and pipes that it chooses to share.
 
  In the next section, we carve the contact functionality out of the root module
  and into a dedicated feature module.

  <a id="contact-module-v1"></a>
  ### Make _Contact_ a feature module

  It's easy to refactor the contact material into a contact feature module.

  1. Create the `ContactModule` in the `app/contact` folder.
  1. Move the contact material from `AppModule` to `ContactModule`.
  1. Replace the imported  `BrowserModule` with `CommonModule`.
  1. Import the `ContactModule` into the `AppModule`.

  `AppModule` is the only _existing_ class that changes. But we do add one new file.
  
  ### Add the _ContactModule_
  
  Here's the new `ContactModule`
+makeExample('ngmodule/ts/app/contact/contact.module.2.ts', '', 'app/contact/contact.module.ts')
:marked
  We copy from `AppModule` the contact-related import statements and the `@NgModule` properties
  that concern the contact and paste them in `ContactModule`.
  
  We _import_ the `FormsModule` because the contact component needs it. 
.alert.is-important
  :marked
    Modules do not inherit access to the components, directives or pipes that are declared in other modules.
    What `AppModule` imports is irrelevant to `ContactModule` and vice versa.
    Before `ContactComponent` can bind with `[(ngModel)]`, its `ContactModule` must import `FormsModule`.
:marked
  We also replaced `BrowserModule` by `CommonModule` for reasons explained in
  [an FAQ](../cookbook/ngmodule-faq.html#q-browser-vs-common-module).

  We _declare_ the contact component, directive, and pipe in the module `declarations`.

  We _export_ the `ContactComponent` so
  other modules that import the `ContactModule` can include it in their component templates.

  All other declared contact classes are private by default.
  The `AwesomePipe` and `HighlightDirective` are hidden from the rest of the application. 
  The `HighlightDirective` can no longer color the `AppComponent` title text.

:marked
 ### Refactor the _AppModule_
 Return to the `AppModule` and remove everything specific to the contact feature set.

 Delete the contact import statements.
 Delete the contact declarations and contact providers.
 Remove the `FormsModule` from the `imports` list (`AppComponent` doesn't need it).
 Leave only the classes required at the application root level.

 Then import the `ContactModule` so the app can continue to display the exported `ContactComponent`.

 Here's the refactored version of the `AppModule` side-by-side with the previous version.
+makeTabs(
  `ngmodule/ts/app/app.module.2.ts,
   ngmodule/ts/app/app.module.1b.ts`,
   '', 
  `app/app.module.ts (v2),
   app/app.module.ts (v1)`)
:marked
 ### Improvements
:marked
  There's a lot to like in the revised `AppModule`
  * It does not change as the _Contact_ domain grows.
  * It only changes when we add new modules.
  * It's simpler:
    * Fewer import statements
    * No `FormsModule` import
    * No contact-specific declarations
    * No `ContactService` provider
    * No `HighlightDirective` conflict

  Try this `ContactModule` version of the sample.
  
  <live-example embedded plnkr="contact.2" img="devguide/ngmodule/contact-2-plunker.png">Try the live example.</live-example>

a#lazy-load
.l-main-section
:marked
  ## Lazy loading modules with the Router

  The Heroic Staffing Agency sample app has evolved. 
  It has two more modules, one for managing the heroes-on-staff and another for matching crises to the heroes.
  Both modules are in the early stages of development. 
  Their specifics aren't important to the story and we won't discuss every line of code.
.l-sub-section
  :marked
    Examine and download the complete source for this version from the 
    <live-example plnkr="pre-shared.3" img="devguide/ngmodule/v3-plunker.png">live example.</live-example>
:marked
  Some facets of the current application merit discussion.

  * The app has three feature modules: Contact, Hero, and Crisis.
  * The Angular router helps users navigate among these modules.
  * The `ContactComponent` is the default destination when the app starts.
  * The `ContactModule` continues to be "eagerly" loaded when the application starts.
  * `HeroModule` and the `CrisisModule` are lazy loaded.

  <a id="app-component-template"></a>
  Let's start at the top with the new `AppComponent` template:
  a title, three links, and a `<router-outlet>`.
+makeExample('ngmodule/ts/app/app.component.3.ts', 'template', 'app/app.component.ts (v3 - Template)')(format='.')
:marked
  The `<app-contact>` element is gone; we're routing to the _Contact_ page now.

  The `AppModule` has changed modestly:
+makeExample('ngmodule/ts/app/app.module.3.ts', '', 'app/app.module.ts (v3)')
.l-sub-section
  :marked
    Some file names bear a `.3` extension indicating
    a difference with prior or future versions.
    We'll explain differences that matter in due course.
    
:marked
  The module still imports `ContactModule` so that its routes and components are mounted when the app starts. 

  The module does _not_ import `HeroModule` or `CrisisModule`. 
  They'll be fetched and mounted asynchronously when the user navigates to one of their routes.
  
  The significant change from version 2 is the addition of a ***routing*** object to the `imports`.
  The routing object, which provides a configured `Router` service, is defined in the `app.routing.ts` file.

  ### App routing
+makeExample('ngmodule/ts/app/app.routing.ts', '', 'app/app.routing.ts')(format='.')
:marked
  The router is the subject of [its own page](router.html) so we'll skip lightly over the details and 
  concentrate on the intersection of Angular modules and routing.

  This file defines three routes. 
  
  The first redirects the empty URL (e.g., `http://host.com/`) 
  to another route whose path is `contact` (e.g., `http://host.com/contact`).
  
  The `contact` route isn't defined here.
  It's defined in the _Contact_ feature's _own_ routing file, `contact.routing.ts`.
  It's standard practice for feature modules with routing components to define their own routes.
  We'll get to that file in a moment.

  The remaining two routes use lazy loading syntax to tell the router where to find the modules:
+makeExample('ngmodule/ts/app/app.routing.ts', 'lazy-routes')(format='.')
.l-sub-section
  :marked
    A lazy loaded module location is a _string_, not a _type_. 
    In this app, the string identifies both the module _file_ and the module _class_,
    the latter separated from the former by a `#`.

:marked
  ### RouterModule.forRoot

  The last line calls the `forRoot` static class method of the `RouterModule`, passing in the configuration.
+makeExample('ngmodule/ts/app/app.routing.ts', 'forRoot')(format='.')
:marked
  The returned `routing` object is a `ModuleWithProviders` containing both the `RouterModule` directives
  and the Dependency Injection providers that produce a configured `Router`. 

  This `routing` object is intended for the app _root_ module _only_.

.alert.is-critical
  :marked
    Never call `RouterModule.forRoot` in a feature module.
:marked
  Back in the root `AppModule`, we add this `routing` object to its `imports` list, 
  and the app is ready to navigate.
+makeExample('ngmodule/ts/app/app.module.3.ts', 'imports', 'app/app.module.ts (imports)')(format='.')

:marked
  ### Routing to a feature module
  The `app/contact` folder holds a new file, `contact.routing.ts`.
  It defines the `contact` route we mentioned a bit earlier and also creates a `routing` object like so:
+makeExample('ngmodule/ts/app/contact/contact.routing.ts', 'routing', 'app/contact/contact.routing.ts (routing)')(format='.')
:marked
  This time we pass the route list to the `forChild` method of the `RouterModule`.
  It produces a different kind of object intended for feature modules.

.alert.is-important
  :marked
    Always call `RouterModule.forChild` in a feature module.

.alert.is-helpful
  :marked
    **_forRoot_** and **_forChild_** are conventional names for methods that
    deliver different `import` values to root and feature modules.
    Angular doesn't recognize them but Angular developers do.

    [Follow this convention](../cookbook/ngmodule-faq.html#q-for-root) if you write a similar module
    that has both shared [_declarables_](../cookbook/ngmodule-faq.html#q-declarable) and services.

:marked
  `ContactModule` has changed in two small but important details
+makeTabs(
  `ngmodule/ts/app/contact/contact.module.3.ts,
   ngmodule/ts/app/contact/contact.module.2.ts`,
   'class, class', 
  `app/contact/contact.module.3.ts,
   app/contact/contact.module.2.ts`)
:marked
  1. It imports the `routing` object from `contact.routing.ts`
  1. It no longer exports `ContactComponent`

  Now that we navigate to `ContactComponent` with the router there's no reason to make it public.
  Nor does it need a selector. 
  No template will ever again reference this `ContactComponent`.
  It's gone from the [_AppComponent_ template](#app-component-template).

a#hero-module
:marked
  ### Lazy loaded routing to a module

  The lazy loaded `HeroModule` and `CrisisModule` follow the same principles as any feature module.
  They don't look different from the eagerly loaded `ContactModule`.

  The `HeroModule` is a bit more complex than the `CrisisModule` which makes it 
  a more interesting and useful example. Here's its file structure:

.filetree
  .file hero
  .children
    .file hero-detail.component.ts
    .file hero-list.component.ts
    .file hero.component.ts
    .file hero.module.ts
    .file hero.routing.ts
    .file hero.service.ts
    .file highlight.directive.ts
:marked
  This is the child routing scenario familiar to readers of the [Router](router.html#child-routing-component) page.
  The `HeroComponent` is the feature's top component and routing host. 
  Its template has a `<router-outlet>` that displays either a list of heroes (`HeroList`) 
  or an editor of a selected hero (`HeroDetail`).
  Both components delegate to the `HeroService` to fetch and save data.

  There's yet _another_ `HighlightDirective` that colors elements in yet a different shade.
  We should [do something](#shared-module "Shared modules") about the repetition and inconsistencies.
  We endure for now.

  The `HeroModule` is a feature module like any other.
+makeExample('ngmodule/ts/app/hero/hero.module.3.ts', 'class', 'app/hero/hero.module.ts (class)')(format='.')
:marked
  It imports the `FormsModule` because the `HeroDetailComponent` template binds with `[(ngModel)]`. 
  It imports a `routing` object from `hero.routing.ts` just as `ContactModule` and `CrisisModule` do.

  The `CrisisModule` is much the same. There's nothing more to say that's new. 

  <live-example embedded plnkr="pre-shared.3" img="devguide/ngmodule/v3-plunker.png">Try the live example.</live-example>

a#shared-module
.l-main-section
:marked
  ## Shared modules
  
  The app is shaping up. 
  One thing we don't like is carrying three different versions of the `HighlightDirective`.
  And there's a bunch of other stuff cluttering the app folder level that could be tucked away.

  Let's add a `SharedModule` to hold the common components, directives, and pipes 
  and share them with the modules that need them.

  * create an `app/shared` folder
  * move the `AwesomePipe` and `HighlightDirective` from `app/contact` to `app/shared`.
  * delete the `HighlightDirective` classes from `app/` and `app/hero`
  * create a `SharedModule` class to own the shared material
  * update other feature modules to import `SharedModule`

  Most of this is familiar blocking and tackling. Here is the `SharedModule`
+makeExample('ngmodule/ts/app/shared/shared.module.ts', '', 'app/app/shared/shared.module.ts')
:marked
  Some highlights
  * It imports the `CommonModule` because its component needs common directives.
  * It declares and exports the utility pipe, directive, and component classes as expected.
  * It re-exports the `CommonModule` and `FormsModule`

  #### Re-exporting other modules

  While reviewing our application, we noticed that many components requiring `SharedModule` directives
  also use `NgIf` and `NgFor` from `CommonModule`
  and bind to component properties with `[(ngModel)]`, a directive in the `FormsModule`.
  Modules that declare these components would have to import `CommonModule`, `FormsModule` and `SharedModule`.

  We can reduce the repetition by having `SharedModule` re-export `CommonModule` and `FormsModule`
  so that importers of `SharedModule` get `CommonModule` and `FormsModule` _for free_.

  As it happens, the components declared by `SharedModule` itself don't bind with `[(ngModel)]`. 
  Technically,  there is no need for `SharedModule` to import `FormsModule`.
  
  `SharedModule` can still export `FormsModule` without listing it among its `imports`.

  ### Why _TitleComponent_ isn't shared

  `SharedModule` exists to make commonly used components, directives and pipes available
  for use in the templates of components in _many_ other modules.

  The `TitleComponent` is used _only once_ by the `AppComponent`. 
  There's no point in sharing it.

  <a id="no-shared-module-providers"></a>
  ### Why _UserService_ isn't shared  

  While many components share the same service _instances_,
  they rely on Angular dependency injection to do this kind of sharing, not the module system.
 
  Several components of our sample inject the `UserService`.
  There should be _only one_ instance of the `UserService` in the entire application 
  and _only one_ provider of it.
  
  `UserService` is an application-wide singleton.
  We don't want each module to have its own separate instance. 
  Yet there is [a real danger](../cookbook/ngmodule-faq.html#q-why-it-is-bad) of that happening 
  if the `SharedModule` provides the `UserService`.

.alert.is-critical
  :marked
    Do **not** specify app-wide singleton `providers` in a shared module.
    A lazy loaded module that imports that shared module will make its own copy of the service.

a#core-module
.l-main-section
:marked
  ## The Core module
  At the moment, our root folder is cluttered with the `UserService`
  and the `TitleComponent` that only appears in the root `AppComponent`.
  We did not include them in the `SharedModule` for reasons just explained.
  
  Instead, we'll gather them in a single `CoreModule` that we **import _once_ when the app starts**
  and _never import anywhere else_.

  **Steps:**

  * create an `app/core` folder
  * move the `UserService` and `TitleComponent` from `app/` to `app/core`
  * create a `CoreModule` class to own the core material
  * update the `AppRoot` module to  import `CoreModule`
  
  Again, most of this is familiar blocking and tackling. The interesting part is the `CoreModule`
+makeExample('ngmodule/ts/app/core/core.module.ts', 'v4', 'app/app/core/core.module.ts')
.l-sub-section
  :marked
    We're importing some extra symbols from the Angular core library that we're not using yet.
    They'll become relevant later in this page.
:marked
  The `@NgModule` metadata should be familiar. 
  We declare the `TitleComponent`  because this module _owns_ it and we export it
  because `AppComponent` (which is in `AppModule`) displays the title in its template.
  `TitleComponent` needs the Angular `NgIf` directive that we import from `CommonModule`.

  `CoreModule` _provides_ the `UserService`. Angular registers that provider with the app root injector,
  making a singleton instance of the `UserService` available to any component that needs it, 
  whether that component is eagerly or lazily loaded.

.l-sub-section
  :marked
    #### Why bother?
    This scenario is clearly contrived. 
    The app is too small to worry about a single service file and a tiny, one-time component.

    A `TitleComponent` sitting in the root folder isn't bothering anyone.
    The root `AppModule` can register the `UserService` itself,
    as it does currently, even if we decide to relocate the `UserService` file to the `app/core` folder.

    Real world apps have more to worry about. 
    They can have several single-use components (e.g., spinners, message toasts, and modal dialogs)
    that appear only in the `AppComponent` template. 
    We don't import them elsewhere so they're not _shared_ in that sense. 
    Yet they're too big and messy to leave loose in the root folder.

    Apps often have many singleton services like this sample's `UserService`.
    Each must be registered _exactly once_, in the app root injector, when the application starts.

    While many Components inject such services in their constructors &mdash;
    and therefore require JavaScript `import` statements to import their symbols &mdash;
    no other component or module should define or re-create the services themselves.
    Their _providers_ are not shared.

    We recommend collecting such single-use classes and hiding their gory details inside a `CoreModule`.
    A simplified root `AppModule` imports `CoreModule` in its capacity as orchestrator of the application as a whole.

.l-main-section
:marked
  ## Cleanup
  Having refactored to a `CoreModule` and a `SharedModule`, it's time to cleanup the other modules. 

  ### A trimmer _AppModule_
  
  Here is the updated `AppModule` paired with version 3 for comparison:
+makeTabs(
  `ngmodule/ts/app/app.module.ts,
   ngmodule/ts/app/app.module.3.ts`,
   'v4,',
  `app/app.module.ts (v4),
   app/app.module.ts (v3)`)

:marked
  Notice that `AppModule` is ...
  * a little smaller because many `app/root` classes have moved to other modules.
  * stable because we'll add future components and providers to other modules, not this one.
  * delegating to imported modules rather than doing work.
  * focused on its main task, orchestrating the app as a whole.

  ### A trimmer _ContactModule_
  Here is the new `ContactModule` paired with the prior version:
+makeTabs(
  `ngmodule/ts/app/contact/contact.module.ts,
   ngmodule/ts/app/contact/contact.module.3.ts`,
   '',
  `app/contact/contact.module.ts (v4),
   app/contact/contact.module.ts (v3)`)

:marked
  Notice that
  * The `AwesomePipe` and `HighlightDirective` are gone.
  * The imports include `SharedModule` instead of `CommonModule` and `FormsModule`
  * This new version is leaner and cleaner.

.l-hr

a#core-for-root
.l-main-section
:marked
  ## Configure core services with _CoreModule.forRoot_

  A module that adds providers to the application can offer a facility for configuring those providers as well.
  
  By convention, the **_forRoot_** static method both provides and configures services at the same time.
  It takes a service configuration object and returns a
  [ModuleWithProviders](../api/core/index/ModuleWithProviders-interface.html) which is
  a simple object with two properties:
  * `ngModule` - the `CoreModule` class
  * `providers` - the configured providers

  The root `AppModule` imports the `CoreModule` and adds the `providers` to the `AppModule` providers.
.l-sub-section
  :marked
    More precisely, Angular accumulates all imported providers _before_ appending the items listed in `@NgModule.providers`. 
    This sequence ensures that whatever we add explicitly to the `AppModule` providers takes precedence 
    over the providers of imported modules.
:marked
  Let's add a `CoreModule.forRoot` method that configures the core `UserService`.

  We've extended the core `UserService` with an optional, injected `UserServiceConfig`.
  If a `UserServiceConfig` exists, the `UserService` sets the user name from that config.
+makeExample('ngmodule/ts/app/core/user.service.ts', 'ctor', 'app/core/user.service.ts (constructor)')(format='.')
:marked
  Here's `CoreModule.forRoot` that takes a `UserServiceConfig` object:
+makeExample('ngmodule/ts/app/core/core.module.ts', 'for-root', 'app/core/core.module.ts (forRoot)')(format='.')
:marked
  Lastly, we call it _within the_ `imports` _list_ of the `AppModule`.
+makeExample('ngmodule/ts/app/app.module.ts', 'import-for-root', 'app//app.module.ts (imports)')(format='.')
:marked
  The app displays "Miss Marple" as the user instead of the default "Sherlock Holmes".

.alert.is-important
  :marked
    Call `forRoot` only in the root application module, `AppModule`.
    Calling it in any other module, particularly in a lazy loaded module,
    is contrary to the intent and is likely to produce a runtime error.

    Remember to _import_ the result; don't add it to any other `@NgModule` list.

.l-hr

a#prevent-reimport
.l-main-section
:marked
  ## Prevent reimport of the _CoreModule_

  Only the root `AppModule` should import the `CoreModule`. 
  [Bad things happen](../cookbook/ngmodule-faq.html#q-why-it-is-bad) if a lazy loaded module imports it.

  We could _hope_ that no developer makes that mistake. 
  Or we can guard against it and fail fast by adding the following `CoreModule` constructor.
+makeExample('ngmodule/ts/app/core/core.module.ts', 'ctor')(format='.')
:marked
  The constructor tells Angular to inject the `CoreModule` into itself.
  That seems dangerously circular.

  The injection _would be circular_ if Angular looked for `CoreModule` in the _current_ injector.
  The `@SkipSelf` decorator means "_look for_ `CoreModule` _in an ancestor injector, above me in the injector hierarchy._"
  
  If the constructor executes as intended in the `AppModule`, 
  there is no ancestor injector that could provide an instance of `CoreModule`.
  The injector should give up.

  By default the injector throws an error when it can't find a requested provider.
  The `@Optional` decorator means not finding the service is OK. 
  The injector returns `null`, the `parentModule` parameter is null,
  and the constructor concludes uneventfully.

  It's a different story if we improperly import `CoreModule` into a lazy loaded module such as `HeroModule` (try it).
  
  Angular creates a lazy loaded module with its own injector, a _child_ of the root injector.
  `@SkipSelf` causes Angular to look for a `CoreModule` in the parent injector which this time is the root injector.
  Of course it finds the instance imported by the root `AppModule`. 
  Now `parentModule` exists and the constructor throws the error.
:marked
  ### Conclusion
  
  You made it! You can examine and download the complete source for this final version from the live example.
  <live-example embedded  img="devguide/ngmodule/final-plunker.png"></live-example>

  ### Frequently Asked Questions

  Now that you understand Angular Modules, you may be interested
  in the companion [Angular Module FAQs](../cookbook/ngmodule-faq.html "Angular Module FAQs") cookbook
  with its ready answers to specific design and implementation questions.
