fix(ivy): support module.id as @NgModule's "id" field value (#30040)
Prior to this commit, the check that verifies correct "id" field type was too strict and didn't allow `module.id` as @NgModule's "id" field value. This change adds a special handling for `module.id` and uses it as id of @NgModule if specified. PR Close #30040
This commit is contained in:
parent
04d13429f0
commit
aaf8145c48
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Expression, ExternalExpr, InvokeFunctionExpr, LiteralArrayExpr, LiteralExpr, R3Identifiers, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, Statement, WrappedNodeExpr, compileInjector, compileNgModule} from '@angular/compiler';
|
import {Expression, ExternalExpr, InvokeFunctionExpr, LiteralArrayExpr, R3Identifiers, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, Statement, WrappedNodeExpr, compileInjector, compileNgModule} from '@angular/compiler';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
|
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
|
||||||
|
@ -29,7 +29,7 @@ export interface NgModuleAnalysis {
|
||||||
metadataStmt: Statement|null;
|
metadataStmt: Statement|null;
|
||||||
declarations: Reference<ClassDeclaration>[];
|
declarations: Reference<ClassDeclaration>[];
|
||||||
exports: Reference<ClassDeclaration>[];
|
exports: Reference<ClassDeclaration>[];
|
||||||
id: string|null;
|
id: Expression|null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,16 +121,8 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
|
||||||
bootstrapRefs = this.resolveTypeList(expr, bootstrapMeta, name, 'bootstrap');
|
bootstrapRefs = this.resolveTypeList(expr, bootstrapMeta, name, 'bootstrap');
|
||||||
}
|
}
|
||||||
|
|
||||||
let id: string|null = null;
|
const id: Expression|null =
|
||||||
if (ngModule.has('id')) {
|
ngModule.has('id') ? new WrappedNodeExpr(ngModule.get('id') !) : null;
|
||||||
const expr = ngModule.get('id') !;
|
|
||||||
const value = this.evaluator.evaluate(expr);
|
|
||||||
if (typeof value !== 'string') {
|
|
||||||
throw new FatalDiagnosticError(
|
|
||||||
ErrorCode.VALUE_HAS_WRONG_TYPE, expr, `NgModule.id must be a string`);
|
|
||||||
}
|
|
||||||
id = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register this module's information with the LocalModuleScopeRegistry. This ensures that
|
// Register this module's information with the LocalModuleScopeRegistry. This ensures that
|
||||||
// during the compile() phase, the module's metadata is available for selector scope
|
// during the compile() phase, the module's metadata is available for selector scope
|
||||||
|
@ -267,8 +259,7 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
|
||||||
}
|
}
|
||||||
if (analysis.id !== null) {
|
if (analysis.id !== null) {
|
||||||
const registerNgModuleType = new ExternalExpr(R3Identifiers.registerNgModuleType);
|
const registerNgModuleType = new ExternalExpr(R3Identifiers.registerNgModuleType);
|
||||||
const callExpr = registerNgModuleType.callFn(
|
const callExpr = registerNgModuleType.callFn([analysis.id, new WrappedNodeExpr(node.name)]);
|
||||||
[new LiteralExpr(analysis.id), new WrappedNodeExpr(node.name)]);
|
|
||||||
ngModuleStatements.push(callExpr.toStmt());
|
ngModuleStatements.push(callExpr.toStmt());
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -496,9 +496,28 @@ describe('ngtsc behavioral tests', () => {
|
||||||
env.driveMain();
|
env.driveMain();
|
||||||
|
|
||||||
const jsContents = env.getContents('test.js');
|
const jsContents = env.getContents('test.js');
|
||||||
expect(jsContents).toContain('i0.\u0275registerNgModuleType("test", TestModule);');
|
expect(jsContents).toContain('i0.\u0275registerNgModuleType(\'test\', TestModule);');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should emit a \u0275registerNgModuleType call when the module id is defined as `module.id`',
|
||||||
|
() => {
|
||||||
|
env.tsconfig();
|
||||||
|
env.write('index.d.ts', `
|
||||||
|
declare const module = {id: string};
|
||||||
|
`);
|
||||||
|
env.write('test.ts', `
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@NgModule({id: module.id})
|
||||||
|
export class TestModule {}
|
||||||
|
`);
|
||||||
|
|
||||||
|
env.driveMain();
|
||||||
|
|
||||||
|
const jsContents = env.getContents('test.js');
|
||||||
|
expect(jsContents).toContain('i0.\u0275registerNgModuleType(module.id, TestModule);');
|
||||||
|
});
|
||||||
|
|
||||||
it('should filter out directives and pipes from module exports in the injector def', () => {
|
it('should filter out directives and pipes from module exports in the injector def', () => {
|
||||||
env.tsconfig();
|
env.tsconfig();
|
||||||
env.write('test.ts', `
|
env.write('test.ts', `
|
||||||
|
|
Loading…
Reference in New Issue