mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(compiler-cli): deduplicate deferred imports across multiple blocks
When @Component.deferredImports is defined as an object mapping block names to dependency arrays, deduplicate entries when aggregating block imports into the component-level flattened scope. This prevents duplicate directive/component collisions in DirectiveMatcher when multiple @defer blocks share dependencies.
This commit is contained in:
committed by
Leon Senft
parent
7d9f55da11
commit
2e2c426e76
@@ -120,7 +120,11 @@ export function validateAndFlattenComponentImports(
|
||||
validateAndFlattenComponentImports(blockValue, propExpr, isDeferred);
|
||||
|
||||
diagnostics.push(...blockDiagnostics);
|
||||
flattened.push(...blockImports);
|
||||
for (const blockImport of blockImports) {
|
||||
if (!flattened.some((existing) => existing.node === blockImport.node)) {
|
||||
flattened.push(blockImport);
|
||||
}
|
||||
}
|
||||
importsByBlock.set(blockName, blockImports);
|
||||
}
|
||||
return {imports: flattened, importsByBlock, diagnostics};
|
||||
|
||||
@@ -2547,6 +2547,46 @@ runInEachFileSystem(() => {
|
||||
"Directive 'DirB' (used on element 'div') was imported via `@Component.deferredImports` under block 'blockB', but is used in a `@defer` block configured for 'blockC'",
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow the same dependency across multiple defer blocks without duplicate symbol diagnostics', () => {
|
||||
env.write(
|
||||
'dirs.ts',
|
||||
`
|
||||
import { Directive } from '@angular/core';
|
||||
@Directive({ selector: '[dirA]' })
|
||||
export class DirA {}
|
||||
`,
|
||||
);
|
||||
|
||||
env.write(
|
||||
'/test.ts',
|
||||
`
|
||||
import { Component } from '@angular/core';
|
||||
import { DirA } from './dirs';
|
||||
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
// @ts-ignore
|
||||
deferredImports: {
|
||||
blockA: [DirA],
|
||||
blockB: [DirA],
|
||||
},
|
||||
template: \`
|
||||
@defer (name blockA) {
|
||||
<div dirA></div>
|
||||
}
|
||||
@defer (name blockB) {
|
||||
<div dirA></div>
|
||||
}
|
||||
\`,
|
||||
})
|
||||
export class TestCmp {}
|
||||
`,
|
||||
);
|
||||
|
||||
const diags = env.driveDiagnostics();
|
||||
expect(diags.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user