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();