Skip to content

Commit 4e693ef

Browse files
Alan Agiusmgechev
Alan Agius
authored andcommitted
fix(@schematics/angular): update or add module and target to non extended tsconfig
Fixes #14436
1 parent 7e0e981 commit 4e693ef

File tree

2 files changed

+81
-58
lines changed

2 files changed

+81
-58
lines changed

packages/schematics/angular/migrations/update-8/differential-loading.ts

+35-51
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import {
9-
JsonAstObject,
109
JsonParseMode,
1110
isJsonObject,
1211
join,
@@ -36,40 +35,10 @@ not dead
3635
not IE 9-11 # For IE 9-11 support, remove 'not'.`;
3736

3837
export function updateES5Projects(): Rule {
39-
return (host: Tree) => {
40-
const tsConfigPath = '/tsconfig.json';
41-
const compilerOptions = getCompilerOptionsAstObject(host, tsConfigPath);
42-
if (!compilerOptions) {
43-
return host;
44-
}
45-
46-
const recorder = host.beginUpdate(tsConfigPath);
47-
const scriptTarget = findPropertyInAstObject(compilerOptions, 'target');
48-
if (!scriptTarget) {
49-
insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'target', 'es2015', 4);
50-
} else if (scriptTarget.value !== 'es2015') {
51-
const { start, end } = scriptTarget;
52-
recorder.remove(start.offset, end.offset - start.offset);
53-
recorder.insertLeft(start.offset, '"es2015"');
54-
}
55-
56-
const scriptModule = findPropertyInAstObject(compilerOptions, 'module');
57-
if (!scriptModule) {
58-
insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'module', 'esnext', 4);
59-
} else if (scriptModule.value !== 'esnext') {
60-
const { start, end } = scriptModule;
61-
recorder.remove(start.offset, end.offset - start.offset);
62-
recorder.insertLeft(start.offset, '"esnext"');
63-
}
64-
65-
host.commitUpdate(recorder);
66-
67-
return updateProjects;
68-
};
69-
}
38+
return (tree: Tree) => {
39+
// update workspace tsconfig
40+
updateTsConfig(tree, '/tsconfig.json');
7041

71-
function updateProjects(): Rule {
72-
return (tree) => {
7342
const angularConfigContent = tree.read('angular.json') || tree.read('.angular.json');
7443

7544
if (!angularConfigContent) {
@@ -106,28 +75,16 @@ function updateProjects(): Rule {
10675
continue;
10776
}
10877

109-
const tsConfigs = [];
11078
const buildOptionsConfig = architect.build.options;
11179
if (isJsonObject(buildOptionsConfig) && typeof buildOptionsConfig.tsConfig === 'string') {
112-
tsConfigs.push(buildOptionsConfig.tsConfig);
80+
updateTsConfig(tree, buildOptionsConfig.tsConfig);
11381
}
11482

11583
const testConfig = architect.test;
11684
if (isJsonObject(testConfig)
11785
&& isJsonObject(testConfig.options)
11886
&& typeof testConfig.options.tsConfig === 'string') {
119-
tsConfigs.push(testConfig.options.tsConfig);
120-
}
121-
122-
for (const tsConfig of tsConfigs) {
123-
const compilerOptions = getCompilerOptionsAstObject(tree, tsConfig);
124-
if (!compilerOptions) {
125-
continue;
126-
}
127-
const recorder = tree.beginUpdate(tsConfig);
128-
removePropertyInAstObject(recorder, compilerOptions, 'target');
129-
removePropertyInAstObject(recorder, compilerOptions, 'module');
130-
tree.commitUpdate(recorder);
87+
updateTsConfig(tree, testConfig.options.tsConfig);
13188
}
13289

13390
const browserslistPath = join(normalize(project.root), 'browserslist');
@@ -159,8 +116,8 @@ function updateProjects(): Rule {
159116
};
160117
}
161118

162-
function getCompilerOptionsAstObject(host: Tree, tsConfigPath: string): JsonAstObject | undefined {
163-
const buffer = host.read(tsConfigPath);
119+
function updateTsConfig(tree: Tree, tsConfigPath: string): void {
120+
const buffer = tree.read(tsConfigPath);
164121
if (!buffer) {
165122
return;
166123
}
@@ -171,10 +128,37 @@ function getCompilerOptionsAstObject(host: Tree, tsConfigPath: string): JsonAstO
171128
return;
172129
}
173130

131+
const configExtends = findPropertyInAstObject(tsCfgAst, 'extends');
132+
const isExtendedConfig = configExtends && configExtends.kind === 'string';
133+
174134
const compilerOptions = findPropertyInAstObject(tsCfgAst, 'compilerOptions');
175135
if (!compilerOptions || compilerOptions.kind !== 'object') {
176136
return;
177137
}
178138

179-
return compilerOptions;
139+
const recorder = tree.beginUpdate(tsConfigPath);
140+
141+
if (isExtendedConfig) {
142+
removePropertyInAstObject(recorder, compilerOptions, 'target');
143+
removePropertyInAstObject(recorder, compilerOptions, 'module');
144+
} else {
145+
const scriptTarget = findPropertyInAstObject(compilerOptions, 'target');
146+
if (!scriptTarget) {
147+
insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'target', 'es2015', 4);
148+
} else if (scriptTarget.value !== 'es2015') {
149+
const { start, end } = scriptTarget;
150+
recorder.remove(start.offset, end.offset - start.offset);
151+
recorder.insertLeft(start.offset, '"es2015"');
152+
}
153+
const scriptModule = findPropertyInAstObject(compilerOptions, 'module');
154+
if (!scriptModule) {
155+
insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'module', 'esnext', 4);
156+
} else if (scriptModule.value !== 'esnext') {
157+
const { start, end } = scriptModule;
158+
recorder.remove(start.offset, end.offset - start.offset);
159+
recorder.insertLeft(start.offset, '"esnext"');
160+
}
161+
}
162+
163+
tree.commitUpdate(recorder);
180164
}

packages/schematics/angular/migrations/update-8/differential-loading_spec.ts

+46-7
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,21 @@ describe('Migration to version 8', () => {
9393
expect(tree2.exists('/browserslist')).toBe(true);
9494
});
9595

96-
it(`should remove 'target' and 'module' from non workspace tsconfig.json`, () => {
96+
it(`should remove 'target' and 'module' from non workspace extended tsconfig.json`, () => {
9797
const appTsConfig = '/tsconfig.app.json';
9898
const specsTsConfig = '/tsconfig.spec.json';
99-
const compilerOptions = {
100-
...oldTsConfig.compilerOptions,
101-
target: 'es2015',
102-
module: 'es2015',
103-
};
99+
const tsConfig = JSON.stringify({
100+
extends: '../../tsconfig.json',
101+
compilerOptions: {
102+
moduleResolution: 'node',
103+
target: 'es2015',
104+
module: 'es2015',
105+
},
106+
}, null, 2);
107+
108+
tree.overwrite(appTsConfig, tsConfig);
109+
tree.overwrite(specsTsConfig, tsConfig);
104110

105-
tree.overwrite(appTsConfig, JSON.stringify({ compilerOptions }, null, 2));
106111
const tree2 = schematicRunner.runSchematic('migration-07', {}, tree.branch());
107112
const { compilerOptions: appCompilerOptions } = JSON.parse(tree2.readContent(appTsConfig));
108113
expect(appCompilerOptions.target).toBeUndefined();
@@ -114,6 +119,40 @@ describe('Migration to version 8', () => {
114119
expect(specsCompilerOptions.module).toBeUndefined();
115120
});
116121

122+
it(`should update 'target' and 'module' to non workspace non-extended tsconfig.json`, () => {
123+
const appTsConfig = '/tsconfig.app.json';
124+
const tsConfig = JSON.stringify({
125+
compilerOptions: {
126+
moduleResolution: 'node',
127+
target: 'es5',
128+
module: 'es5',
129+
},
130+
}, null, 2);
131+
132+
tree.overwrite(appTsConfig, tsConfig);
133+
134+
const tree2 = schematicRunner.runSchematic('migration-07', {}, tree.branch());
135+
const { compilerOptions: appCompilerOptions } = JSON.parse(tree2.readContent(appTsConfig));
136+
expect(appCompilerOptions.target).toBe('es2015');
137+
expect(appCompilerOptions.module).toBe('esnext');
138+
});
139+
140+
it(`should add 'target' and 'module' to non workspace non-extended tsconfig.json`, () => {
141+
const appTsConfig = '/tsconfig.app.json';
142+
const tsConfig = JSON.stringify({
143+
compilerOptions: {
144+
moduleResolution: 'node',
145+
},
146+
}, null, 2);
147+
148+
tree.overwrite(appTsConfig, tsConfig);
149+
150+
const tree2 = schematicRunner.runSchematic('migration-07', {}, tree.branch());
151+
const { compilerOptions: appCompilerOptions } = JSON.parse(tree2.readContent(appTsConfig));
152+
expect(appCompilerOptions.target).toBe('es2015');
153+
expect(appCompilerOptions.module).toBe('esnext');
154+
});
155+
117156
it(`should not update projects which browser builder is not 'build-angular:browser'`, () => {
118157
tree.delete('/browserslist');
119158
const config = JSON.parse(tree.readContent('angular.json'));

0 commit comments

Comments
 (0)