Skip to content

Commit 16d0d43

Browse files
mattlewis92thePunderWoman
authored andcommitted
fix(migrations): handle import aliases to the same module name (#63934)
Fixes a bug in the standalone migration where 2 imported modules have the same class name but 1 is imported with an alias and would not be added to the component imports array when migrating Fixes #63913 PR Close #63934
1 parent 5d9de59 commit 16d0d43

File tree

2 files changed

+97
-3
lines changed

2 files changed

+97
-3
lines changed

packages/core/schematics/ng-generate/standalone-migration/to-standalone.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,17 @@ function getComponentImportExpressions(
194194
typeChecker,
195195
);
196196

197-
if (importLocation && !seenImports.has(importLocation.symbolName)) {
198-
seenImports.add(importLocation.symbolName);
199-
resolvedDependencies.push(importLocation);
197+
if (importLocation) {
198+
// Create a unique key that includes both the symbol name and module specifier
199+
// to handle cases where the same symbol name is imported from different modules
200+
const importKey = importLocation.moduleSpecifier
201+
? `${importLocation.symbolName}::${importLocation.moduleSpecifier}`
202+
: importLocation.symbolName;
203+
204+
if (!seenImports.has(importKey)) {
205+
seenImports.add(importKey);
206+
resolvedDependencies.push(importLocation);
207+
}
200208
}
201209
}
202210

packages/core/schematics/test/standalone_migration_spec.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5037,4 +5037,90 @@ describe('standalone migration', () => {
50375037
`),
50385038
);
50395039
});
5040+
5041+
it('should add handle import aliases to the same module name', async () => {
5042+
writeFile(
5043+
'./app/comp.ts',
5044+
`
5045+
import { Component, NgModule } from '@angular/core';
5046+
import { AnotherModule } from '../another/another';
5047+
import { AnotherModule as LegacyAnotherModule } from '../another/another-legacy';
5048+
5049+
@Component({
5050+
selector: 'my-comp',
5051+
template: '<another1 /> <another2 />',
5052+
standalone: false
5053+
})
5054+
export class MyComponent {}
5055+
5056+
@NgModule({
5057+
imports: [AnotherModule, LegacyAnotherModule],
5058+
declarations: [MyComponent],
5059+
exports: [MyComponent]
5060+
})
5061+
export class MyModule {}
5062+
5063+
`,
5064+
);
5065+
5066+
writeFile(
5067+
'./another/another.ts',
5068+
`
5069+
import { Component, NgModule } from '@angular/core';
5070+
5071+
@Component({
5072+
selector: 'another1',
5073+
template: 'another1',
5074+
standalone: false
5075+
})
5076+
export class AnotherComponent {}
5077+
5078+
@NgModule({
5079+
declarations: [AnotherComponent],
5080+
exports: [AnotherComponent]
5081+
})
5082+
export class AnotherModule {}
5083+
5084+
`,
5085+
);
5086+
5087+
writeFile(
5088+
'./another/another-legacy.ts',
5089+
`
5090+
import { Component, NgModule } from '@angular/core';
5091+
5092+
@Component({
5093+
selector: 'another2',
5094+
template: 'another2',
5095+
standalone: false
5096+
})
5097+
export class AnotherComponent {}
5098+
5099+
@NgModule({
5100+
declarations: [AnotherComponent],
5101+
exports: [AnotherComponent]
5102+
})
5103+
export class AnotherModule {}
5104+
5105+
`,
5106+
);
5107+
5108+
await runMigration('convert-to-standalone', './app/');
5109+
5110+
const myCompContent = tree.readContent('app/comp.ts');
5111+
5112+
expect(myCompContent).toContain(`import { AnotherModule } from '../another/another';`);
5113+
expect(myCompContent).toContain(
5114+
`import { AnotherModule as LegacyAnotherModule } from '../another/another-legacy';`,
5115+
);
5116+
expect(stripWhitespace(myCompContent)).toContain(
5117+
stripWhitespace(`
5118+
@Component({
5119+
selector: 'my-comp',
5120+
template: '<another1 /> <another2 />',
5121+
imports: [AnotherModule, LegacyAnotherModule]
5122+
})
5123+
`),
5124+
);
5125+
});
50405126
});

0 commit comments

Comments
 (0)