The Anatomy of An NgModule and How They Differ From Other JS Modules.

Angular NgModules are classes that have special decorators and meta data. Every Angular application has at least one of these modules. It is known as the root module. Often though, an aplication is composed of an interconnected group of NgModules all tied together by the root module.

First off, the world of JavaScript has a complicated relationship with modules. There are so many types. There are AMD modules, CommonJS modules, and now ES2015 modules. These are all different from NgModules ways of making vanilla modules in the javascript language. Angular works with ES2015 modules by default when using the CLI and adds them to it's own NgModule system to compose your application's environment. Think of NgModule as an Angular abstraction that sits on top of your gluing it all together.

Now that you know a bit of context, let's look at some of the characteristics of NgModules.

  1. By convention they are usually in their own file.
  2. They describe to angular what classes angular knows about.
  3. Multiple NgModules are typically composed together to create an angular application.
  4. They are created by using the @NgModule decorator.

NgModules tell angular which classes it knows about and how to build and launch the application.

This is done in five ways:

  1. declarations: Delcarable classes, these are components, directives, and pipes.
  2. imports: are for importing entire other modules.
  3. exports: declarable items it owns or has imported from other modules.
  4. providers: tell angular's DI system how to inject something into a class. These are typically services.
  5. bootstrap: This tells angular what the root component is that gets put into the index file.

The Root Module

This is where the app is glued together. It's top level services, components, modules, pipes and ect are all imported here and angular is told about what it can manage and control. All of the metadata associated with the @NgModule decorator is what tells Angular how to compile and run the application.

Composing functionality through module imports

Modules provide a way to group related business logic, services and components together. An application that has any size, scope, or complexity at all is usually a grouping of discrete modules into one unified application. For example, an app like Amazon has catalog logic, shipping logic, shopping cart logic that all combine to serve one purpose, an e-commerce experience.

Since your application starts with a root NgModule you can think of that as an ECommerceModule in this example. That may import a ShoppingCartModule, a CatalogModule, and so on.

Modules can export declarable classes. This means any components, pipes, or directives you wish to make public to other parts of your root module can be added to an NgModule's exports property. This makes them public classes. In addition, that's not the only way to extend the root application. Providers added to a bootstrapped module's providers array become public for the entire application. This is because when an NgModule get's imported into the root application, it's providers get added to the root injector. If the concepts of root injectors and Angular's DI system is unfamiliar to you there is a great article at thoughtram about it.

Sharing Angular Modules As A Package

There is yet another type of module to be aware of, the feature module. A feature module is exaclt the same as a regular NgModule. It's just a collection of of components, directives and services that are grouped together to implement a feature. You can see more on this here.