feat(ivy): ngtsc compiles @Component, @Directive, @NgModule (#24427)
This change supports compilation of components, directives, and modules within ngtsc. Support is not complete, but is enough to compile and test //packages/core/test/bundling/todo in full AOT mode. Code size benefits are not yet achieved as //packages/core itself does not get compiled, and some decorators (e.g. @Input) are not stripped, leading to unwanted code being retained by the tree-shaker. This will be improved in future commits. PR Close #24427
This commit is contained in:

committed by
Miško Hevery

parent
0f7e4fae20
commit
27bc7dcb43
@ -119,6 +119,11 @@ export class Identifiers {
|
||||
moduleName: CORE,
|
||||
};
|
||||
|
||||
static NgModuleDef: o.ExternalReference = {
|
||||
name: 'NgModuleDef',
|
||||
moduleName: CORE,
|
||||
};
|
||||
|
||||
static defineNgModule: o.ExternalReference = {name: 'ɵdefineNgModule', moduleName: CORE};
|
||||
|
||||
static definePipe: o.ExternalReference = {name: 'ɵdefinePipe', moduleName: CORE};
|
||||
|
@ -72,8 +72,11 @@ export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef {
|
||||
exports: o.literalArr(exports),
|
||||
})]);
|
||||
|
||||
// TODO(alxhub): write a proper type reference when AOT compilation of @NgModule is implemented.
|
||||
const type = new o.ExpressionType(o.NULL_EXPR);
|
||||
const type = new o.ExpressionType(o.importExpr(R3.NgModuleDef, [
|
||||
new o.ExpressionType(moduleType), new o.ExpressionType(o.literalArr(declarations)),
|
||||
new o.ExpressionType(o.literalArr(imports)), new o.ExpressionType(o.literalArr(exports))
|
||||
]));
|
||||
|
||||
const additionalStatements: o.Statement[] = [];
|
||||
return {expression, type, additionalStatements};
|
||||
}
|
||||
|
@ -85,8 +85,9 @@ export function compileDirectiveFromMetadata(
|
||||
bindingParser: BindingParser): R3DirectiveDef {
|
||||
const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
|
||||
const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]);
|
||||
const type =
|
||||
new o.ExpressionType(o.importExpr(R3.DirectiveDef, [new o.ExpressionType(meta.type)]));
|
||||
const type = new o.ExpressionType(o.importExpr(
|
||||
R3.DirectiveDef,
|
||||
[new o.ExpressionType(meta.type), new o.ExpressionType(o.literal(meta.selector || ''))]));
|
||||
return {expression, type};
|
||||
}
|
||||
|
||||
@ -154,8 +155,9 @@ export function compileComponentFromMetadata(
|
||||
}
|
||||
|
||||
const expression = o.importExpr(R3.defineComponent).callFn([definitionMap.toLiteralMap()]);
|
||||
const type =
|
||||
new o.ExpressionType(o.importExpr(R3.ComponentDef, [new o.ExpressionType(meta.type)]));
|
||||
const type = new o.ExpressionType(o.importExpr(
|
||||
R3.ComponentDef,
|
||||
[new o.ExpressionType(meta.type), new o.ExpressionType(o.literal(meta.selector || ''))]));
|
||||
|
||||
return {expression, type};
|
||||
}
|
||||
@ -243,15 +245,15 @@ function directiveMetadataFromGlobalMetadata(
|
||||
selector: directive.selector,
|
||||
deps: dependenciesFromGlobalMetadata(directive.type, outputCtx, reflector),
|
||||
queries: queriesFromGlobalMetadata(directive.queries, outputCtx),
|
||||
lifecycle: {
|
||||
usesOnChanges:
|
||||
directive.type.lifecycleHooks.some(lifecycle => lifecycle == LifecycleHooks.OnChanges),
|
||||
},
|
||||
host: {
|
||||
attributes: directive.hostAttributes,
|
||||
listeners: summary.hostListeners,
|
||||
properties: summary.hostProperties,
|
||||
},
|
||||
lifecycle: {
|
||||
usesOnChanges:
|
||||
directive.type.lifecycleHooks.some(lifecycle => lifecycle == LifecycleHooks.OnChanges),
|
||||
},
|
||||
inputs: directive.inputs,
|
||||
outputs: directive.outputs,
|
||||
};
|
||||
|
@ -849,7 +849,7 @@ function interpolate(args: o.Expression[]): o.Expression {
|
||||
* @param templateUrl URL to use for source mapping of the parsed template
|
||||
*/
|
||||
export function parseTemplate(
|
||||
template: string, templateUrl: string, options: {preserveWhitespace?: boolean} = {}):
|
||||
template: string, templateUrl: string, options: {preserveWhitespaces?: boolean} = {}):
|
||||
{errors?: ParseError[], nodes: t.Node[], hasNgContent: boolean, ngContentSelectors: string[]} {
|
||||
const bindingParser = makeBindingParser();
|
||||
const htmlParser = new HtmlParser();
|
||||
@ -860,7 +860,7 @@ export function parseTemplate(
|
||||
}
|
||||
|
||||
let rootNodes: html.Node[] = parseResult.rootNodes;
|
||||
if (!options.preserveWhitespace) {
|
||||
if (!options.preserveWhitespaces) {
|
||||
rootNodes = html.visitAll(new WhitespaceVisitor(), rootNodes);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user