From 081f3095ef06267b9408422e2cd948a2b52598d7 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Sun, 3 Nov 2019 13:33:25 +0100 Subject: [PATCH 1/2] fix(@schematics/angular): replace `'**/*.ts` file inclusion with `**/*.d.ts` This fixes warnings such as the below; ``` WARNING in /test-update/src/environments/environment.prod.ts is part of the TypeScript compilation but it's unused. Add only entry points to the 'files' or 'include' properties in your tsconfig. ``` When the previous generated add was in VE. --- .../update-9/update-app-tsconfigs.ts | 37 +++++++++++-------- .../update-9/update-app-tsconfigs_spec.ts | 35 +++++++++++++++++- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts index 99c56a37a8fd..7d1645909189 100644 --- a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts +++ b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts @@ -74,6 +74,8 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B } // Add stricter file inclusions to avoid unused file warning during compilation + const rootInSrc = tsConfigPath.includes('src/'); + const rootSrc = rootInSrc ? '' : 'src/'; if (builderName !== Builders.Karma) { // Note: we need to re-read the tsconfig after very commit because // otherwise the updates will be out of sync since we are ammending the same node. @@ -81,26 +83,29 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B const files = findPropertyInAstObject(tsConfigAst, 'files'); const include = findPropertyInAstObject(tsConfigAst, 'include'); - if (!files && !include) { - const rootInSrc = tsConfigPath.includes('src/'); - const rootSrc = rootInSrc ? '' : 'src/'; - const files = builderName === Builders.Server - ? [`${rootSrc}main.server.ts`] - : [`${rootSrc}main.ts`, `${rootSrc}polyfills.ts`]; - - recorder = tree.beginUpdate(tsConfigPath); - insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'files', files, 2); - tree.commitUpdate(recorder); - - if (builderName === Builders.Browser) { - tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath); - recorder = tree.beginUpdate(tsConfigPath); - insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'include', [`${rootSrc}**/*.d.ts`], 2); - tree.commitUpdate(recorder); + recorder = tree.beginUpdate(tsConfigPath); + if (include && include.kind === 'array') { + const tsInclude = include.elements.find(({ value }) => typeof value === 'string' && value.endsWith('**/*.ts')); + if (tsInclude) { + const { start, end } = tsInclude; + recorder.remove(start.offset, end.offset - start.offset); + // Replace ts includes with d.ts + recorder.insertLeft(start.offset, tsInclude.text.replace('.ts', '.d.ts')); } + } else { + insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'include', [`${rootSrc}**/*.d.ts`], 2); + } + + tree.commitUpdate(recorder); + if (!files) { tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath); recorder = tree.beginUpdate(tsConfigPath); + + const files = builderName === Builders.Server + ? [`${rootSrc}main.server.ts`] + : [`${rootSrc}main.ts`, `${rootSrc}polyfills.ts`]; + insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'files', files, 2); removePropertyInAstObject(recorder, tsConfigAst, 'exclude'); tree.commitUpdate(recorder); } diff --git a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts index 1655d9badce6..4cdf76388c2b 100644 --- a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts +++ b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts @@ -64,7 +64,7 @@ describe('Migration to version 9', () => { expect(include).toEqual(['src/**/*.d.ts']); }); - it('should not update apps tsConfig when tsconfig has include', async () => { + it('should update apps tsConfig when tsconfig has include', async () => { const tsConfigContent = { ...defaultTsConfigOptions, include: ['foo.ts'], @@ -74,10 +74,41 @@ describe('Migration to version 9', () => { const tree2 = await schematicRunner.runSchematicAsync('migration-09', {}, tree.branch()).toPromise(); const { files, include } = JSON.parse(tree2.readContent('tsconfig.app.json')); - expect(files).toEqual(undefined); + expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']); expect(include).toEqual(['foo.ts']); }); + it(`should update include '**/*.ts' in apps tsConfig to '**/*.d.ts'`, async () => { + const tsConfigContent = { + ...defaultTsConfigOptions, + include: ['src/**/*.ts'], + exclude: ['test.ts'], + }; + + overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent); + + const tree2 = await schematicRunner.runSchematicAsync('migration-09', {}, tree.branch()).toPromise(); + const { files, include, exclude } = JSON.parse(tree2.readContent('tsconfig.app.json')); + expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']); + expect(include).toEqual(['src/**/*.d.ts']); + expect(exclude).toBeUndefined(); + }); + + it(`should update include '**/*.ts' in apps tsConfig to '**/*.d.ts' when includes contains multiple elements`, async () => { + const tsConfigContent = { + ...defaultTsConfigOptions, + include: ['foo.ts', 'src/**/*.ts'], + }; + + overrideJsonFile(tree, 'tsconfig.app.json', tsConfigContent); + + const tree2 = await schematicRunner.runSchematicAsync('migration-09', {}, tree.branch()).toPromise(); + const { files, include, exclude } = JSON.parse(tree2.readContent('tsconfig.app.json')); + expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']); + expect(include).toEqual(['foo.ts', 'src/**/*.d.ts']); + expect(exclude).toBeUndefined(); + }); + it(`should remove angularCompilerOptions when enableIvy is true and it's the only option`, async () => { overrideJsonFile(tree, 'tsconfig.app.json', defaultTsConfigOptions); const tree2 = await schematicRunner.runSchematicAsync('migration-09', {}, tree.branch()).toPromise(); From 8c5e71b2754a7f1aa957ced4ea37a1aebc0edce4 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Sun, 3 Nov 2019 13:41:27 +0100 Subject: [PATCH 2/2] fix(@schematics/angular): tsconfig creates invalid file references Fixes: #16035 --- .../update-9/update-app-tsconfigs.ts | 38 ++++++++++++------- .../update-9/update-app-tsconfigs_spec.ts | 3 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts index 7d1645909189..a3bf37cb7739 100644 --- a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts +++ b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs.ts @@ -7,6 +7,7 @@ */ import { JsonAstObject } from '@angular-devkit/core'; import { Rule, Tree, UpdateRecorder } from '@angular-devkit/schematics'; +import { posix } from 'path'; import { findPropertyInAstObject, insertPropertyInAstObjectInOrder, @@ -74,38 +75,47 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B } // Add stricter file inclusions to avoid unused file warning during compilation - const rootInSrc = tsConfigPath.includes('src/'); - const rootSrc = rootInSrc ? '' : 'src/'; if (builderName !== Builders.Karma) { // Note: we need to re-read the tsconfig after very commit because // otherwise the updates will be out of sync since we are ammending the same node. tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath); - const files = findPropertyInAstObject(tsConfigAst, 'files'); const include = findPropertyInAstObject(tsConfigAst, 'include'); - recorder = tree.beginUpdate(tsConfigPath); if (include && include.kind === 'array') { const tsInclude = include.elements.find(({ value }) => typeof value === 'string' && value.endsWith('**/*.ts')); if (tsInclude) { const { start, end } = tsInclude; + recorder = tree.beginUpdate(tsConfigPath); recorder.remove(start.offset, end.offset - start.offset); // Replace ts includes with d.ts recorder.insertLeft(start.offset, tsInclude.text.replace('.ts', '.d.ts')); + tree.commitUpdate(recorder); } - } else { - insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'include', [`${rootSrc}**/*.d.ts`], 2); } - tree.commitUpdate(recorder); - + const files = findPropertyInAstObject(tsConfigAst, 'files'); if (!files) { - tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath); - recorder = tree.beginUpdate(tsConfigPath); + const newFiles: string[] = []; + + const mainOption = findPropertyInAstObject(option, 'main'); + if (mainOption && mainOption.kind === 'string') { + newFiles.push(posix.relative(posix.dirname(tsConfigPath), mainOption.value)); + } - const files = builderName === Builders.Server - ? [`${rootSrc}main.server.ts`] - : [`${rootSrc}main.ts`, `${rootSrc}polyfills.ts`]; - insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'files', files, 2); + const polyfillsOption = findPropertyInAstObject(option, 'polyfills'); + if (polyfillsOption && polyfillsOption.kind === 'string') { + newFiles.push(posix.relative(posix.dirname(tsConfigPath), polyfillsOption.value)); + } + + if (newFiles.length) { + recorder = tree.beginUpdate(tsConfigPath); + tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath); + insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'files', newFiles, 2); + tree.commitUpdate(recorder); + } + + recorder = tree.beginUpdate(tsConfigPath); + tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath); removePropertyInAstObject(recorder, tsConfigAst, 'exclude'); tree.commitUpdate(recorder); } diff --git a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts index 4cdf76388c2b..83359f2778ca 100644 --- a/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts +++ b/packages/schematics/angular/migrations/update-9/update-app-tsconfigs_spec.ts @@ -58,10 +58,9 @@ describe('Migration to version 9', () => { it('should update apps tsConfig with stricter files inclusions', async () => { overrideJsonFile(tree, 'tsconfig.app.json', defaultTsConfigOptions); const tree2 = await schematicRunner.runSchematicAsync('migration-09', {}, tree.branch()).toPromise(); - const { exclude, files, include } = JSON.parse(tree2.readContent('tsconfig.app.json')); + const { exclude, files } = JSON.parse(tree2.readContent('tsconfig.app.json')); expect(exclude).toBeUndefined(); expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']); - expect(include).toEqual(['src/**/*.d.ts']); }); it('should update apps tsConfig when tsconfig has include', async () => {