diff --git a/packages/angular_devkit/build_angular/src/utils/normalize-asset-patterns.ts b/packages/angular_devkit/build_angular/src/utils/normalize-asset-patterns.ts index 27d2d9d995..faf66dac43 100644 --- a/packages/angular_devkit/build_angular/src/utils/normalize-asset-patterns.ts +++ b/packages/angular_devkit/build_angular/src/utils/normalize-asset-patterns.ts @@ -38,6 +38,13 @@ export function normalizeAssetPatterns( const sourceRoot = maybeSourceRoot || join(projectRoot, 'src'); const resolvedSourceRoot = resolve(root, sourceRoot); + if (assetPatterns.length === 0) { + // If there are no asset patterns, return an empty array. + // It's important to do this because forkJoin with an empty array will immediately complete + // the observable. + return of([]); + } + const assetPatternObjectObservables: Observable[] = assetPatterns .map(assetPattern => { // Normalize string asset patterns to objects. diff --git a/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts index 183973b822..fbc5c3255e 100644 --- a/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts +++ b/packages/angular_devkit/build_angular/test/browser/assets_spec_large.ts @@ -7,7 +7,7 @@ */ import { normalize, virtualFs } from '@angular-devkit/core'; -import { tap } from 'rxjs/operators'; +import { tap, toArray } from 'rxjs/operators'; import { Timeout, browserTargetSpec, host, runTargetSpec } from '../utils'; @@ -91,4 +91,15 @@ describe('Browser Builder assets', () => { // node_modules folder will hit this one and can fail. host.scopedSync().delete(normalize('./node_modules')); }, Timeout.Basic); + + it('still builds with empty asset array', (done) => { + const overrides = { + assets: [], + }; + + runTargetSpec(host, browserTargetSpec, overrides).pipe( + toArray(), + tap((buildEvents) => expect(buildEvents.length).toBe(1)), + ).subscribe(undefined, done.fail, done); + }, Timeout.Basic); });