Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): add migration to remove entryComponents (#44322)
Adds an automated migration that will drop any usages of `entryComponents` from `@NgModule` and `@Component`. PR Close #44322
- Loading branch information
Showing
11 changed files
with
595 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
packages/core/schematics/migrations/entry-components/BUILD.bazel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
load("//tools:defaults.bzl", "ts_library") | ||
|
||
ts_library( | ||
name = "entry-components", | ||
srcs = glob(["**/*.ts"]), | ||
tsconfig = "//packages/core/schematics:tsconfig.json", | ||
visibility = [ | ||
"//packages/core/schematics:__pkg__", | ||
"//packages/core/schematics/migrations/google3:__pkg__", | ||
"//packages/core/schematics/test:__pkg__", | ||
], | ||
deps = [ | ||
"//packages/core/schematics/utils", | ||
"@npm//@angular-devkit/schematics", | ||
"@npm//@types/node", | ||
"@npm//typescript", | ||
], | ||
) |
33 changes: 33 additions & 0 deletions
33
packages/core/schematics/migrations/entry-components/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
## entryComponents migration | ||
As of Angular version 13, the `entryComponents` option in `@NgModule` and `@Component` isn't | ||
necessary anymore. This migration will automatically remove any usages. | ||
|
||
#### Before | ||
```ts | ||
import { NgModule, Component } from '@angular/core'; | ||
|
||
@Component({selector: 'my-comp', template: ''}) | ||
export class MyComp {} | ||
|
||
@NgModule({ | ||
declarations: [MyComp], | ||
entryComponents: [MyComp], | ||
exports: [MyComp] | ||
}) | ||
export class MyModule {} | ||
``` | ||
|
||
#### After | ||
```ts | ||
import { NgModule, Component } from '@angular/core'; | ||
|
||
@Component({selector: 'my-comp', template: ''}) | ||
export class MyComp {} | ||
|
||
@NgModule({ | ||
declarations: [MyComp], | ||
exports: [MyComp] | ||
}) | ||
export class MyModule {} | ||
``` | ||
|
56 changes: 56 additions & 0 deletions
56
packages/core/schematics/migrations/entry-components/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {Rule, SchematicsException, Tree} from '@angular-devkit/schematics'; | ||
import {relative} from 'path'; | ||
import ts from 'typescript'; | ||
|
||
import {getProjectTsConfigPaths} from '../../utils/project_tsconfig_paths'; | ||
import {canMigrateFile, createMigrationProgram} from '../../utils/typescript/compiler_host'; | ||
|
||
import {migrateEntryComponentsUsages} from './util'; | ||
|
||
|
||
/** Migration that removes `entryComponents` usages. */ | ||
export default function(): Rule { | ||
return async (tree: Tree) => { | ||
const {buildPaths, testPaths} = await getProjectTsConfigPaths(tree); | ||
const basePath = process.cwd(); | ||
const allPaths = [...buildPaths, ...testPaths]; | ||
|
||
if (!allPaths.length) { | ||
throw new SchematicsException( | ||
'Could not find any tsconfig file. Cannot remove `entryComponents`.'); | ||
} | ||
|
||
for (const tsconfigPath of allPaths) { | ||
runEntryComponentsMigration(tree, tsconfigPath, basePath); | ||
} | ||
}; | ||
} | ||
|
||
function runEntryComponentsMigration(tree: Tree, tsconfigPath: string, basePath: string) { | ||
const {program} = createMigrationProgram(tree, tsconfigPath, basePath); | ||
const typeChecker = program.getTypeChecker(); | ||
const printer = ts.createPrinter(); | ||
|
||
program.getSourceFiles() | ||
.filter(sourceFile => canMigrateFile(basePath, sourceFile, program)) | ||
.forEach(sourceFile => { | ||
const usages = migrateEntryComponentsUsages(typeChecker, printer, sourceFile); | ||
|
||
if (usages.length > 0) { | ||
const update = tree.beginUpdate(relative(basePath, sourceFile.fileName)); | ||
usages.forEach(usage => { | ||
update.remove(usage.start, usage.length); | ||
update.insertRight(usage.start, usage.replacement); | ||
}); | ||
tree.commitUpdate(update); | ||
} | ||
}); | ||
} |
51 changes: 51 additions & 0 deletions
51
packages/core/schematics/migrations/entry-components/util.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import ts from 'typescript'; | ||
|
||
import {getCallDecoratorImport} from '../../utils/typescript/decorators'; | ||
|
||
/** Finds and migrates all Angular decorators that pass in `entryComponents`. */ | ||
export function migrateEntryComponentsUsages( | ||
typeChecker: ts.TypeChecker, printer: ts.Printer, sourceFile: ts.SourceFile) { | ||
const results: {start: number, length: number, end: number, replacement: string}[] = []; | ||
|
||
sourceFile.forEachChild(function walk(node: ts.Node) { | ||
if (ts.isDecorator(node) && ts.isCallExpression(node.expression) && | ||
node.expression.arguments.length === 1 && | ||
ts.isObjectLiteralExpression(node.expression.arguments[0])) { | ||
const analysis = getCallDecoratorImport(typeChecker, node); | ||
|
||
if (analysis && analysis.importModule === '@angular/core' && | ||
(analysis.name === 'Component' || analysis.name === 'NgModule')) { | ||
const literal = node.expression.arguments[0]; | ||
const entryComponentsProp = literal.properties.find( | ||
property => ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && | ||
property.name.text === 'entryComponents'); | ||
|
||
if (entryComponentsProp) { | ||
const replacementNode = ts.updateObjectLiteral( | ||
literal, literal.properties.filter(prop => prop !== entryComponentsProp)); | ||
|
||
results.push({ | ||
start: literal.getStart(), | ||
length: literal.getWidth(), | ||
end: literal.getEnd(), | ||
replacement: printer.printNode(ts.EmitHint.Unspecified, replacementNode, sourceFile) | ||
}); | ||
} | ||
} | ||
} | ||
|
||
node.forEachChild(walk); | ||
}); | ||
|
||
// Sort the operations in reverse order in order to avoid | ||
// issues when migrating multiple usages within the same file. | ||
return results.sort((a, b) => b.start - a.start); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
packages/core/schematics/migrations/google3/entryComponentsRule.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {Replacement, RuleFailure, Rules} from 'tslint'; | ||
import ts from 'typescript'; | ||
|
||
import {migrateEntryComponentsUsages} from '../entry-components/util'; | ||
|
||
|
||
/** TSLint rule that removes usages of `entryComponents`. */ | ||
export class Rule extends Rules.TypedRule { | ||
override applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): RuleFailure[] { | ||
const typeChecker = program.getTypeChecker(); | ||
const printer = ts.createPrinter(); | ||
|
||
return migrateEntryComponentsUsages(typeChecker, printer, sourceFile).map(usage => { | ||
return new RuleFailure( | ||
sourceFile, usage.start, usage.end, | ||
'entryComponents are deprecated and don\'t need to be passed in.', this.ruleName, | ||
new Replacement(usage.start, usage.length, usage.replacement)); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.