feat(ivy): first steps towards JIT compilation (#23833)
This commit adds a mechanism by which the @angular/core annotations for @Component, @Injectable, and @NgModule become decorators which, when executed at runtime, trigger just-in-time compilation of their associated types. The activation of these decorators is configured by the ivy_switch mechanism, ensuring that the Ivy JIT engine does not get included in Angular bundles unless specifically requested. PR Close #23833
This commit is contained in:

committed by
Matias Niemelä

parent
1b6b936ef4
commit
919f42fea1
@ -8,9 +8,9 @@
|
||||
|
||||
import {ChangeDetectionStrategy} from '../change_detection/constants';
|
||||
import {Provider} from '../di';
|
||||
import {R3_COMPILE_COMPONENT} from '../ivy_switch';
|
||||
import {Type} from '../type';
|
||||
import {TypeDecorator, makeDecorator, makePropDecorator} from '../util/decorators';
|
||||
|
||||
import {ViewEncapsulation} from './view';
|
||||
|
||||
|
||||
@ -754,7 +754,8 @@ export interface Component extends Directive {
|
||||
*/
|
||||
export const Component: ComponentDecorator = makeDecorator(
|
||||
'Component', (c: Component = {}) => ({changeDetection: ChangeDetectionStrategy.Default, ...c}),
|
||||
Directive);
|
||||
Directive, undefined,
|
||||
(type: Type<any>, meta: Component) => (R3_COMPILE_COMPONENT || (() => {}))(type, meta));
|
||||
|
||||
/**
|
||||
* Type of the Pipe decorator / constructor function.
|
||||
|
@ -9,9 +9,31 @@
|
||||
import {InjectorDef, InjectorType, defineInjector} from '../di/defs';
|
||||
import {convertInjectableProviderToFactory} from '../di/injectable';
|
||||
import {Provider} from '../di/provider';
|
||||
import {R3_COMPILE_NGMODULE} from '../ivy_switch';
|
||||
import {Type} from '../type';
|
||||
import {TypeDecorator, makeDecorator} from '../util/decorators';
|
||||
|
||||
export interface NgModuleDef<T> {
|
||||
type: T;
|
||||
bootstrap: Type<any>[];
|
||||
declarations: Type<any>[];
|
||||
imports: Type<any>[];
|
||||
exports: Type<any>[];
|
||||
|
||||
transitiveCompileScope: {directives: any[]; pipes: any[];}|undefined;
|
||||
}
|
||||
|
||||
export function defineNgModule<T>(def: {type: T} & Partial<NgModuleDef<T>>): never {
|
||||
const res: NgModuleDef<T> = {
|
||||
type: def.type,
|
||||
bootstrap: def.bootstrap || [],
|
||||
declarations: def.declarations || [],
|
||||
imports: def.imports || [],
|
||||
exports: def.exports || [],
|
||||
transitiveCompileScope: undefined,
|
||||
};
|
||||
return res as never;
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around a module that also includes the providers.
|
||||
@ -187,6 +209,19 @@ export interface NgModule {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* NgModule decorator and metadata.
|
||||
*
|
||||
@ -195,15 +230,4 @@ export interface NgModule {
|
||||
*/
|
||||
export const NgModule: NgModuleDecorator = makeDecorator(
|
||||
'NgModule', (ngModule: NgModule) => ngModule, undefined, undefined,
|
||||
(moduleType: InjectorType<any>, metadata: NgModule) => {
|
||||
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,
|
||||
});
|
||||
});
|
||||
(type: Type<any>, meta: NgModule) => (R3_COMPILE_NGMODULE || preR3NgModuleCompile)(type, meta));
|
||||
|
Reference in New Issue
Block a user