Skip to content

Commit 7f0d459

Browse files
clydinmgechev
authored andcommitted
refactor(@schematics/angular): use new workspace helpers in polyfill-metadata migration
1 parent 1735724 commit 7f0d459

File tree

1 file changed

+27
-84
lines changed

1 file changed

+27
-84
lines changed

packages/schematics/angular/migrations/update-7/polyfill-metadata.ts

Lines changed: 27 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import { JsonObject, JsonParseMode, JsonValue, parseJson } from '@angular-devkit/core';
9-
import { Rule, Tree, chain, noop } from '@angular-devkit/schematics';
8+
import { Rule, Tree, chain } from '@angular-devkit/schematics';
109
import * as ts from '../../third_party/github.com/Microsoft/TypeScript/lib/typescript';
11-
12-
function isJsonObject(value: JsonValue): value is JsonObject {
13-
return value != null && typeof value === 'object' && !Array.isArray(value);
14-
}
10+
import { getWorkspace } from '../../utility/workspace';
11+
import { Builders } from '../../utility/workspace-models';
1512

1613
/**
1714
* Remove the Reflect import from a polyfill file.
@@ -29,8 +26,7 @@ function _removeReflectFromPolyfills(tree: Tree, path: string) {
2926
const recorder = tree.beginUpdate(path);
3027

3128
const sourceFile = ts.createSourceFile(path, source.toString(), ts.ScriptTarget.Latest);
32-
const imports = sourceFile.statements
33-
.filter(s => s.kind === ts.SyntaxKind.ImportDeclaration) as ts.ImportDeclaration[];
29+
const imports = sourceFile.statements.filter(ts.isImportDeclaration);
3430

3531
for (const i of imports) {
3632
const module = ts.isStringLiteral(i.moduleSpecifier) && i.moduleSpecifier.text;
@@ -45,92 +41,39 @@ function _removeReflectFromPolyfills(tree: Tree, path: string) {
4541
tree.commitUpdate(recorder);
4642
}
4743

48-
/**
49-
* Update a project's target, maybe. Only if it's a builder supported and the options look right.
50-
* This is a rule factory so we return the new rule (or noop if we don't support doing the change).
51-
* @param root The root of the project source.
52-
* @param targetObject The target information.
53-
* @private
54-
*/
55-
function _updateProjectTarget(targetObject: JsonObject): Rule {
56-
// Make sure we're using the correct builder.
57-
if (targetObject.builder !== '@angular-devkit/build-angular:browser'
58-
|| !isJsonObject(targetObject.options)) {
59-
return noop();
60-
}
61-
const options = targetObject.options;
62-
if (typeof options.polyfills != 'string') {
63-
return noop();
64-
}
65-
66-
const polyfillsToUpdate = [options.polyfills];
67-
const configurations = targetObject.configurations;
68-
if (isJsonObject(configurations)) {
69-
for (const configName of Object.keys(configurations)) {
70-
const config = configurations[configName];
71-
72-
// Just in case, only do non-AOT configurations.
73-
if (isJsonObject(config)
74-
&& typeof config.polyfills == 'string'
75-
&& config.aot !== true) {
76-
polyfillsToUpdate.push(config.polyfills);
77-
}
78-
}
79-
}
80-
81-
return chain(
82-
polyfillsToUpdate.map(polyfillPath => {
83-
return (tree: Tree) => _removeReflectFromPolyfills(tree, polyfillPath);
84-
}),
85-
);
86-
}
87-
88-
/**
89-
* Move the import reflect metadata polyfill from the polyfill file to the dev environment. This is
90-
* not guaranteed to work, but if it doesn't it will result in no changes made.
91-
*/
9244
export function polyfillMetadataRule(): Rule {
93-
return (tree) => {
94-
// Simple. Take the ast of polyfills (if it exists) and find the import metadata. Remove it.
95-
const angularConfigContent = tree.read('angular.json') || tree.read('.angular.json');
96-
const rules: Rule[] = [];
97-
98-
if (!angularConfigContent) {
99-
// Is this even an angular project?
100-
return;
101-
}
102-
103-
const angularJson = parseJson(angularConfigContent.toString(), JsonParseMode.Loose);
45+
return async (tree) => {
46+
const workspace = await getWorkspace(tree);
10447

105-
if (!isJsonObject(angularJson) || !isJsonObject(angularJson.projects)) {
106-
// If that field isn't there, no use...
107-
return;
108-
}
109-
110-
// For all projects, for all targets, read the polyfill field, and read the environment.
111-
for (const projectName of Object.keys(angularJson.projects)) {
112-
const project = angularJson.projects[projectName];
113-
if (!isJsonObject(project)) {
114-
continue;
115-
}
116-
if (typeof project.root != 'string') {
48+
const rules: Rule[] = [];
49+
for (const [, project] of workspace.projects) {
50+
if (typeof project.root !== 'string') {
11751
continue;
11852
}
11953

120-
const targets = project.targets || project.architect;
121-
if (!isJsonObject(targets)) {
122-
continue;
123-
}
54+
for (const [, target] of project.targets) {
55+
if (target.builder !== Builders.Browser) {
56+
continue;
57+
}
58+
59+
const optionPolyfills = target.options?.polyfills;
60+
if (optionPolyfills && typeof optionPolyfills === 'string') {
61+
rules.push((tree) => _removeReflectFromPolyfills(tree, optionPolyfills));
62+
}
63+
64+
if (!target.configurations) {
65+
continue;
66+
}
12467

125-
for (const targetName of Object.keys(targets)) {
126-
const target = targets[targetName];
127-
if (isJsonObject(target)) {
128-
rules.push(_updateProjectTarget(target));
68+
for (const configuration of Object.values(target.configurations)) {
69+
const configurationPolyfills = configuration?.polyfills;
70+
if (configurationPolyfills && typeof configurationPolyfills === 'string') {
71+
rules.push((tree) => _removeReflectFromPolyfills(tree, configurationPolyfills));
72+
}
12973
}
13074
}
13175
}
13276

133-
// Remove null or undefined rules.
13477
return chain(rules);
13578
};
13679
}

0 commit comments

Comments
 (0)