feat(migrations): add schematic to clean up unused imports#59353
feat(migrations): add schematic to clean up unused imports#59353crisbeto wants to merge 3 commits intoangular:mainfrom
Conversation
Exports the error codes so that they can be reused.
Allows for user-defined options to be passed in when creating a program in tsurge.
In v19 we added a warning about unused standalone imports, however we didn't do anything about existing code which means that users have to clean it up manually. These changes add the `ng g @angular/core:cleanup-unused-imports` schematic which will remove the unused dependencies automatically. There isn't any new detection code since all the manipulations are based on the produced diagnostics, but there's a bit of code to remove the import declarations from the file as well. Fixes angular#58849.
| }); | ||
| } | ||
|
|
||
| override async analyze(info: ProgramInfo): Promise<Serializable<CompilationUnitData>> { |
There was a problem hiding this comment.
Note: I'm not sure if I'm using the analyze method properly since it produces all the text replacements in addition to the analysis. The reason is that each file can be migrated independently and it doesn't require any information from other files (aside from typings). It was more hassle to encode the analysis results in a serializable way just to produce the same result in migrate than to produce the result immediately.
There was a problem hiding this comment.
It's totally fine to produce replacements in the analyze stage if they are easy to compute 👍. I think at this point you likely never generate replacements directly in migrate, but only ever filter replacements there (based on the global metadata).
devversion
left a comment
There was a problem hiding this comment.
will review more as soon as possible!
| }); | ||
| } | ||
|
|
||
| override async analyze(info: ProgramInfo): Promise<Serializable<CompilationUnitData>> { |
There was a problem hiding this comment.
It's totally fine to produce replacements in the analyze stage if they are easy to compute 👍. I think at this point you likely never generate replacements directly in migrate, but only ever filter replacements there (based on the global metadata).
|
Q: Do we intend to add a doc entry for it ? |
|
Yes, I'll send a follow-up with docs and potentially change the diagnostic message to mention the schematic. |
In v19 we added a warning about unused standalone imports, however we didn't do anything about existing code which means that users have to clean it up manually. These changes add the `ng g @angular/core:cleanup-unused-imports` schematic which will remove the unused dependencies automatically. There isn't any new detection code since all the manipulations are based on the produced diagnostics, but there's a bit of code to remove the import declarations from the file as well. Fixes #58849. PR Close #59353
|
This PR was merged into the repository by commit d298d25. The changes were merged into the following branches: main |
|
Not sure if this is the right place to report this, but I tried the
In my case, the command duplicated the TypeScript imports and added syntax errors like import {
CardBodyComponent,
CardComponent,
CardFooterComponent,
CardHeaderComponent,
CardTitleDirective,
ColComponent,
ContainerComponent,
DropdownDividerDirective,
FormControlDirective,
FormDirective,
InputGroupComponent,
InputGroupTextDirective,
ModalService,
NavComponent,
NavItemComponent,
RowComponent,
TableDirective
}{
CardBodyComponent,
CardComponent,
CardFooterComponent,
CardHeaderComponent,
CardTitleDirective,
ColComponent,
ContainerComponent,
DropdownDividerDirective,
FormControlDirective,
FormDirective,
InputGroupComponent,
InputGroupTextDirective,
ModalService,
NavComponent,
NavItemComponent,
RowComponent,
TableDirective
} from '@coreui/angular';The imports in the @Component({
selector: 'oitc-servicetemplategroups-index',
imports: [
TranslocoDirective,
DeleteAllModalComponent,
FaIconComponent,
PermissionDirective,
RouterLink,
ActionsButtonComponent,
ActionsButtonElementComponent,
CardBodyComponent,
CardComponent,
CardFooterComponent,
CardHeaderComponent,
CardTitleDirective,
ColComponent,
ContainerComponent,
DebounceDirective,
DropdownDividerDirective,
FormControlDirective,
FormDirective,
FormsModule,
InputGroupComponent,
InputGroupTextDirective,
ItemSelectComponent,
MatSort,
MatSortHeader,
NavComponent,
NavItemComponent,
NgForOf,
NgIf,
NoRecordsComponent,
PaginateOrScrollComponent,
ReactiveFormsModule,
RowComponent,
SelectAllComponent,
TableDirective,
TranslocoPipe,
XsButtonDirective,
TableLoaderComponent
][
TranslocoDirective,
DeleteAllModalComponent,
FaIconComponent,
PermissionDirective,
RouterLink,
ActionsButtonComponent,
ActionsButtonElementComponent,
CardBodyComponent,
CardComponent,
CardFooterComponent,
CardHeaderComponent,
CardTitleDirective,
ColComponent,
ContainerComponent,
DebounceDirective,
DropdownDividerDirective,
FormControlDirective,
FormDirective,
FormsModule,
InputGroupComponent,
InputGroupTextDirective,
ItemSelectComponent,
MatSort,
MatSortHeader,
NavComponent,
NavItemComponent,
NgForOf,
NgIf,
NoRecordsComponent,
PaginateOrScrollComponent,
ReactiveFormsModule,
RowComponent,
SelectAllComponent,
TableDirective,
TranslocoPipe,
XsButtonDirective,
TableLoaderComponent
],
templateUrl: './servicetemplategroups-index.component.html',
styleUrl: './servicetemplategroups-index.component.css',
providers: [
{ provide: DELETE_SERVICE_TOKEN, useClass: ServicetemplategroupsService } // Inject the ServicetemplategroupsService into the DeleteAllModalComponent
],
changeDetection: ChangeDetectionStrategy.OnPush
}) |
|
@nook24 that does sound like a bug. Did this happen in all files or only specific ones? |
|
This happened in a lot of files, so probably all that where touched by the command. In my case a few hundred files, I only checked a few of them they all had the same issue. |
|
Interesting, I'm trying it against some of our own projects and it works fine. This looks like a string replacement issue, rather than the imports actually being duplicated. Do you happen to be on Windows? We've had issues in the past with text encoding there. |
|
This was my first thought as well, that the string replace was gone wild. This is one of the files in question (original): https://gist.github.com/nook24/7d9141f4d82c071331f52d3fb1b43e6b I run the command on Linux, with Linux new lines ( Not sure if related, but the first run crashed with out of memory, increasing the system memory from 8 to 16GB resolved this. |
|
That file seems fine from what I can tell, although Github might be normalizing something. I can't run the file as is through our tests since all those imports need to actually exist for the migration to run. |
|
I can get an identical result to yours if I comment out this line although I don't see a way that could happen in a migration. Can you try resetting your repo and running it from scratch with the extra memory? I wonder if the project wasn't left in a corrupted state during your first run when it ran out of memory. |
|
In my case, the code is located at Maybe i have installed the Angular version wrong, I used
That was what I did in the first place. To be extra sure, I did it again, unfortunately with the same result. According to git, 283 files where changed in the process. I randomly picked 10 for manual inspection. All files I checked have the same issue. Also single line imports are affected ( --- a/src/app/modules/import_module/components/dependency-tree/not-in-monitoring/not-in-monitoring.component.ts
+++ b/src/app/modules/import_module/components/dependency-tree/not-in-monitoring/not-in-monitoring.component.ts
@@ -1,8 +1,8 @@
import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core';
-import { BadgeComponent, TableDirective } from '@coreui/angular';
+
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
-import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
-import { PermissionDirective } from '../../../../../permissions/permission.directive';
+import { AsyncPipe, NgIf }{ AsyncPipe, NgIf } from '@angular/common';
+
import { TranslocoDirective } from '@jsverse/transloco';
import { NodeExtended } from '../dependency-tree.component';
import { SystemnameService } from '../../../../../services/systemname.service';
@@ -10,15 +10,16 @@ import { SystemnameService } from '../../../../../services/systemname.service';
@Component({
selector: 'oitc-not-in-monitoring',
imports: [
- BadgeComponent,
- FaIconComponent,
- NgForOf,
- NgIf,
- PermissionDirective,
- TableDirective,
- TranslocoDirective,
- AsyncPipe
- ],
+ FaIconComponent,
+ NgIf,
+ TranslocoDirective,
+ AsyncPipe
+][
+ FaIconComponent,
+ NgIf,
+ TranslocoDirective,
+ AsyncPipe
+],
templateUrl: './not-in-monitoring.component.html',
styleUrl: './not-in-monitoring.component.css',
changeDetection: ChangeDetectionStrategy.OnPush |
…plate of ... errors until angular/angular#59353 (comment) is fixed
|
Hmm then I'm a bit out of ideas without being able to reproduce it locally. One last thing we can try is to replace the |
|
--- a/src/app/modules/import_module/components/dependency-tree/not-in-monitoring/not-in-monitoring.component.ts
+++ b/src/app/modules/import_module/components/dependency-tree/not-in-monitoring/not-in-monitoring.component.ts
@@ -1,8 +1,8 @@
import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core';
-import { BadgeComponent, TableDirective } from '@coreui/angular';
+
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
-import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
-import { PermissionDirective } from '../../../../../permissions/permission.directive';
+import { AsyncPipe, NgIf } from '@angular/common';
+
import { TranslocoDirective } from '@jsverse/transloco';
import { NodeExtended } from '../dependency-tree.component';
import { SystemnameService } from '../../../../../services/systemname.service';
@@ -10,15 +10,11 @@ import { SystemnameService } from '../../../../../services/systemname.service';
@Component({
selector: 'oitc-not-in-monitoring',
imports: [
- BadgeComponent,
- FaIconComponent,
- NgForOf,
- NgIf,
- PermissionDirective,
- TableDirective,
- TranslocoDirective,
- AsyncPipe
- ],
+ FaIconComponent,
+ NgIf,
+ TranslocoDirective,
+ AsyncPipe
+],
templateUrl: './not-in-monitoring.component.html',
styleUrl: './not-in-monitoring.component.css',
changeDetection: ChangeDetectionStrategy.OnPushUpdated 283 files in this case. Many thanks for your time and effort ❤️ |
Based on angular#59353 (comment), fixes a text replacement issue that seems to cause code to be duplicated in some setups.
|
Awesome, thank you for verifying it! 🎉 I've sent a fix at #59452. |
Based on #59353 (comment), fixes a text replacement issue that seems to cause code to be duplicated in some setups. PR Close #59452
Based on #59353 (comment), fixes a text replacement issue that seems to cause code to be duplicated in some setups. PR Close #59452
Exports the error codes so that they can be reused. PR Close angular#59353
…ge (angular#59353) Allows for user-defined options to be passed in when creating a program in tsurge. PR Close angular#59353
…9353) In v19 we added a warning about unused standalone imports, however we didn't do anything about existing code which means that users have to clean it up manually. These changes add the `ng g @angular/core:cleanup-unused-imports` schematic which will remove the unused dependencies automatically. There isn't any new detection code since all the manipulations are based on the produced diagnostics, but there's a bit of code to remove the import declarations from the file as well. Fixes angular#58849. PR Close angular#59353
Based on angular#59353 (comment), fixes a text replacement issue that seems to cause code to be duplicated in some setups. PR Close angular#59452
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |



In v19 we added a warning about unused standalone imports, however we didn't do anything about existing code which means that users have to clean it up manually. These changes add the
ng g @angular/core:cleanup-unused-importsschematic which will remove the unused dependencies automatically.There isn't any new detection code since all the manipulations are based on the produced diagnostics, but there's a bit of code to remove the import declarations from the file as well.
Fixes #58849.