Repository navigation
feat(ivy): emit module scope metadata using pure function call #29598
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
Changes from all commits
269b4f0
75c56ed
993809b
9c94276
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 |
|---|---|---|
|
|
@@ -442,10 +442,13 @@ describe('ngtsc behavioral tests', () => { | |
| env.driveMain(); | ||
|
|
||
| const jsContents = env.getContents('test.js'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule, bootstrap: [TestCmp] });'); | ||
| expect(jsContents) | ||
| .toContain('/*@__PURE__*/ i0.ɵsetNgModuleScope(TestModule, { declarations: [TestCmp] });'); | ||
| expect(jsContents) | ||
| .toContain( | ||
| 'i0.ɵdefineNgModule({ type: TestModule, bootstrap: [TestCmp], ' + | ||
| 'declarations: [TestCmp] })'); | ||
| 'i0.defineInjector({ factory: ' + | ||
| 'function TestModule_Factory(t) { return new (t || TestModule)(); } });'); | ||
|
|
||
| const dtsContents = env.getContents('test.d.ts'); | ||
| expect(dtsContents) | ||
|
|
@@ -457,6 +460,82 @@ describe('ngtsc behavioral tests', () => { | |
| expect(dtsContents).not.toContain('__decorate'); | ||
| }); | ||
|
|
||
| it('should not emit a setNgModuleScope call when no scope metadata is present', () => { | ||
| env.tsconfig(); | ||
| env.write('test.ts', ` | ||
| import {NgModule} from '@angular/core'; | ||
|
|
||
| @NgModule({}) | ||
| export class TestModule {} | ||
| `); | ||
|
|
||
| env.driveMain(); | ||
|
|
||
| const jsContents = env.getContents('test.js'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule });'); | ||
| expect(jsContents).not.toContain('ɵsetNgModuleScope(TestModule,'); | ||
| }); | ||
|
|
||
| it('should filter out directives and pipes from module exports in the injector def', () => { | ||
| env.tsconfig(); | ||
| env.write('test.ts', ` | ||
| import {NgModule} from '@angular/core'; | ||
| import {RouterComp, RouterModule} from '@angular/router'; | ||
| import {Dir, OtherDir, MyPipe, Comp} from './decls'; | ||
|
|
||
| @NgModule({ | ||
| declarations: [OtherDir], | ||
| exports: [OtherDir], | ||
| }) | ||
| export class OtherModule {} | ||
|
|
||
| const EXPORTS = [Dir, MyPipe, Comp, OtherModule, OtherDir, RouterModule, RouterComp]; | ||
|
|
||
| @NgModule({ | ||
| declarations: [Dir, MyPipe, Comp], | ||
| imports: [OtherModule, RouterModule.forRoot()], | ||
| exports: [EXPORTS], | ||
| }) | ||
| export class TestModule {} | ||
| `); | ||
| env.write(`decls.ts`, ` | ||
| import {Component, Directive, Pipe} from '@angular/core'; | ||
|
|
||
| @Directive({selector: '[dir]'}) | ||
| export class Dir {} | ||
|
|
||
| @Directive({selector: '[other]'}) | ||
| export class OtherDir {} | ||
|
|
||
| @Pipe({name:'pipe'}) | ||
| export class MyPipe {} | ||
|
|
||
| @Component({selector: 'test', template: ''}) | ||
| export class Comp {} | ||
| `); | ||
| env.write('node_modules/@angular/router/index.d.ts', ` | ||
| import {ɵComponentDefWithMeta, ModuleWithProviders, ɵNgModuleDefWithMeta} from '@angular/core'; | ||
|
|
||
| export declare class RouterComp { | ||
| static ngComponentDef: ɵComponentDefWithMeta<RouterComp, "lib-cmp", never, {}, {}, never> | ||
| } | ||
|
|
||
| declare class RouterModule { | ||
| static forRoot(): ModuleWithProviders<RouterModule>; | ||
| static ngModuleDef: ɵNgModuleDefWithMeta<RouterModule, [typeof RouterComp], never, [typeof RouterComp]>; | ||
| } | ||
| `); | ||
|
|
||
| env.driveMain(); | ||
|
|
||
| const jsContents = env.getContents('test.js'); | ||
| expect(jsContents) | ||
| .toContain( | ||
|
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. We don't need to match the whole structure of |
||
| 'i0.defineInjector({ factory: function TestModule_Factory(t) ' + | ||
| '{ return new (t || TestModule)(); }, imports: [[OtherModule, RouterModule.forRoot()],' + | ||
| '\n OtherModule,\n RouterModule] });'); | ||
|
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. Using the |
||
| }); | ||
|
|
||
| it('should compile NgModules with services without errors', () => { | ||
| env.tsconfig(); | ||
| env.write('test.ts', ` | ||
|
|
@@ -484,7 +563,7 @@ describe('ngtsc behavioral tests', () => { | |
| env.driveMain(); | ||
|
|
||
| const jsContents = env.getContents('test.js'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule,'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule });'); | ||
| expect(jsContents) | ||
| .toContain( | ||
| `TestModule.ngInjectorDef = i0.defineInjector({ factory: ` + | ||
|
|
@@ -525,7 +604,7 @@ describe('ngtsc behavioral tests', () => { | |
| env.driveMain(); | ||
|
|
||
| const jsContents = env.getContents('test.js'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule,'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule });'); | ||
| expect(jsContents) | ||
| .toContain( | ||
| `TestModule.ngInjectorDef = i0.defineInjector({ factory: ` + | ||
|
|
@@ -570,7 +649,7 @@ describe('ngtsc behavioral tests', () => { | |
| env.driveMain(); | ||
|
|
||
| const jsContents = env.getContents('test.js'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule,'); | ||
| expect(jsContents).toContain('i0.ɵdefineNgModule({ type: TestModule });'); | ||
| expect(jsContents) | ||
| .toContain( | ||
| `TestModule.ngInjectorDef = i0.defineInjector({ factory: ` + | ||
|
|
||
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.
I am not too certain about using the module scope to figure out if the ref is a module. It does however conveniently provide us with information on both refs from the program, as well as resolved refs from typings files.
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.
I actually like the approach of filtering out any exports from the scope, instead of filtering and including only known modules. It feels more robust.