diff --git a/packages/core/schematics/ng-generate/route-lazy-loading/to-lazy-routes.ts b/packages/core/schematics/ng-generate/route-lazy-loading/to-lazy-routes.ts index 92f639dac56..c275759e80b 100644 --- a/packages/core/schematics/ng-generate/route-lazy-loading/to-lazy-routes.ts +++ b/packages/core/schematics/ng-generate/route-lazy-loading/to-lazy-routes.ts @@ -278,9 +278,26 @@ function migrateRoute( return routeMigrationResults; } - const componentImport = route.routeFileImports.find((importDecl) => - importDecl.importClause?.getText().includes(componentClassName), - )!; + // Resolve the import that provides this component by exact specifier match + // Handles default imports, named imports, and aliases (e.g., `import { Foo as Bar }`). + const componentImport = route.routeFileImports.find((importDecl) => { + const clause = importDecl.importClause; + if (!clause) return false; + // Default import: import FooComponent from '...' + if (clause.name && ts.isIdentifier(clause.name) && clause.name.text === componentClassName) { + return true; + } + // Named imports: import { FooComponent } from '...' + const named = clause.namedBindings; + if (named && ts.isNamedImports(named)) { + return named.elements.some((el: ts.ImportSpecifier) => { + // Support alias: import { Foo as Bar } + const importedName = el.propertyName ? el.propertyName.text : el.name.text; + return importedName === componentClassName; + }); + } + return false; + })!; // remove single and double quotes from the import path let componentImportPath = ts.isStringLiteral(componentImport?.moduleSpecifier) diff --git a/packages/core/schematics/test/standalone_routes_spec.ts b/packages/core/schematics/test/standalone_routes_spec.ts index cc27f2f37b1..72230ce70e4 100644 --- a/packages/core/schematics/test/standalone_routes_spec.ts +++ b/packages/core/schematics/test/standalone_routes_spec.ts @@ -850,6 +850,59 @@ describe('route lazy loading migration', () => { ); }); + it('should resolve the correct import when one component name is a suffix of another', async () => { + writeFile( + 'app.module.ts', + ` + import {NgModule} from '@angular/core'; + import {RouterModule} from '@angular/router'; + import {FooBarComponent} from './foo-bar'; + import {BarComponent} from './bar'; + + @NgModule({ + imports: [RouterModule.forRoot([ + {path: 'foo-bar', component: FooBarComponent}, + {path: 'bar', component: BarComponent}, + ])], + }) + export class AppModule {} + `, + ); + + writeFile( + 'foo-bar.ts', + ` + import {Component} from '@angular/core'; + @Component({template: 'foo bar', standalone: true}) + export class FooBarComponent {} + `, + ); + + writeFile( + 'bar.ts', + ` + import {Component} from '@angular/core'; + @Component({template: 'bar', standalone: true}) + export class BarComponent {} + `, + ); + + await runMigration('route-lazy-loading'); + + const result = stripWhitespace(tree.readContent('app.module.ts')); + + expect(result).toContain( + stripWhitespace( + `{path: 'foo-bar', loadComponent: () => import('./foo-bar').then(m => m.FooBarComponent)}`, + ), + ); + expect(result).toContain( + stripWhitespace( + `{path: 'bar', loadComponent: () => import('./bar').then(m => m.BarComponent)}`, + ), + ); + }); + // TODO: support multiple imports of components // ex import * as Components from './components'; // export const MenuRoutes: Routes = [