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:

committed by
Miško Hevery

parent
d4d07233dc
commit
64fd0d6db9
@ -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
|
||||
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
Reference in New Issue
Block a user