refactor(core): rename ngComponentDef to ɵcmp (#33088)

Component defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.

This commit adds the prefix and shortens the name from
`ngComponentDef` to `cmp`. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.

Note that the other "defs" (ngDirectiveDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.

PR Close #33088
This commit is contained in:
Kara Erickson
2019-10-10 14:57:15 -07:00
committed by Miško Hevery
parent d4d07233dc
commit 64fd0d6db9
61 changed files with 306 additions and 312 deletions

View File

@ -11,7 +11,7 @@ This document details the new architecture of the Angular compiler in a post-Ivy
Broadly speaking, The Ivy model is that Angular decorators (`@Injectable`, etc) are compiled to static properties on the classes (`ngInjectableDef`). This operation must take place without global program knowledge, and in most cases only with knowledge of that single decorator.
The one exception is `@Component`, which requires knowledge of the metadata from the `@NgModule` which declares the component in order to properly generate the `ngComponentDef`. In particular, the selectors which are applicable during compilation of a component template are determined by the module that declares that component, and the transitive closure of the exports of that module's imports.
The one exception is `@Component`, which requires knowledge of the metadata from the `@NgModule` which declares the component in order to properly generate the component def (`ɵcmp`). In particular, the selectors which are applicable during compilation of a component template are determined by the module that declares that component, and the transitive closure of the exports of that module's imports.
Going forward, this will be the model by which Angular code will be compiled, shipped to NPM, and eventually bundled into applications.
@ -81,7 +81,7 @@ In `ngtsc` this is instead emitted as,
```js
const i0 = require("@angular/core");
class GreetComponent {}
GreetComponent.ngComponentDef = i0.ɵɵdefineComponent({
GreetComponent.ɵcmp = i0.ɵɵdefineComponent({
type: GreetComponent,
tag: 'greet',
factory: () => new GreetComponent(),
@ -104,7 +104,7 @@ and the `.d.ts` contains:
```ts
import * as i0 from '@angular/core';
export class GreetComponent {
static ngComponentDef: i0.NgComponentDef<
static ɵcmp: i0.NgComponentDef<
GreetComponent,
'greet',
{input: 'input'}
@ -113,7 +113,7 @@ export class GreetComponent {
```
The information needed by reference inversion and type-checking is included in
the type declaration of the `ngComponentDef` in the `.d.ts`.
the type declaration of the `ɵcmp` in the `.d.ts`.
#### TypeScript architecture
@ -171,7 +171,7 @@ There are also a list of helper decorators that make the `@Component` and `@Dire
Each of the class decorators can be thought of as class transformers that take the declared class and transform it, possibly using information from the helper decorators, to produce an Angular class. The JIT compiler performs this transformation at runtime. The AoT compiler performs this transformation at compile time.
Each of the class decorators' class transformer creates a corresponding static member on the class that describes to the runtime how to use the class. For example, the `@Component` decorator creates an `ngComponentDef` static member, `@Directive` create an `ngDirectiveDef`, etc. Internally, these class transformers are called a "Compiler". Most of the compilers are straight forward translations of the metadata specified in the decorator to the information provided in the corresponding definition and, therefore, do not require anything outside the source file to perform the conversion. However, the component, during production builds and for type checking a template require the module scope of the component which requires information from other files in the program.
Each of the class decorators' class transformer creates a corresponding static member on the class that describes to the runtime how to use the class. For example, the `@Component` decorator creates a `ɵcmp` static member, `@Directive` create an `ngDirectiveDef`, etc. Internally, these class transformers are called a "Compiler". Most of the compilers are straight forward translations of the metadata specified in the decorator to the information provided in the corresponding definition and, therefore, do not require anything outside the source file to perform the conversion. However, the component, during production builds and for type checking a template require the module scope of the component which requires information from other files in the program.
#### Compiler design

View File

@ -39,7 +39,7 @@ The mental model of Ivy is that the decorator is the compiler. That is
the decorator can be thought of as parameters to a class transformer that
transforms the class by generating definitions based on the decorator
parameters. An `@Component` decorator transforms the class by adding
an `ngComponentDef` static property, `@Directive` adds `ngDirectiveDef`,
a `ɵcmp` static property, `@Directive` adds `ngDirectiveDef`,
`@Pipe` adds `ngPipeDef`, etc. In most cases values supplied to the
decorator is sufficient to generate the definition. However, in the case of
interpreting the template, the compiler needs to know the selector defined for
@ -65,7 +65,7 @@ class:
| field | destination |
|---------------------|-----------------------|
| `type` | implicit |
| `isComponent` | `ngComponentDef` |
| `isComponent` | `ɵcmp` |
| `selector` | `ngModuleScope` |
| `exportAs` | `ngDirectiveDef` |
| `inputs` | `ngDirectiveDef` |
@ -74,20 +74,20 @@ class:
| `hostProperties` | `ngDirectiveDef` |
| `hostAttributes` | `ngDirectiveDef` |
| `providers` | `ngInjectorDef` |
| `viewProviders` | `ngComponentDef` |
| `viewProviders` | `ɵcmp` |
| `queries` | `ngDirectiveDef` |
| `guards` | not used |
| `viewQueries` | `ngComponentDef` |
| `viewQueries` | `ɵcmp` |
| `entryComponents` | not used |
| `changeDetection` | `ngComponentDef` |
| `template` | `ngComponentDef` |
| `changeDetection` | `ɵcmp` |
| `template` | `ɵcmp` |
| `componentViewType` | not used |
| `renderType` | not used |
| `componentFactory` | not used |
Only one definition is generated per class. All components are directives so a
`ngComponentDef` contains all the `ngDirectiveDef` information. All directives
are injectable so `ngComponentDef` and `ngDirectiveDef` contain `ngInjectableDef`
`ɵcmp` contains all the `ngDirectiveDef` information. All directives
are injectable so `ɵcmp` and `ngDirectiveDef` contain `ngInjectableDef`
information.
For `CompilePipeSummary` the table looks like:
@ -126,9 +126,9 @@ reexported from the index.
The metadata for a class in ivy is transformed to be what the metadata of the
transformed .js file produced by the ivy compiler would be. For example, a
component's `@Component` is removed by the compiler and replaced by a `ngComponentDef`.
component's `@Component` is removed by the compiler and replaced by a `ɵcmp`.
The `.metadata.json` file is similarly transformed but the content of the
value assigned is elided (e.g. `"ngComponentDef": {}`). The compiler doesn't
value assigned is elided (e.g. `"ɵcmp": {}`). The compiler doesn't
record the selector declared for a component but it is needed to produce the
`ngModuleScope` so the information is recorded as if a static field
`ngSelector` was declared on class with the value of the `selector` field
@ -141,7 +141,7 @@ The following transformations are performed:
The metadata for a component is transformed by:
1. Removing the `@Component` directive.
2. Add `"ngComponentDef": {}` static field.
2. Add `"ɵcmp": {}` static field.
3. Add `"ngSelector": <selector-value>` static field.
##### Example
@ -161,7 +161,7 @@ export class MyComponent {
```js
export class MyComponent {
name: string;
static ngComponentDef = ɵɵdefineComponent({...});
static ɵcmp = ɵɵdefineComponent({...});
}
```
@ -174,7 +174,7 @@ export class MyComponent {
"MyComponent": {
"__symbolic": "class",
"statics": {
"ngComponentDef": {},
"ɵcmp": {},
"ngSelector": "my-comp"
}
}

View File

@ -200,7 +200,7 @@ export class ConstantPool {
public propertyNameOf(kind: DefinitionKind): string {
switch (kind) {
case DefinitionKind.Component:
return 'ngComponentDef';
return 'ɵcmp';
case DefinitionKind.Directive:
return 'ngDirectiveDef';
case DefinitionKind.Injector: