From 47afd4b0e7774a51c6963926fb24b13372131ce4 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 16 May 2019 11:03:36 +0200 Subject: [PATCH] fix(@schematics/angular): update or add module and target to non extended tsconfig Fixes #14436 --- .../update-8/differential-loading.ts | 86 ++++++++----------- .../update-8/differential-loading_spec.ts | 53 ++++++++++-- 2 files changed, 81 insertions(+), 58 deletions(-) diff --git a/packages/schematics/angular/migrations/update-8/differential-loading.ts b/packages/schematics/angular/migrations/update-8/differential-loading.ts index ff565c60d29d..620a34bedba2 100644 --- a/packages/schematics/angular/migrations/update-8/differential-loading.ts +++ b/packages/schematics/angular/migrations/update-8/differential-loading.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ import { - JsonAstObject, JsonParseMode, isJsonObject, join, @@ -36,40 +35,10 @@ not dead not IE 9-11 # For IE 9-11 support, remove 'not'.`; export function updateES5Projects(): Rule { - return (host: Tree) => { - const tsConfigPath = '/tsconfig.json'; - const compilerOptions = getCompilerOptionsAstObject(host, tsConfigPath); - if (!compilerOptions) { - return host; - } - - const recorder = host.beginUpdate(tsConfigPath); - const scriptTarget = findPropertyInAstObject(compilerOptions, 'target'); - if (!scriptTarget) { - insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'target', 'es2015', 4); - } else if (scriptTarget.value !== 'es2015') { - const { start, end } = scriptTarget; - recorder.remove(start.offset, end.offset - start.offset); - recorder.insertLeft(start.offset, '"es2015"'); - } - - const scriptModule = findPropertyInAstObject(compilerOptions, 'module'); - if (!scriptModule) { - insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'module', 'esnext', 4); - } else if (scriptModule.value !== 'esnext') { - const { start, end } = scriptModule; - recorder.remove(start.offset, end.offset - start.offset); - recorder.insertLeft(start.offset, '"esnext"'); - } - - host.commitUpdate(recorder); - - return updateProjects; - }; -} + return (tree: Tree) => { + // update workspace tsconfig + updateTsConfig(tree, '/tsconfig.json'); -function updateProjects(): Rule { - return (tree) => { const angularConfigContent = tree.read('angular.json') || tree.read('.angular.json'); if (!angularConfigContent) { @@ -106,28 +75,16 @@ function updateProjects(): Rule { continue; } - const tsConfigs = []; const buildOptionsConfig = architect.build.options; if (isJsonObject(buildOptionsConfig) && typeof buildOptionsConfig.tsConfig === 'string') { - tsConfigs.push(buildOptionsConfig.tsConfig); + updateTsConfig(tree, buildOptionsConfig.tsConfig); } const testConfig = architect.test; if (isJsonObject(testConfig) && isJsonObject(testConfig.options) && typeof testConfig.options.tsConfig === 'string') { - tsConfigs.push(testConfig.options.tsConfig); - } - - for (const tsConfig of tsConfigs) { - const compilerOptions = getCompilerOptionsAstObject(tree, tsConfig); - if (!compilerOptions) { - continue; - } - const recorder = tree.beginUpdate(tsConfig); - removePropertyInAstObject(recorder, compilerOptions, 'target'); - removePropertyInAstObject(recorder, compilerOptions, 'module'); - tree.commitUpdate(recorder); + updateTsConfig(tree, testConfig.options.tsConfig); } const browserslistPath = join(normalize(project.root), 'browserslist'); @@ -159,8 +116,8 @@ function updateProjects(): Rule { }; } -function getCompilerOptionsAstObject(host: Tree, tsConfigPath: string): JsonAstObject | undefined { - const buffer = host.read(tsConfigPath); +function updateTsConfig(tree: Tree, tsConfigPath: string): void { + const buffer = tree.read(tsConfigPath); if (!buffer) { return; } @@ -171,10 +128,37 @@ function getCompilerOptionsAstObject(host: Tree, tsConfigPath: string): JsonAstO return; } + const configExtends = findPropertyInAstObject(tsCfgAst, 'extends'); + const isExtendedConfig = configExtends && configExtends.kind === 'string'; + const compilerOptions = findPropertyInAstObject(tsCfgAst, 'compilerOptions'); if (!compilerOptions || compilerOptions.kind !== 'object') { return; } - return compilerOptions; + const recorder = tree.beginUpdate(tsConfigPath); + + if (isExtendedConfig) { + removePropertyInAstObject(recorder, compilerOptions, 'target'); + removePropertyInAstObject(recorder, compilerOptions, 'module'); + } else { + const scriptTarget = findPropertyInAstObject(compilerOptions, 'target'); + if (!scriptTarget) { + insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'target', 'es2015', 4); + } else if (scriptTarget.value !== 'es2015') { + const { start, end } = scriptTarget; + recorder.remove(start.offset, end.offset - start.offset); + recorder.insertLeft(start.offset, '"es2015"'); + } + const scriptModule = findPropertyInAstObject(compilerOptions, 'module'); + if (!scriptModule) { + insertPropertyInAstObjectInOrder(recorder, compilerOptions, 'module', 'esnext', 4); + } else if (scriptModule.value !== 'esnext') { + const { start, end } = scriptModule; + recorder.remove(start.offset, end.offset - start.offset); + recorder.insertLeft(start.offset, '"esnext"'); + } + } + + tree.commitUpdate(recorder); } diff --git a/packages/schematics/angular/migrations/update-8/differential-loading_spec.ts b/packages/schematics/angular/migrations/update-8/differential-loading_spec.ts index 92ddab277791..4dfdf6347ca5 100644 --- a/packages/schematics/angular/migrations/update-8/differential-loading_spec.ts +++ b/packages/schematics/angular/migrations/update-8/differential-loading_spec.ts @@ -93,16 +93,21 @@ describe('Migration to version 8', () => { expect(tree2.exists('/browserslist')).toBe(true); }); - it(`should remove 'target' and 'module' from non workspace tsconfig.json`, () => { + it(`should remove 'target' and 'module' from non workspace extended tsconfig.json`, () => { const appTsConfig = '/tsconfig.app.json'; const specsTsConfig = '/tsconfig.spec.json'; - const compilerOptions = { - ...oldTsConfig.compilerOptions, - target: 'es2015', - module: 'es2015', - }; + const tsConfig = JSON.stringify({ + extends: '../../tsconfig.json', + compilerOptions: { + moduleResolution: 'node', + target: 'es2015', + module: 'es2015', + }, + }, null, 2); + + tree.overwrite(appTsConfig, tsConfig); + tree.overwrite(specsTsConfig, tsConfig); - tree.overwrite(appTsConfig, JSON.stringify({ compilerOptions }, null, 2)); const tree2 = schematicRunner.runSchematic('migration-07', {}, tree.branch()); const { compilerOptions: appCompilerOptions } = JSON.parse(tree2.readContent(appTsConfig)); expect(appCompilerOptions.target).toBeUndefined(); @@ -114,6 +119,40 @@ describe('Migration to version 8', () => { expect(specsCompilerOptions.module).toBeUndefined(); }); + it(`should update 'target' and 'module' to non workspace non-extended tsconfig.json`, () => { + const appTsConfig = '/tsconfig.app.json'; + const tsConfig = JSON.stringify({ + compilerOptions: { + moduleResolution: 'node', + target: 'es5', + module: 'es5', + }, + }, null, 2); + + tree.overwrite(appTsConfig, tsConfig); + + const tree2 = schematicRunner.runSchematic('migration-07', {}, tree.branch()); + const { compilerOptions: appCompilerOptions } = JSON.parse(tree2.readContent(appTsConfig)); + expect(appCompilerOptions.target).toBe('es2015'); + expect(appCompilerOptions.module).toBe('esnext'); + }); + + it(`should add 'target' and 'module' to non workspace non-extended tsconfig.json`, () => { + const appTsConfig = '/tsconfig.app.json'; + const tsConfig = JSON.stringify({ + compilerOptions: { + moduleResolution: 'node', + }, + }, null, 2); + + tree.overwrite(appTsConfig, tsConfig); + + const tree2 = schematicRunner.runSchematic('migration-07', {}, tree.branch()); + const { compilerOptions: appCompilerOptions } = JSON.parse(tree2.readContent(appTsConfig)); + expect(appCompilerOptions.target).toBe('es2015'); + expect(appCompilerOptions.module).toBe('esnext'); + }); + it(`should not update projects which browser builder is not 'build-angular:browser'`, () => { tree.delete('/browserslist'); const config = JSON.parse(tree.readContent('angular.json'));