The NgModule system is different from, and unrelated to the JavaScript (ES2015) module system for managing collections of JavaScript objects. These are two different and complementary module systems. You can use them both to write your apps.
In JavaScript each file is a module and all objects defined in the file belong to that module. The module declares some objects to be public by marking them with the export key word. Other JavaScript modules use import statements to access public objects from other modules.
import { NgModule } from ‘@angular/core’;
import { AppComponent } from ‘./app.component’;
export class AppModule { }
JavaScript Module System
JavaScript has had modules for a long time. However, they were implemented via libraries, not built into the language. In JavaScript, modules are individual files with JavaScript code in them. JavaScript modules help you namespace, preventing accidental global variables.
Even though JavaScript never had built-in modules, the community has converged on a simple style of modules, which is supported by libraries in ES5 and earlier. This style has also been adopted by ES6:
- Each module is a piece of code that is executed once it is loaded.
- In that code, there may be declarations (variable declarations, function declarations, etc.).
- By default, these declarations stay local to the module.
- You can mark some of them as exports, then other modules can import them.
- A module can import things from other modules. It refers to those modules via module specifiers, strings that are either:
- Relative paths (‘../model/user’): these paths are interpreted relatively to the location of the importing module. The file extension .js can usually be omitted.
- Absolute paths (‘/lib/js/helpers’): point directly to the file of the module to be imported.
- Names (‘util’): What modules names refer to has to be configured.
- Modules are singletons. Even if a module is imported multiple times, only a single “instance” of it exists.
This approach to modules avoids global variables, the only things that are global are module specifiers.
JavaScript Modules vs. NgModules
NgModules are classes decorated with @NgModule. The @NgModule decorator’s imports array tells Angular what other NgModules the current module needs. The modules in the imports array are different than JavaScript modules because they are NgModules rather than regular JavaScript modules. Classes with an @NgModule decorator are by convention kept in their own files, but what makes them an NgModule isn’t being in their own file, like JavaScript modules; it’s the presence of @NgModule and its metadata.
The AppModule generated from the Angular CLI demonstrates both kinds of modules in action:
/* These are JavaScript import statements. Angular doesn’t know anything about these. */
import { BrowserModule } from ‘@angular/platform-browser’;
import { NgModule } from ‘@angular/core’;
import { AppComponent } from ‘./app.component’;
/* The @NgModule decorator lets Angular know that this is an NgModule. */
@NgModule({
declarations: [
AppComponent
],
imports: [ /* These are NgModule imports. */
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
The NgModule classes differ from JavaScript module in the following key ways:
- An NgModule bounds declarable classes only. Declarables are the only classes that matter to the Angular compiler.
- Instead of defining all member classes in one giant file as in a JavaScript module, you list the module’s classes in the @NgModule.declarations list.
- An NgModule can only export the declarable classes it owns or imports from other modules. It doesn’t declare or export any other kind of class.
- Unlike JavaScript modules, an NgModule can extend the entire application with services by adding providers to the @NgModule.providers list.