From 8b1c1f50fe485b24e6e00d0be6281dc3e85048ee Mon Sep 17 00:00:00 2001 From: Alan Date: Mon, 22 Jul 2019 14:37:05 +0200 Subject: [PATCH] fix(@ngtools/webpack): delete all virtual files for styles on change Fixes #15143 --- .../test/browser/rebuild_spec_large.ts | 66 ++++++++++++++++++- packages/ngtools/webpack/src/compiler_host.ts | 20 +++++- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts index 50b4ed03381e..a128523a5b22 100644 --- a/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts +++ b/packages/angular_devkit/build_angular/test/browser/rebuild_spec_large.ts @@ -8,14 +8,16 @@ // tslint:disable:no-big-function import { Architect } from '@angular-devkit/architect'; import { TestLogger } from '@angular-devkit/architect/testing'; -import { logging, normalize, virtualFs } from '@angular-devkit/core'; +import { join, logging, normalize, virtualFs } from '@angular-devkit/core'; import { debounceTime, take, takeWhile, tap } from 'rxjs/operators'; import { createArchitect, host, ivyEnabled, lazyModuleFiles, - lazyModuleStringImport, + lazyModuleFnImport, + lazyModuleStringImport, + outputPath, } from '../utils'; describe('Browser Builder rebuilds', () => { @@ -477,4 +479,64 @@ describe('Browser Builder rebuilds', () => { .toPromise(); await run.stop(); }); + + it('rebuilds AOT on CSS changes', async () => { + const overrides = { watch: true, aot: true }; + + let buildCount = 1; + const run = await architect.scheduleTarget(target, overrides); + await run.output.pipe( + debounceTime(1000), + tap(() => { + const content = virtualFs.fileBufferToString( + host.scopedSync().read(join(outputPath, 'main.js')), + ); + + switch (buildCount) { + case 1: + expect(content).not.toContain('color: green'); + host.appendToFile('src/app/app.component.css', 'h1 { color: green; }'); + break; + case 2: + expect(content).toContain('color: green'); + break; + } + + buildCount++; + }), + tap((buildEvent) => expect(buildEvent.success).toBe(true)), + take(2), + ).toPromise(); + await run.stop(); + }); + + it('rebuilds AOT on HTML changes', async () => { + const overrides = { watch: true, aot: true }; + + let buildCount = 1; + const run = await architect.scheduleTarget(target, overrides); + await run.output.pipe( + debounceTime(1000), + tap(() => { + const content = virtualFs.fileBufferToString( + host.scopedSync().read(join(outputPath, 'main.js')), + ); + + switch (buildCount) { + case 1: + expect(content).not.toContain('New Updated Content'); + host.appendToFile('src/app/app.component.html', 'New Updated Content'); + break; + case 2: + expect(content).toContain('New Updated Content'); + break; + } + + buildCount++; + }), + tap((buildEvent) => expect(buildEvent.success).toBe(true)), + take(2), + ).toPromise(); + await run.stop(); + }); }); diff --git a/packages/ngtools/webpack/src/compiler_host.ts b/packages/ngtools/webpack/src/compiler_host.ts index 5653905b7fea..915b94454dc4 100644 --- a/packages/ngtools/webpack/src/compiler_host.ts +++ b/packages/ngtools/webpack/src/compiler_host.ts @@ -31,11 +31,14 @@ export class WebpackCompilerHost implements ts.CompilerHost { '.js.map', '.ngfactory.js', '.ngfactory.js.map', - '.ngstyle.js', - '.ngstyle.js.map', '.ngsummary.json', ]; + private _virtualStyleFileExtensions = [ + '.shim.ngstyle.js', + '.shim.ngstyle.js.map', + ]; + constructor( private _options: ts.CompilerOptions, basePath: string, @@ -110,6 +113,10 @@ export class WebpackCompilerHost implements ts.CompilerHost { }); } + if (fullPath.endsWith('.ts')) { + return; + } + // In case resolveJsonModule and allowJs we also need to remove virtual emitted files // both if they exists or not. if ( @@ -119,6 +126,15 @@ export class WebpackCompilerHost implements ts.CompilerHost { if (this._memoryHost.exists(fullPath)) { this._memoryHost.delete(fullPath); } + + return; + } + + for (const ext of this._virtualStyleFileExtensions) { + const virtualFile = (fullPath + ext) as Path; + if (this._memoryHost.exists(virtualFile)) { + this._memoryHost.delete(virtualFile); + } } }