Repository navigation
docs(ivy): update status.md #26382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs(ivy): update status.md #26382
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ We currently expect Ivy to remain behind the flag until it's feature complete an | |
| The work can be divided into three categories: | ||
| - `@angular/compiler-cli`: TypeScript transformer pipeline which includes two command line tools: | ||
| - `ngtsc`: (Angular TypeScript Compiler) Angular compiler which strips out `@Component` (and friends) and replaces it with `defineComponent` (and friends). | ||
| - `ngcc`: (Angular Compatibility Compiler) NPM upgrade compiler which reads the `.STORING_METADATA_IN_D.TS.json` files and `.js` files and adds `defineComponent` (and friends) into the `node_module`. This in effect converts a pre-ivy module into ivy module. | ||
| - `ngcc`: (Angular Compatibility Compiler) NPM upgrade compiler which reads the `STORING_METADATA_IN_D.TS.json` files and `.js` files and adds `defineComponent` (and friends) into the `node_module`. This in effect converts a pre-ivy module into ivy module. | ||
| - `@angular/compiler`: Ivy Compiler which converts decorator into ivy | ||
| - `@angular/core`: Decorators which can be patched with `@angular/compiler`. | ||
|
|
||
|
|
@@ -22,86 +22,71 @@ The work can be divided into three categories: | |
| TSC transformer which removes and converts `@Pipe`, `@Component`, `@Directive` and `@NgModule` | ||
| to the corresponding `definePipe`, `defineComponent`, `defineDirective` and `defineInjector`. | ||
|
|
||
| - ❌ Basic setup of the transformer into `tsc` | ||
| - ❌ Can read STORING_METADATA_IN_D.TS from `.d.ts` (see: [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md)) | ||
| - ❌ Detect decorators and convert them to the `defineXXX` method using the `__Compiler` in `@angular/compiler`. | ||
| - ❌ `@Pipe` => `definePipe` | ||
| - ❌ `@Component` => `defineComponent` | ||
| - ❌ `@Directive` => `defineDirective` | ||
| - ❌ `@NgModule` => `defineInjector` | ||
| - ❌ Encode selectors into `.d.ts` file. | ||
| - ❌ `@Pipe` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md) | ||
| - ❌ `@Component` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md) | ||
| - ❌ `@Directive` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md) | ||
| - ❌ `@NgModule` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md) | ||
| - ❌ support `extends` for `@Pipe`, `@Component`, `@Directive` and `@NgModule`. | ||
| - ✅ Basic setup of the transformer into `tsc` | ||
| - ✅ Can read STORING_METADATA_IN_D.TS from `.d.ts` (see: [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md)) | ||
| - ✅ Detect decorators and convert them to the `defineXXX` method using the `__Compiler` in `@angular/compiler`. | ||
| - ✅ Encode selectors into `.d.ts` file. | ||
| - ✅ support `extends` for `@Pipe`, `@Component`, `@Directive` and `@NgModule`. | ||
| - ❌ Documentation | ||
|
|
||
| ### `ngcc` Angular `node_module` compatibility compiler | ||
|
|
||
| A tool which "upgrades" `node_module` compiled with non-ivy `ngc` into ivy compliant format. | ||
|
|
||
| - ❌ Basic setup of stand alone executable | ||
| - ✅ Basic setup of stand alone executable | ||
| - ✅ Rewrite existing code by interpreting the associated STORING_METADATA_IN_D.TS | ||
| - ❌ Integration with WebPack (cli) | ||
| - ❌ Rewrite existing code by interpreting the associated STORING_METADATA_IN_D.TS | ||
| - ❌ `PipeCompiler`: `@Pipe` => `definePipe` | ||
| - ❌ `DirectiveCompiler`: `@Directive` => `defineDirective` | ||
| - ❌ `NgModuleCompiler`: `@NgModule` => `defineInjector` | ||
| - ❌ `ComponentCompiler`: `@Component` => `defineComponent` | ||
| - ❌ `TemplateCompiler` | ||
| - ❌ `StyleCompiler` | ||
| - ❌ Documentation | ||
|
|
||
| ## `@angular/compiler` changes | ||
|
|
||
| - ❌ Component compilation: Translates `@Component` => `defineComponent` | ||
| - ❌ `TemplateCompiler` (current known as `ViewCompiler`) | ||
| - ❌ `StyleCompiler` | ||
| - ❌ `PipeCompiler`: Translates `@Pipe` => `definePipe` | ||
| - ❌ `DirectiveCompiler`: Translates `@Directive` => `defineDirective` | ||
| - ❌ `InjectableCompiler`: Translates `@Injectable` => `defineInjectable` | ||
| - ❌ `NgModuleCompiler`: Translates `@NgModule` => `defineInjector` (and `defineNgModule` only in jit) | ||
| - ✅ Component compilation: Translates `@Component` => `defineComponent` | ||
| - ✅ `TemplateCompiler` (current known as `ViewCompiler`) | ||
| - ✅ `StyleCompiler` | ||
| - ✅ `PipeCompiler`: Translates `@Pipe` => `definePipe` | ||
| - ✅ `DirectiveCompiler`: Translates `@Directive` => `defineDirective` | ||
| - ✅ `InjectableCompiler`: Translates `@Injectable` => `defineInjectable` | ||
| - ✅ `NgModuleCompiler`: Translates `@NgModule` => `defineInjector` (and `defineNgModule` only in jit) | ||
| - ❌ Documentation | ||
|
|
||
|
|
||
| ## `@angular/core` changes | ||
|
|
||
| The goal is for the `@Component` (and friends) to be the compiler of template. Since decorators are functions which execute during parsing of the `.js` file, the decorator can compile the template into Ivy. The AoT compiler's job is to remove the `@Component` and replace it with call to `defineComponent`. | ||
|
|
||
| - ❌ Remove `createDecorator` (and friends) since we no longer support other modes. | ||
| - ❌ `@angular/compiler` can patch itself onto: | ||
| - ❌ `@Injectable` | ||
| - ❌ `@NgModule` | ||
| - ❌ `@Pipe` | ||
| - ❌ `@Directive` | ||
| - ❌ `@Component` | ||
| - ❌ `ResourceLoader.resolved: Promise<>` Returns true if all `templateUrl`s and `styleUrl` have been resolved and application is ready to be bootstrapped. | ||
| - ✅ `@angular/compiler` can patch itself onto: | ||
| - ✅ `@Injectable` | ||
| - ✅ `@NgModule` | ||
| - ✅ `@Pipe` | ||
| - ✅ `@Directive` | ||
| - ✅ `@Component` | ||
| - ✅ `ResourceLoader.resolved: Promise<>` Returns true if all `templateUrl`s and `styleUrl` have been resolved and application is ready to be bootstrapped. | ||
|
|
||
| # Testing / Debugging | ||
| - ❌ in debug mode publish components into DOM nodes for easier debugging. | ||
| - ✅ in debug mode publish components into DOM nodes for easier debugging. | ||
|
|
||
| # Crosscutting | ||
|
|
||
| ## Decorators | ||
| | Annotation | `defineXXX()` | Run time | Spec | Compiler | Back Patch | | ||
| | -------------------- | ------------------------------ | ------- | -------- | -------- | -------- | | ||
| | `@Component` | ✅ `defineComponent()` | ✅ | ✅ | ✅ | ❌ | | ||
| | `@Directive` | ✅ `defineDirective()` | ✅ | ✅ | ✅ | ❌ | | ||
| | `@Directive` | ❌ `defineAbstractDirective()` | ❌ | ❌ | ❌ | ❌ | | ||
| | `@Pipe` | ✅ `definePipe()` | ✅ | ✅ | ✅ | ❌ | | ||
| | `@Injectable` | ✅ `defineInjectable()` | ✅ | ❌ | ❌ | ❌ | | ||
| | `@NgModule` | ✅ `defineInjector()` | ✅ | ❌ | ❌ | ❌ | | ||
| | `@ConfigureInjector` | ❌ `defineInjector()` | ❌ | ❌ | ❌ | ❌ | | ||
| | Annotation | `defineXXX()` | Run time | Spec | Compiler | | ||
| | -------------------- | ------------------------------ | ------- | -------- | -------- | | ||
| | `@Component` | ✅ `defineComponent()` | ✅ | ✅ | ✅ | | ||
| | `@Directive` | ✅ `defineDirective()` | ✅ | ✅ | ✅ | | ||
| | `@Directive` | ✅ `defineBase()` | ✅ | ✅ | ✅ | | ||
| | `@Pipe` | ✅ `definePipe()` | ✅ | ✅ | ✅ | | ||
| | `@Injectable` | ✅ `defineInjectable()` | ✅ | ✅ | ✅ | | ||
| | `@NgModule` | ✅ `defineInjector()` | ✅ | ✅ | ✅ | | ||
| | `@ConfigureInjector` | ✅ `defineInjector()` | ❌ | ❌ | ❌ | | ||
|
|
||
|
|
||
|
|
||
| ## Component Composition | ||
| | Feature | Runtime | Spec | Compiler | | ||
| | ---------------------------------------- | ------- | -------- | -------- | | ||
| | creation reordering based on injection | ❌ | ❌ | ✅ | | ||
| | `class CompA extends CompB {}` | ❌ | ❌ | ❌ | | ||
| | `class CompA extends CompB { @Input }` | ❌ | ❌ | ❌ | | ||
| | `class CompA extends CompB { @Output }` | ❌ | ❌ | ❌ | | ||
| | creation reordering based on injection | ✅ | ✅ | ✅ | | ||
| | `class CompA extends CompB {}` | ✅ | ✅ | ✅ | | ||
| | `class CompA extends CompB { @Input }` | ✅ | ✅ | ✅ | | ||
| | `class CompA extends CompB { @Output }` | ✅ | ✅ | ✅ | | ||
|
|
||
|
|
||
|
|
||
|
|
@@ -147,16 +132,12 @@ The goal is for the `@Component` (and friends) to be the compiler of template. S | |
| | `<div style="literal">` | ✅ | ✅ | ✅ | | ||
| | `<div [style]="exp">` | ✅ | ✅ | ✅ | | ||
| | `<div [style.foo]="exp">` | ✅ | ✅ | ✅ | | ||
| | `<div xmlns:foo="url" foo:bar="baz">` <br/>Compiler still needs to be updated to process templates with namespaced attributes. ([see #24386](https://github.com/angular/angular/pull/24386)) | ✅ | ✅ | ❌ | | ||
| | `<div xmlns:foo="url" foo:bar="baz">` | ✅ | ✅ | ✅ | | ||
| | `{{ ['literal', exp ] }}` | ✅ | ✅ | ✅ | | ||
| | `{{ { a: 'literal', b: exp } }}` | ✅ | ✅ | ✅ | | ||
| | `{{ exp \| pipe: arg }}` | ✅ | ✅ | ✅ | | ||
| | `<svg:g svg:p>` | ✅ | ✅ | ✅ | | ||
| | `<img src=[userData]>` sanitization | ❌ | ❌ | ❌ | | ||
| | `<div (nocd.click)>` | ❌ | ❌ | ❌ | | ||
| | `<div (bubble.click)>` | ❌ | ❌ | ❌ | | ||
| | `<div (keyup.enter)>` | ❌ | ❌ | ❌ | | ||
| | `<div (hammer.js)>` | ❌ | ❌ | ❌ | | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All the gestures with hammer.js work today so we should either preserve this or designed an alternative (hammer.js seems to be getting outdated and not maintained those days, if I'm not mistaken).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above comment. |
||
| | `<img src=[userData]>` sanitization | ✅ | ✅ | ✅ | | ||
| | [`<div (directiveOut)>`][gh23560] | ✅ | ✅ | ✅ | | ||
| | [`<ng-template (directiveOut)>`][gh23561] | ✅ | ✅ | ✅ | | ||
| | [`<ng-container>`][gh24381] | ✅ | ✅ | ✅ | | ||
|
|
@@ -189,10 +170,10 @@ The goal is for the `@Component` (and friends) to be the compiler of template. S | |
| | `@Query(read)` | ✅ | ✅ | n/a | | ||
| | `@Query(selector)` | ✅ | ✅ | n/a | | ||
| | `@Query(Type)` | ✅ | ✅ | n/a | | ||
| | `@ContentChildren` | ✅ | ✅ | ❌ | | ||
| | `@ContentChildren` | ✅ | ✅ | ✅ | | ||
| | `@ContentChild` | ✅ | ✅ | ✅ | | ||
| | `@ViewChildren` | ✅ | ✅ | ❌ | | ||
| | `@ViewChild` | ✅ | ✅ | ❌ | | ||
| | `@ViewChildren` | ✅ | ✅ | ✅ | | ||
| | `@ViewChild` | ✅ | ✅ | ✅ | | ||
|
|
||
|
|
||
|
|
||
|
|
@@ -201,41 +182,41 @@ The goal is for the `@Component` (and friends) to be the compiler of template. S | |
| | ------------------------------- | ------- | -------- | -------- | | ||
| | `<ng-content>` | ✅ | ✅ | ✅ | | ||
| | `<ng-content selector="...">` | ✅ | ✅ | ✅ | | ||
| | container `projectAs` | ✅ | ✅ | ❌ | | ||
| | container `ngProjectAs` | ✅ | ✅ | ✅ | | ||
|
|
||
|
|
||
|
|
||
| ### Injection Features | ||
| | Feature | Runtime | Spec | Compiler | | ||
| | ----------------------------------- | ------- | -------- | -------- | | ||
| | `inject(Type)` | ✅ | ✅ | ✅ | | ||
| | `directiveInject(Type)` | ✅ | ✅ | ❌ | | ||
| | `directiveInject(Type)` | ✅ | ✅ | ✅ | | ||
| | `inject(Type, SkipSelf)` | ❌ | ❌ | ❌ | | ||
| | `attribute('name')` | ✅ | ✅ | ❌ | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it |
||
| | `injectChangeDetectionRef()` | ✅ | ✅ | ❌ | | ||
| | `injectChangeDetectionRef()` | ✅ | ✅ | ✅ | | ||
| | `injectElementRef()` | ✅ | ✅ | ✅ | | ||
| | `injectViewContainerRef()` | ✅ | ✅ | ✅ | | ||
| | `injectTemplateRef()` | ✅ | ✅ | ✅ | | ||
| | `injectRenderer2()` | ✅ | ✅ | ✅ | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| | default `inject()` with no injector | ❌ | ❌ | ❌ | | ||
| | sanitization with no injector | ✅ | ✅ | ❌ | | ||
| | default `inject()` with no injector | ✅ | ✅ | ✅ | | ||
| | sanitization with no injector | ✅ | ✅ | ✅ | | ||
|
|
||
|
|
||
| ### I18N | ||
| | Feature | Runtime | Spec | Compiler | | ||
| | ----------------------------------- | ------- | -------- | -------- | | ||
| | translate text literals | ✅ | ✅ | ✅ | | ||
| | translate text literals | ❌ | ❌ | ✅ | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😢
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We realized that the current implementation was flawed. Should have a fix soon. |
||
| | rearrange text nodes | ❌ | ❌ | ❌ | | ||
| | ICU | ❌ | ❌ | ❌ | | ||
|
|
||
|
|
||
| ### View Encapsulation | ||
| | Feature | Runtime | Spec | Compiler | | ||
| | ----------------------------------- | ------- | -------- | -------- | | ||
| | Renderer3.None | ✅ | ✅ | ✅ | | ||
| | Renderer2.None | ✅ | ✅ | ✅ | | ||
| | Renderer2.Emulated | ❌ | ❌ | ❌ | | ||
| | Renderer2.Native | ❌ | ❌ | ❌ | | ||
| | Renderer3.None | ✅ | ✅ | ✅ | | ||
| | Renderer2.None | ✅ | ✅ | ✅ | | ||
| | Renderer2.Emulated | ✅ | ✅ | ✅ | | ||
| | Renderer2.Native | ✅ | ✅ | ✅ | | ||
|
|
||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # Storing Metadata in `.d.ts` files | ||
|
|
||
| Previous version of Angular used `metadata.json` files to store information about directives/component/pipes/ng-modules. | ||
| `ngc` compiler would than do a global analysis to generate the `.ngfactory.ts` files from the `metadata.json`. | ||
| Ivy strives for locality, which means that `ngtsc` should not need any global information in order to compile the system. | ||
| The above is mostly true. | ||
| Unfortunately, in order for `ngtsc` to generate code which is tree shakable `ngtsc` does need to have global knowledge. | ||
|
|
||
| Here is an abbreviated example of breakage of tree-shake-ability. | ||
| ```typescript | ||
| @Directive({ | ||
| selector: '[tooltip]' | ||
| }) | ||
| export class TooltipDirective { | ||
| // ngtsc generates this: | ||
| static ngDirectiveDef = defineDirective(...); | ||
| } | ||
|
|
||
| @Component({ | ||
| selector: 'my-app', | ||
| template: 'Hello World!' | ||
| }) | ||
| class MyAppComponent { | ||
| // ngtsc generates this: | ||
| static ngDirectiveDef = defineComponent({ | ||
| ... | ||
| directives: [ | ||
| // BREAKS TREE-SHAKING!!! | ||
| // TooltipDirective included here because it was declared in the NgModule | ||
| // ngtsc does not know it can be omitted. | ||
| // Only way for ngtsc to know that it can omit TooltipDirective is if it knows | ||
| // its selector and see if the selector matches the current component's template. | ||
| TooltipDirective | ||
| ] | ||
| }); | ||
| } | ||
|
|
||
| @NgModule({ | ||
| declarations: [MyAppComponent, TooltipDirective], | ||
| bootstrap: [MyAppComponent], | ||
| }) | ||
| class MyAppModule { | ||
| // ngtsc generates this: | ||
| static ngDirectiveDef = defineNgModule(...); | ||
| } | ||
| ``` | ||
|
|
||
| Notice that `ngtsc` can't remove `TooltipDirective` because it would need to know its selector and see if the directive matches in the component's template. | ||
| Knowing the selector breaks locality and so we make an exception for some locality information such as selector, inputs and outputs. | ||
| Since we are breaking the locality rule, we need to store the information someplace since `ngtsc` can't have access to the `TooltipDirective` source. | ||
| We store the information in the `.d.ts` file like so. | ||
|
|
||
| ```typescript | ||
| class TooltipDirective { | ||
| static ngDirectiveDef: DirectiveDefWithMeta<TooltipDirective, '[tooltip]', '', {}, {}, []> | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(keyup.enter)works in the current view engine so we should preserve this functionality, otherwise this is a breaking change.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but it is all existing functionality from
Renderer2and so I don't think we need to track it here.