2016-06-28 09:54:42 -07:00
|
|
|
/**
|
|
|
|
|
* @license
|
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
|
*/
|
|
|
|
|
|
2018-04-13 23:02:29 -07:00
|
|
|
import {InjectorDef, InjectorType, defineInjector} from '../di/defs';
|
2018-02-16 08:45:21 -08:00
|
|
|
import {convertInjectableProviderToFactory} from '../di/injectable';
|
|
|
|
|
import {Provider} from '../di/provider';
|
2018-05-09 08:35:25 -07:00
|
|
|
import {R3_COMPILE_NGMODULE} from '../ivy_switch';
|
2016-08-10 18:21:28 -07:00
|
|
|
import {Type} from '../type';
|
2016-09-12 09:44:20 -07:00
|
|
|
import {TypeDecorator, makeDecorator} from '../util/decorators';
|
2016-06-28 09:54:42 -07:00
|
|
|
|
2018-06-06 11:23:38 -07:00
|
|
|
/**
|
|
|
|
|
* Represents the expansion of an `NgModule` into its scopes.
|
|
|
|
|
*
|
|
|
|
|
* A scope is a set of directives and pipes that are visible in a particular context. Each
|
|
|
|
|
* `NgModule` has two scopes. The `compilation` scope is the set of directives and pipes that will
|
|
|
|
|
* be recognized in the templates of components declared by the module. The `exported` scope is the
|
|
|
|
|
* set of directives and pipes exported by a module (that is, module B's exported scope gets added
|
|
|
|
|
* to module A's compilation scope when module A imports B).
|
|
|
|
|
*/
|
|
|
|
|
export interface NgModuleTransitiveScopes {
|
|
|
|
|
compilation: {directives: Set<any>; pipes: Set<any>;};
|
|
|
|
|
exported: {directives: Set<any>; pipes: Set<any>;};
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-31 15:50:02 -07:00
|
|
|
/**
|
|
|
|
|
* A version of {@link NgModuleDef} that represents the runtime type shape only, and excludes
|
|
|
|
|
* metadata parameters.
|
|
|
|
|
*/
|
|
|
|
|
export type NgModuleDefInternal<T> = NgModuleDef<T, any, any, any>;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Runtime link information for NgModules.
|
|
|
|
|
*
|
|
|
|
|
* This is the internal data structure used by the runtime to assemble components, directives,
|
|
|
|
|
* pipes, and injectors.
|
|
|
|
|
*
|
|
|
|
|
* NOTE: Always use `defineNgModule` function to create this object,
|
|
|
|
|
* never create the object directly since the shape of this object
|
|
|
|
|
* can change between versions.
|
|
|
|
|
*/
|
|
|
|
|
export interface NgModuleDef<T, Declarations, Imports, Exports> {
|
|
|
|
|
/** Token representing the module. Used by DI. */
|
2018-05-09 08:35:25 -07:00
|
|
|
type: T;
|
2018-05-31 15:50:02 -07:00
|
|
|
|
|
|
|
|
/** List of components to bootstrap. */
|
2018-05-09 08:35:25 -07:00
|
|
|
bootstrap: Type<any>[];
|
2018-05-31 15:50:02 -07:00
|
|
|
|
|
|
|
|
/** List of components, directives, and pipes declared by this module. */
|
2018-05-09 08:35:25 -07:00
|
|
|
declarations: Type<any>[];
|
2018-05-31 15:50:02 -07:00
|
|
|
|
|
|
|
|
/** List of modules or `ModuleWithProviders` imported by this module. */
|
2018-05-09 08:35:25 -07:00
|
|
|
imports: Type<any>[];
|
2018-05-31 15:50:02 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* List of modules, `ModuleWithProviders`, components, directives, or pipes exported by this
|
|
|
|
|
* module.
|
|
|
|
|
*/
|
2018-05-09 08:35:25 -07:00
|
|
|
exports: Type<any>[];
|
|
|
|
|
|
2018-06-06 11:23:38 -07:00
|
|
|
/**
|
|
|
|
|
* Cached value of computed `transitiveCompileScopes` for this module.
|
|
|
|
|
*
|
|
|
|
|
* This should never be read directly, but accessed via `transitiveScopesFor`.
|
|
|
|
|
*/
|
|
|
|
|
transitiveCompileScopes: NgModuleTransitiveScopes|null;
|
2018-05-09 08:35:25 -07:00
|
|
|
}
|
|
|
|
|
|
2016-07-25 01:39:50 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* A wrapper around an NgModule that associates it with the providers.
|
2016-07-25 01:39:50 -07:00
|
|
|
*
|
2018-07-09 11:36:30 -07:00
|
|
|
* @param T the module type. In Ivy applications, this must be explicitly
|
|
|
|
|
* provided.
|
2016-07-25 01:39:50 -07:00
|
|
|
*/
|
2018-07-09 11:36:30 -07:00
|
|
|
export interface ModuleWithProviders<T = any> {
|
|
|
|
|
ngModule: Type<T>;
|
2016-08-24 13:39:44 -07:00
|
|
|
providers?: Provider[];
|
2016-07-25 01:39:50 -07:00
|
|
|
}
|
|
|
|
|
|
2016-07-25 03:02:57 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* A schema definition associated with an NgModule.
|
|
|
|
|
*
|
|
|
|
|
* @see `@NgModule`, `CUSTOM_ELEMENTS_SCHEMA`, `NO_ERRORS_SCHEMA`
|
|
|
|
|
*
|
|
|
|
|
* @param name The name of a defined schema.
|
2016-07-25 03:02:57 -07:00
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
|
|
|
|
export interface SchemaMetadata { name: string; }
|
|
|
|
|
|
|
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* Defines a schema that allows an NgModule to contain the following:
|
|
|
|
|
* - Non-Angular elements named with dash case (`-`).
|
|
|
|
|
* - Element properties named with dash case (`-`).
|
|
|
|
|
* Dash case is the naming convention for custom elements.
|
2016-07-25 03:02:57 -07:00
|
|
|
*
|
2018-04-05 22:31:44 +01:00
|
|
|
*
|
2016-07-25 03:02:57 -07:00
|
|
|
*/
|
|
|
|
|
export const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata = {
|
|
|
|
|
name: 'custom-elements'
|
|
|
|
|
};
|
|
|
|
|
|
2016-08-19 16:05:34 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* Defines a schema that allows any property on any element.
|
2016-08-19 16:05:34 -07:00
|
|
|
*
|
|
|
|
|
* @experimental
|
|
|
|
|
*/
|
|
|
|
|
export const NO_ERRORS_SCHEMA: SchemaMetadata = {
|
|
|
|
|
name: 'no-errors-schema'
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-12 09:44:20 -07:00
|
|
|
|
2016-07-29 02:10:30 -07:00
|
|
|
/**
|
2016-09-12 09:44:20 -07:00
|
|
|
* Type of the NgModule decorator / constructor function.
|
|
|
|
|
*
|
2018-04-05 22:31:44 +01:00
|
|
|
*
|
2016-07-29 02:10:30 -07:00
|
|
|
*/
|
2016-09-12 19:14:17 -07:00
|
|
|
export interface NgModuleDecorator {
|
2016-09-12 09:44:20 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* Marks a class as an NgModule and supplies configuration metadata.
|
2016-09-12 09:44:20 -07:00
|
|
|
*/
|
|
|
|
|
(obj?: NgModule): TypeDecorator;
|
|
|
|
|
new (obj?: NgModule): NgModule;
|
2016-07-29 02:10:30 -07:00
|
|
|
}
|
|
|
|
|
|
2016-06-28 09:54:42 -07:00
|
|
|
/**
|
2016-09-12 09:44:20 -07:00
|
|
|
* Type of the NgModule metadata.
|
|
|
|
|
*
|
2018-04-05 22:31:44 +01:00
|
|
|
*
|
2016-06-28 09:54:42 -07:00
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
export interface NgModule {
|
2016-06-28 09:54:42 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* The set of injectable objects that are available in the injector
|
2016-06-28 09:54:42 -07:00
|
|
|
* of this module.
|
2018-07-02 12:06:52 -07:00
|
|
|
*
|
|
|
|
|
* @see [Dependency Injection guide](guide/dependency-injection)
|
|
|
|
|
* @see [NgModule guide](guide/providers)
|
2016-06-28 09:54:42 -07:00
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* @usageNotes
|
2016-06-28 09:54:42 -07:00
|
|
|
*
|
2018-07-02 12:06:52 -07:00
|
|
|
* Dependencies whose providers are listed here become available for injection
|
|
|
|
|
* into any component, directive, pipe or service that is a child of this injector.
|
|
|
|
|
* The NgModule used for bootstrapping uses the root injector, and can provide dependencies
|
|
|
|
|
* to any part of the app.
|
|
|
|
|
*
|
|
|
|
|
* A lazy-loaded module has its own injector, typically a child of the app root injector.
|
|
|
|
|
* Lazy-loaded services are scoped to the lazy-loaded module's injector.
|
|
|
|
|
* If a lazy-loaded module also provides the `UserService`, any component created
|
|
|
|
|
* within that module's context (such as by router navigation) gets the local instance
|
|
|
|
|
* of the service, not the instance in the root injector.
|
|
|
|
|
* Components in external modules continue to receive the instance provided by their injectors.
|
|
|
|
|
*
|
|
|
|
|
* ### Example
|
|
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* The following example defines a class that is injected in
|
|
|
|
|
* the HelloWorld NgModule:
|
2016-06-28 09:54:42 -07:00
|
|
|
*
|
|
|
|
|
* ```
|
|
|
|
|
* class Greeter {
|
|
|
|
|
* greet(name:string) {
|
|
|
|
|
* return 'Hello ' + name + '!';
|
|
|
|
|
* }
|
|
|
|
|
* }
|
|
|
|
|
*
|
2016-07-18 03:50:31 -07:00
|
|
|
* @NgModule({
|
2016-06-28 09:54:42 -07:00
|
|
|
* providers: [
|
|
|
|
|
* Greeter
|
|
|
|
|
* ]
|
|
|
|
|
* })
|
|
|
|
|
* class HelloWorld {
|
|
|
|
|
* greeter:Greeter;
|
|
|
|
|
*
|
|
|
|
|
* constructor(greeter:Greeter) {
|
|
|
|
|
* this.greeter = greeter;
|
|
|
|
|
* }
|
|
|
|
|
* }
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
providers?: Provider[];
|
2016-06-28 09:54:42 -07:00
|
|
|
|
|
|
|
|
/**
|
2018-07-02 12:06:52 -07:00
|
|
|
* The set of components, directives, and pipes ([declarables](guide/glossary#declarable))
|
|
|
|
|
* that belong to this module.
|
2016-06-28 09:54:42 -07:00
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* @usageNotes
|
|
|
|
|
*
|
2018-07-02 12:06:52 -07:00
|
|
|
* The set of selectors that are available to a template include those declared here, and
|
|
|
|
|
* those that are exported from imported NgModules.
|
|
|
|
|
*
|
|
|
|
|
* Declarables must belong to exactly one module.
|
|
|
|
|
* The compiler emits an error if you try to declare the same class in more than one module.
|
|
|
|
|
* Be careful not to declare a class that is imported from another module.
|
|
|
|
|
*
|
|
|
|
|
* ### Example
|
|
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* The following example allows the CommonModule to use the `NgFor`
|
|
|
|
|
* directive.
|
2016-06-28 09:54:42 -07:00
|
|
|
*
|
|
|
|
|
* ```javascript
|
2016-07-18 03:50:31 -07:00
|
|
|
* @NgModule({
|
|
|
|
|
* declarations: [NgFor]
|
2016-06-28 09:54:42 -07:00
|
|
|
* })
|
2016-07-18 03:50:31 -07:00
|
|
|
* class CommonModule {
|
2016-06-28 09:54:42 -07:00
|
|
|
* }
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
declarations?: Array<Type<any>|any[]>;
|
2016-06-28 09:54:42 -07:00
|
|
|
|
|
|
|
|
/**
|
2018-07-02 12:06:52 -07:00
|
|
|
* The set of NgModules whose exported directives and pipes
|
2018-05-14 08:37:43 -07:00
|
|
|
* are available to templates in this module.
|
|
|
|
|
*
|
|
|
|
|
* @usageNotes
|
2016-06-28 09:54:42 -07:00
|
|
|
*
|
2018-07-02 12:06:52 -07:00
|
|
|
* A template can exported declarables from any
|
|
|
|
|
* imported module, including those that are imported indirectly.
|
|
|
|
|
* For example, `CommonModule` imports `BrowserModule`, make the
|
|
|
|
|
* `BrowserModule` exports available wherever `CommonModule` is imported.
|
|
|
|
|
*
|
|
|
|
|
* ### Example
|
|
|
|
|
*
|
|
|
|
|
* The following example allows MainModule to use `CommonModule`:
|
2016-06-28 09:54:42 -07:00
|
|
|
*
|
|
|
|
|
* ```javascript
|
2016-07-18 03:50:31 -07:00
|
|
|
* @NgModule({
|
|
|
|
|
* imports: [CommonModule]
|
2016-06-28 09:54:42 -07:00
|
|
|
* })
|
2016-07-18 03:50:31 -07:00
|
|
|
* class MainModule {
|
2016-06-28 09:54:42 -07:00
|
|
|
* }
|
|
|
|
|
* ```
|
2018-07-02 12:06:52 -07:00
|
|
|
*
|
2016-06-28 09:54:42 -07:00
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
imports?: Array<Type<any>|ModuleWithProviders|any[]>;
|
2016-07-18 03:50:31 -07:00
|
|
|
|
|
|
|
|
/**
|
2018-07-02 12:06:52 -07:00
|
|
|
* The set of components, directives, and pipes declared in this
|
|
|
|
|
* NgModule that can be used in the template of any component that is part of an
|
|
|
|
|
* NgModule that imports this NgModule. Exported declarations are the module's public API.
|
2018-05-14 08:37:43 -07:00
|
|
|
*
|
|
|
|
|
* @usageNotes
|
2016-07-18 03:50:31 -07:00
|
|
|
*
|
2018-07-02 12:06:52 -07:00
|
|
|
* Declarations are private by default. If this module does not export UserComponent,
|
|
|
|
|
* then only the components within this module can use UserComponent.
|
|
|
|
|
*
|
|
|
|
|
* Importing a module does not automatically re-export the imported module's imports.
|
|
|
|
|
* Module 'B' can't use `ngIf` just because it imported module 'A' which imported `CommonModule`.
|
|
|
|
|
* Module 'B' must import `CommonModule` itself.
|
|
|
|
|
*
|
|
|
|
|
* A module can list another module among its exports, in which case all of that module's
|
|
|
|
|
* public declaration are exported. Re-export makes module transitivity explicit.
|
|
|
|
|
* If Module 'A' re-exports `CommonModule` and Module 'B' imports Module 'A',
|
|
|
|
|
* then Module 'B' components can use `ngIf` even though 'B' itself did not import `CommonModule`.
|
|
|
|
|
*
|
|
|
|
|
* ### Example
|
|
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* The following example exports the `NgFor` directive from CommonModule.
|
2016-07-18 03:50:31 -07:00
|
|
|
*
|
|
|
|
|
* ```javascript
|
|
|
|
|
* @NgModule({
|
|
|
|
|
* exports: [NgFor]
|
|
|
|
|
* })
|
|
|
|
|
* class CommonModule {
|
|
|
|
|
* }
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
exports?: Array<Type<any>|any[]>;
|
2016-06-28 09:54:42 -07:00
|
|
|
|
|
|
|
|
/**
|
2018-07-02 12:06:52 -07:00
|
|
|
* The set of components to compile when this NgModule is defined,
|
|
|
|
|
* so that they can be dynamically loaded into the view.
|
|
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* For each component listed here, Angular creates a `ComponentFactory`
|
|
|
|
|
* and stores it in the `ComponentFactoryResolver`.
|
2018-07-02 12:06:52 -07:00
|
|
|
*
|
|
|
|
|
* Angular automatically adds components in the module's bootstrap
|
|
|
|
|
* and route definitions into the `entryComponents` list. Use this
|
|
|
|
|
* option to add components that are bootstrapped
|
|
|
|
|
* using one of the imperative techniques, such as `ViewComponentRef.createComponent()`.
|
|
|
|
|
*
|
|
|
|
|
* @see [Entry Components](guide/entry-components)
|
2016-06-28 09:54:42 -07:00
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
entryComponents?: Array<Type<any>|any[]>;
|
2016-06-28 09:54:42 -07:00
|
|
|
|
2016-08-02 06:54:08 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* The set of components that are bootstrapped when
|
2016-08-02 06:54:08 -07:00
|
|
|
* this module is bootstrapped. The components listed here
|
2018-05-14 08:37:43 -07:00
|
|
|
* are automatically added to `entryComponents`.
|
2016-08-02 06:54:08 -07:00
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
bootstrap?: Array<Type<any>|any[]>;
|
2016-08-02 06:54:08 -07:00
|
|
|
|
2016-08-23 10:52:40 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* The set of schemas that declare elements to be allowed in the NgModule.
|
|
|
|
|
* Elements and properties that are neither Angular components nor directives
|
|
|
|
|
* must be declared in a schema.
|
2016-08-23 10:52:40 -07:00
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* Allowed value are `NO_ERRORS_SCHEMA` and `CUSTOM_ELEMENTS_SCHEMA`.
|
2016-08-23 10:52:40 -07:00
|
|
|
*
|
2018-05-14 08:37:43 -07:00
|
|
|
* @security When using one of `NO_ERRORS_SCHEMA` or `CUSTOM_ELEMENTS_SCHEMA`
|
|
|
|
|
* you must ensure that allowed elements and properties securely escape inputs.
|
2016-08-23 10:52:40 -07:00
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
schemas?: Array<SchemaMetadata|any[]>;
|
2016-07-25 03:02:57 -07:00
|
|
|
|
2016-09-01 13:46:08 -07:00
|
|
|
/**
|
2018-05-14 08:37:43 -07:00
|
|
|
* A name or path that uniquely identifies this NgModule in `getModuleFactory`.
|
|
|
|
|
* If left `undefined`, the NgModule is not registered with
|
2016-09-01 13:46:08 -07:00
|
|
|
* `getModuleFactory`.
|
|
|
|
|
*/
|
2016-09-12 09:44:20 -07:00
|
|
|
id?: string;
|
2018-05-31 15:50:02 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If true, this module will be skipped by the AOT compiler and so will always be compiled
|
|
|
|
|
* using JIT.
|
|
|
|
|
*
|
|
|
|
|
* This exists to support future Ivy work and has no effect currently.
|
|
|
|
|
*/
|
|
|
|
|
jit?: true;
|
2016-06-28 09:54:42 -07:00
|
|
|
}
|
2016-09-12 09:44:20 -07:00
|
|
|
|
2018-05-09 08:35:25 -07:00
|
|
|
function preR3NgModuleCompile(moduleType: InjectorType<any>, metadata: NgModule): void {
|
|
|
|
|
let imports = (metadata && metadata.imports) || [];
|
|
|
|
|
if (metadata && metadata.exports) {
|
|
|
|
|
imports = [...imports, metadata.exports];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
moduleType.ngInjectorDef = defineInjector({
|
|
|
|
|
factory: convertInjectableProviderToFactory(moduleType, {useClass: moduleType}),
|
|
|
|
|
providers: metadata && metadata.providers,
|
|
|
|
|
imports: imports,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-12 09:44:20 -07:00
|
|
|
/**
|
|
|
|
|
* @Annotation
|
|
|
|
|
*/
|
2018-02-16 08:45:21 -08:00
|
|
|
export const NgModule: NgModuleDecorator = makeDecorator(
|
|
|
|
|
'NgModule', (ngModule: NgModule) => ngModule, undefined, undefined,
|
2018-05-14 08:37:43 -07:00
|
|
|
/**
|
|
|
|
|
* Decorator that marks the following class as an NgModule, and supplies
|
|
|
|
|
* configuration metadata for it.
|
2018-07-02 12:06:52 -07:00
|
|
|
*
|
|
|
|
|
* * The `declarations` and `entryComponents` options configure the compiler
|
|
|
|
|
* with information about what belongs to the NgModule.
|
|
|
|
|
* * The `providers` options configures the NgModule's injector to provide
|
|
|
|
|
* dependencies the NgModule members.
|
|
|
|
|
* * The `import` and `export` options bring in members from other modules, and make
|
|
|
|
|
* this module's members available to others.
|
2018-05-14 08:37:43 -07:00
|
|
|
*/
|
2018-05-09 08:35:25 -07:00
|
|
|
(type: Type<any>, meta: NgModule) => (R3_COMPILE_NGMODULE || preR3NgModuleCompile)(type, meta));
|