mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-19 04:26:01 +08:00
fix(@angular-devkit/build-angular): run build steps for differential loading in sequence to avoid confusing progress information
Before, the build tasks ran in parallel and so the different webpack instances competed over the same lines on the console. To fail fast and to prevent to show the same errors twice, the second build step is not executed if the first one fails. As running these tasks in sequence causes issues with watch mode, this PR also disables differential loading when watch mode is requested.
This commit is contained in:
parent
4807ff00d1
commit
201856a5ec
@ -10,7 +10,7 @@ import {
|
|||||||
BuilderOutput,
|
BuilderOutput,
|
||||||
createBuilder,
|
createBuilder,
|
||||||
} from '@angular-devkit/architect';
|
} from '@angular-devkit/architect';
|
||||||
import { WebpackLoggingCallback, runWebpack } from '@angular-devkit/build-webpack';
|
import { BuildResult, WebpackLoggingCallback, runWebpack } from '@angular-devkit/build-webpack';
|
||||||
import {
|
import {
|
||||||
experimental,
|
experimental,
|
||||||
join,
|
join,
|
||||||
@ -23,8 +23,8 @@ import {
|
|||||||
import { NodeJsSyncHost } from '@angular-devkit/core/node';
|
import { NodeJsSyncHost } from '@angular-devkit/core/node';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { from, of, zip } from 'rxjs';
|
import { concat, from, of, zip } from 'rxjs';
|
||||||
import { catchError, concatMap, map, switchMap } from 'rxjs/operators';
|
import { bufferCount, catchError, concatMap, map, mergeScan, switchMap } from 'rxjs/operators';
|
||||||
import * as webpack from 'webpack';
|
import * as webpack from 'webpack';
|
||||||
import { NgBuildAnalyticsPlugin } from '../../plugins/webpack/analytics';
|
import { NgBuildAnalyticsPlugin } from '../../plugins/webpack/analytics';
|
||||||
import { WebpackConfigOptions } from '../angular-cli-files/models/build-options';
|
import { WebpackConfigOptions } from '../angular-cli-files/models/build-options';
|
||||||
@ -182,12 +182,18 @@ export function buildWebpackBrowser(
|
|||||||
normalize(workspace.getProject(projectName).root),
|
normalize(workspace.getProject(projectName).root),
|
||||||
);
|
);
|
||||||
|
|
||||||
// We use zip because when having multiple builds we want to wait
|
return from(configs).pipe(
|
||||||
// for all builds to finish before processeding
|
// the concurrency parameter (3rd parameter of mergeScan) is deliberately
|
||||||
return zip(
|
// set to 1 to make sure the build steps are executed in sequence.
|
||||||
...configs.map(config => runWebpack(config, context, { logging: loggingFn })),
|
mergeScan((lastResult, config) => {
|
||||||
)
|
// Make sure to only run the 2nd build step, if 1st one succeeded
|
||||||
.pipe(
|
if (lastResult.success) {
|
||||||
|
return runWebpack(config, context, { logging: loggingFn });
|
||||||
|
} else {
|
||||||
|
return of();
|
||||||
|
}
|
||||||
|
}, { success: true } as BuildResult, 1),
|
||||||
|
bufferCount(configs.length),
|
||||||
switchMap(buildEvents => {
|
switchMap(buildEvents => {
|
||||||
const success = buildEvents.every(r => r.success);
|
const success = buildEvents.every(r => r.success);
|
||||||
if (success && buildEvents.length === 2 && options.index) {
|
if (success && buildEvents.length === 2 && options.index) {
|
||||||
|
@ -55,7 +55,8 @@ export async function generateWebpackConfig(
|
|||||||
// However this config generation is used by multiple builders such as dev-server
|
// However this config generation is used by multiple builders such as dev-server
|
||||||
const scriptTarget = tsConfig.options.target;
|
const scriptTarget = tsConfig.options.target;
|
||||||
const differentialLoading = context.builder.builderName === 'browser'
|
const differentialLoading = context.builder.builderName === 'browser'
|
||||||
&& isDifferentialLoadingNeeded(projectRoot, scriptTarget);
|
&& isDifferentialLoadingNeeded(projectRoot, scriptTarget) && !options.watch;
|
||||||
|
|
||||||
const scriptTargets = [scriptTarget];
|
const scriptTargets = [scriptTarget];
|
||||||
|
|
||||||
if (differentialLoading) {
|
if (differentialLoading) {
|
||||||
|
@ -63,6 +63,36 @@ describe('Browser Builder with differential loading', () => {
|
|||||||
.toEqual(jasmine.arrayWithExactContents(expectedOutputs));
|
.toEqual(jasmine.arrayWithExactContents(expectedOutputs));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('deactivates differential loading for watch mode', async () => {
|
||||||
|
const { files } = await browserBuild(architect, host, target, { watch: true });
|
||||||
|
|
||||||
|
const expectedOutputs = [
|
||||||
|
'favicon.ico',
|
||||||
|
'index.html',
|
||||||
|
|
||||||
|
'main.js',
|
||||||
|
'main.js.map',
|
||||||
|
|
||||||
|
'polyfills-es5.js',
|
||||||
|
'polyfills-es5.js.map',
|
||||||
|
'polyfills.js',
|
||||||
|
'polyfills.js.map',
|
||||||
|
|
||||||
|
'runtime.js',
|
||||||
|
'runtime.js.map',
|
||||||
|
|
||||||
|
'styles.js',
|
||||||
|
'styles.js.map',
|
||||||
|
|
||||||
|
'vendor.js',
|
||||||
|
'vendor.js.map',
|
||||||
|
] as PathFragment[];
|
||||||
|
|
||||||
|
expect(Object.keys(files))
|
||||||
|
.toEqual(jasmine.arrayWithExactContents(expectedOutputs));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('emits the right ES formats', async () => {
|
it('emits the right ES formats', async () => {
|
||||||
const { files } = await browserBuild(architect, host, target, { optimization: true });
|
const { files } = await browserBuild(architect, host, target, { optimization: true });
|
||||||
expect(await files['main-es5.js']).not.toContain('class');
|
expect(await files['main-es5.js']).not.toContain('class');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user