Skip to content

Commit 64fa571

Browse files
pmvaldthePunderWoman
authored andcommitted
fix(compiler-cli): generating extra imports in local compilation mode when cycle is introduced (#53543)
At the moment the extra import generation in local compilation mode fails if these extra imports produce a cycle. To handle this, the cycle handling strategy is updated for local compilation, and following the behaviour in the full compilation mode, the compiler does not generate extra import if it leads to cycle and instead leave things to the runtime. PR Close #53543
1 parent 7e861c6 commit 64fa571

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

packages/compiler-cli/src/ngtsc/annotations/ng_module/src/handler.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,11 @@ export class NgModuleDecoratorHandler implements
788788
ngModuleStatements: Statement[], node: ClassDeclaration,
789789
declarations: Reference<ClassDeclaration>[],
790790
remoteScopesMayRequireCycleProtection: boolean): void {
791+
// Local compilation mode generates its own runtimes to compute the dependencies. So there no
792+
// need to add remote scope statements (which also conflicts with local compilation runtimes)
793+
if (this.compilationMode === CompilationMode.LOCAL) {
794+
return;
795+
}
791796
const context = getSourceFile(node);
792797
for (const decl of declarations) {
793798
const remoteScope = this.scopeRegistry.getRemoteScope(decl.node);

packages/compiler-cli/src/ngtsc/core/src/compiler.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,12 +1100,12 @@ export class NgCompiler {
11001100
localCompilationExtraImportsTracker = new LocalCompilationExtraImportsTracker(checker);
11011101
}
11021102

1103-
// Cycles are handled in full compilation mode by "remote scoping".
1103+
// Cycles are handled in full and local compilation modes by "remote scoping".
11041104
// "Remote scoping" does not work well with tree shaking for libraries.
11051105
// So in partial compilation mode, when building a library, a cycle will cause an error.
1106-
const cycleHandlingStrategy = compilationMode === CompilationMode.FULL ?
1107-
CycleHandlingStrategy.UseRemoteScoping :
1108-
CycleHandlingStrategy.Error;
1106+
const cycleHandlingStrategy = compilationMode === CompilationMode.PARTIAL ?
1107+
CycleHandlingStrategy.Error :
1108+
CycleHandlingStrategy.UseRemoteScoping;
11091109

11101110
const strictCtorDeps = this.options.strictInjectionParameters || false;
11111111
const supportJitMode = this.options['supportJitMode'] ?? true;

packages/compiler-cli/test/ngtsc/local_compilation_spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,49 @@ runInEachFileSystem(
262262
expect(env.getContents('main_comp.js')).toContain('import "internal_dir"');
263263
expect(env.getContents('main_comp.js')).toContain('import "internal_pipe"');
264264
});
265+
266+
it('should not include extra import and remote scope runtime for the local component dependencies when cycle is produced',
267+
() => {
268+
env.write('internal_comp.ts', `
269+
import {Component} from '@angular/core';
270+
import {cycleCreatingDep} from './main_comp';
271+
272+
@Component({template: '...', selector: 'internal-comp'})
273+
export class InternalComp {
274+
}
275+
`);
276+
env.write('internal_module.ts', `
277+
import {NgModule} from '@angular/core';
278+
279+
import {InternalComp} from 'internal_comp';
280+
281+
@NgModule({declarations: [InternalComp], exports: [InternalComp]})
282+
export class InternalModule {
283+
}
284+
`);
285+
env.write('main_comp.ts', `
286+
import {Component} from '@angular/core';
287+
288+
@Component({template: '<internal-comp></internal-comp>'})
289+
export class MainComp {
290+
}
291+
`);
292+
env.write('main_module.ts', `
293+
import {NgModule} from '@angular/core';
294+
295+
import {MainComp} from 'main_comp';
296+
import {InternalModule} from 'internal_module';
297+
298+
@NgModule({declarations: [MainComp], imports: [InternalModule]})
299+
export class MainModule {
300+
}
301+
`);
302+
303+
env.driveMain();
304+
305+
expect(env.getContents('main_comp.js')).not.toContain('import "internal_comp"');
306+
expect(env.getContents('main_module.js')).not.toContain('ɵɵsetComponentScope');
307+
});
265308
});
266309

267310
describe('ng module injector def', () => {

0 commit comments

Comments
 (0)