From 9b163eef1d7b4ec8d57f82c64eaf60fc6618fb2a Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 15 Jun 2018 14:53:53 +0200 Subject: [PATCH 1/2] fix(@schematics/angular): add `baseUrl` in root tsconfig when migrating Closes: #11258 --- .../angular/migrations/update-6/index.ts | 40 +++++++++++++++++++ .../angular/migrations/update-6/index_spec.ts | 21 ++++++++++ 2 files changed, 61 insertions(+) diff --git a/packages/schematics/angular/migrations/update-6/index.ts b/packages/schematics/angular/migrations/update-6/index.ts index a6cf7c0c32a5..ab829d5f44fc 100644 --- a/packages/schematics/angular/migrations/update-6/index.ts +++ b/packages/schematics/angular/migrations/update-6/index.ts @@ -32,6 +32,7 @@ import { addPackageJsonDependency, } from '../../utility/dependencies'; import { + appendPropertyInAstObject, appendValueInAstArray, findPropertyInAstObject, } from '../../utility/json-utils'; @@ -724,6 +725,44 @@ function updateTsLintConfig(): Rule { }; } +function updateRootTsConfig(): Rule { + return (host: Tree, context: SchematicContext) => { + const tsConfigPath = '/tsconfig.json'; + const buffer = host.read(tsConfigPath); + if (!buffer) { + return; + } + + const tsCfgAst = parseJsonAst(buffer.toString(), JsonParseMode.Loose); + if (tsCfgAst.kind != 'object') { + throw new SchematicsException( + 'Invalid tsconfig. Was expecting an object' + ); + } + + const compilerOptionsAstNode = findPropertyInAstObject(tsCfgAst, 'compilerOptions'); + if (!compilerOptionsAstNode || compilerOptionsAstNode.kind != 'object') { + throw new SchematicsException('Invalid tsconfig "compilerOptions" property; expected an object.'); + } + + if (findPropertyInAstObject(compilerOptionsAstNode, 'baseUrl')) { + return host; + } + + const recorder = host.beginUpdate(tsConfigPath); + appendPropertyInAstObject( + recorder, + compilerOptionsAstNode, + 'baseUrl', + './', + 4, + ); + + host.commitUpdate(recorder); + return host; + }; +} + export default function (): Rule { return (host: Tree, context: SchematicContext) => { if (host.exists('/.angular.json') || host.exists('/angular.json')) { @@ -748,6 +787,7 @@ export default function (): Rule { migrateConfiguration(config, context.logger), updateSpecTsConfig(config), updatePackageJson(config), + updateRootTsConfig(), updateTsLintConfig(), (host: Tree, context: SchematicContext) => { context.logger.warn(tags.oneLine`Some configuration options have been changed, diff --git a/packages/schematics/angular/migrations/update-6/index_spec.ts b/packages/schematics/angular/migrations/update-6/index_spec.ts index 12b430cb5ca4..118670b21514 100644 --- a/packages/schematics/angular/migrations/update-6/index_spec.ts +++ b/packages/schematics/angular/migrations/update-6/index_spec.ts @@ -775,6 +775,27 @@ describe('Migration to v6', () => { }); }); + describe('root ts config', () => { + const rootTsConfig = '/tsconfig.json'; + beforeEach(() => { + tree.create(rootTsConfig, ` + { + "compilerOptions": { + "module": "es2015" + } + } + `); + }); + + it('should add baseUrl', () => { + tree.create(oldConfigPath, JSON.stringify(baseConfig, null, 2)); + tree = schematicRunner.runSchematic('migration-01', defaultOptions, tree); + const content = tree.readContent(rootTsConfig); + const config = JSON.parse(content); + expect(config.compilerOptions.baseUrl).toEqual('./'); + }); + }); + describe('package.json', () => { it('should add a dev dependency to @angular-devkit/build-angular', () => { tree.create(oldConfigPath, JSON.stringify(baseConfig, null, 2)); From 2883d0df65ea759f742ccc361f60f03a7fd22ee7 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 18 Jun 2018 09:20:51 +0200 Subject: [PATCH 2/2] fix(@schematics/angular): add `module` in root tsconfig when migrating --- .../angular/migrations/update-6/index.ts | 47 ++++++++++++------- .../angular/migrations/update-6/index_spec.ts | 21 +++++++-- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/packages/schematics/angular/migrations/update-6/index.ts b/packages/schematics/angular/migrations/update-6/index.ts index ab829d5f44fc..27e74d77ce1c 100644 --- a/packages/schematics/angular/migrations/update-6/index.ts +++ b/packages/schematics/angular/migrations/update-6/index.ts @@ -32,7 +32,6 @@ import { addPackageJsonDependency, } from '../../utility/dependencies'; import { - appendPropertyInAstObject, appendValueInAstArray, findPropertyInAstObject, } from '../../utility/json-utils'; @@ -734,31 +733,47 @@ function updateRootTsConfig(): Rule { } const tsCfgAst = parseJsonAst(buffer.toString(), JsonParseMode.Loose); - if (tsCfgAst.kind != 'object') { - throw new SchematicsException( - 'Invalid tsconfig. Was expecting an object' - ); + if (tsCfgAst.kind !== 'object') { + throw new SchematicsException('Invalid root tsconfig. Was expecting an object'); } const compilerOptionsAstNode = findPropertyInAstObject(tsCfgAst, 'compilerOptions'); if (!compilerOptionsAstNode || compilerOptionsAstNode.kind != 'object') { - throw new SchematicsException('Invalid tsconfig "compilerOptions" property; expected an object.'); + throw new SchematicsException( + 'Invalid root tsconfig "compilerOptions" property; expected an object.', + ); } - if (findPropertyInAstObject(compilerOptionsAstNode, 'baseUrl')) { + if ( + findPropertyInAstObject(compilerOptionsAstNode, 'baseUrl') && + findPropertyInAstObject(compilerOptionsAstNode, 'module') + ) { return host; } - const recorder = host.beginUpdate(tsConfigPath); - appendPropertyInAstObject( - recorder, - compilerOptionsAstNode, - 'baseUrl', - './', - 4, - ); + const compilerOptions = compilerOptionsAstNode.value; + const { baseUrl = './', module = 'es2015'} = compilerOptions; + + const validBaseUrl = ['./', '', '.']; + if (!validBaseUrl.includes(baseUrl as string)) { + const formattedBaseUrl = validBaseUrl.map(x => `'${x}'`).join(', '); + context.logger.warn(tags.oneLine + `Root tsconfig option 'baseUrl' is not one of: ${formattedBaseUrl}. + This might cause unexpected behaviour when generating libraries.`, + ); + } + + if (module !== 'es2015') { + context.logger.warn( + `Root tsconfig option 'module' is not 'es2015'. This might cause unexpected behaviour.`, + ); + } + + compilerOptions.module = module; + compilerOptions.baseUrl = baseUrl; + + host.overwrite(tsConfigPath, JSON.stringify(tsCfgAst.value, null, 2)); - host.commitUpdate(recorder); return host; }; } diff --git a/packages/schematics/angular/migrations/update-6/index_spec.ts b/packages/schematics/angular/migrations/update-6/index_spec.ts index 118670b21514..d2627791ee08 100644 --- a/packages/schematics/angular/migrations/update-6/index_spec.ts +++ b/packages/schematics/angular/migrations/update-6/index_spec.ts @@ -777,22 +777,33 @@ describe('Migration to v6', () => { describe('root ts config', () => { const rootTsConfig = '/tsconfig.json'; + let compilerOptions: JsonObject; + beforeEach(() => { tree.create(rootTsConfig, ` { "compilerOptions": { - "module": "es2015" + "noEmitOnError": true } } `); - }); - it('should add baseUrl', () => { tree.create(oldConfigPath, JSON.stringify(baseConfig, null, 2)); tree = schematicRunner.runSchematic('migration-01', defaultOptions, tree); const content = tree.readContent(rootTsConfig); - const config = JSON.parse(content); - expect(config.compilerOptions.baseUrl).toEqual('./'); + compilerOptions = JSON.parse(content).compilerOptions; + }); + + it('should add baseUrl', () => { + expect(compilerOptions.baseUrl).toEqual('./'); + }); + + it('should add module', () => { + expect(compilerOptions.module).toEqual('es2015'); + }); + + it('should not remove existing options', () => { + expect(compilerOptions.noEmitOnError).toBeDefined(); }); });