mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(compiler-cli): move NgModule bootstrap definition to runtime in local compilation mode (#51767)
Today in local compilation mode the NgModule bootstrap definition is moved as it is into the runtime `ɵɵdefineNgModule`. This runtime was initially made for AoT full compilation mode and assumes that the bootstrap info is already flattened and resolved. This is not the case in local compilation where the bootstrap is the raw expression coming from the NgModule decorator and can be a nested array. To get around this problem we move the bootstrap along with other scope info (e.g., declarations, imports, exports) to the runtime`ɵɵsetNgModuleScope` to be further analyzed and flattened in runtime. PR Close #51767
This commit is contained in:
committed by
Pawel Kozlowski
parent
1d0fc42fc7
commit
fbf3ac247b
@@ -562,5 +562,55 @@ runInEachFileSystem(() => {
|
||||
expect(text).toContain('either inline it or move it to a separate file');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ng module bootstrap def', () => {
|
||||
it('should include the bootstrap definition in ɵɵsetNgModuleScope instead of ɵɵdefineNgModule',
|
||||
() => {
|
||||
env.write('test.ts', `
|
||||
import {NgModule} from '@angular/core';
|
||||
import {App} from './some-where';
|
||||
|
||||
@NgModule({
|
||||
declarations: [App],
|
||||
bootstrap: [App],
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
`);
|
||||
|
||||
env.driveMain();
|
||||
const jsContents = env.getContents('test.js');
|
||||
|
||||
expect(jsContents)
|
||||
.toContain(
|
||||
'AppModule.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: AppModule });');
|
||||
expect(jsContents)
|
||||
.toContain(
|
||||
'ɵɵsetNgModuleScope(AppModule, { declarations: [App], bootstrap: [App] }); })();');
|
||||
});
|
||||
|
||||
it('should include no bootstrap definition in ɵɵsetNgModuleScope if the NgModule has no bootstrap field',
|
||||
() => {
|
||||
env.write('test.ts', `
|
||||
import {NgModule} from '@angular/core';
|
||||
import {App} from './some-where';
|
||||
|
||||
@NgModule({
|
||||
declarations: [App],
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
`);
|
||||
|
||||
env.driveMain();
|
||||
const jsContents = env.getContents('test.js');
|
||||
|
||||
expect(jsContents)
|
||||
.toContain(
|
||||
'AppModule.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: AppModule });');
|
||||
expect(jsContents)
|
||||
.toContain('ɵɵsetNgModuleScope(AppModule, { declarations: [App] }); })();');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -204,15 +204,11 @@ export function compileNgModule(meta: R3NgModuleMetadata): R3CompiledExpression
|
||||
const definitionMap = new DefinitionMap<R3NgModuleDefMap>();
|
||||
definitionMap.set('type', meta.type.value);
|
||||
|
||||
// Assign bootstrap definition
|
||||
if (meta.kind === R3NgModuleMetadataKind.Global) {
|
||||
if (meta.bootstrap.length > 0) {
|
||||
definitionMap.set('bootstrap', refsToArray(meta.bootstrap, meta.containsForwardDecls));
|
||||
}
|
||||
} else {
|
||||
if (meta.bootstrapExpression) {
|
||||
definitionMap.set('bootstrap', meta.bootstrapExpression);
|
||||
}
|
||||
// Assign bootstrap definition. In local compilation mode (i.e., for
|
||||
// `R3NgModuleMetadataKind.LOCAL`) we assign the bootstrap field using the runtime
|
||||
// `ɵɵsetNgModuleScope`.
|
||||
if (meta.kind === R3NgModuleMetadataKind.Global && meta.bootstrap.length > 0) {
|
||||
definitionMap.set('bootstrap', refsToArray(meta.bootstrap, meta.containsForwardDecls));
|
||||
}
|
||||
|
||||
if (meta.selectorScopeMode === R3SelectorScopeMode.Inline) {
|
||||
@@ -321,8 +317,12 @@ export function createNgModuleType(meta: R3NgModuleMetadata): o.ExpressionType {
|
||||
* symbols to become tree-shakeable.
|
||||
*/
|
||||
function generateSetNgModuleScopeCall(meta: R3NgModuleMetadata): o.Statement|null {
|
||||
const scopeMap = new DefinitionMap<
|
||||
{declarations: o.Expression, imports: o.Expression, exports: o.Expression}>();
|
||||
const scopeMap = new DefinitionMap<{
|
||||
declarations: o.Expression,
|
||||
imports: o.Expression,
|
||||
exports: o.Expression,
|
||||
bootstrap: o.Expression
|
||||
}>();
|
||||
|
||||
if (meta.kind === R3NgModuleMetadataKind.Global) {
|
||||
if (meta.declarations.length > 0) {
|
||||
@@ -354,6 +354,10 @@ function generateSetNgModuleScopeCall(meta: R3NgModuleMetadata): o.Statement|nul
|
||||
}
|
||||
}
|
||||
|
||||
if (meta.kind === R3NgModuleMetadataKind.Local && meta.bootstrapExpression) {
|
||||
scopeMap.set('bootstrap', meta.bootstrapExpression);
|
||||
}
|
||||
|
||||
if (Object.keys(scopeMap.values).length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user