Skip to content

Commit 27d89ce

Browse files
author
Angular Builds
committed
faabbbf fix(@angular-devkit/build-angular): remove double-watch in karma
1 parent 17b04e4 commit 27d89ce

File tree

4 files changed

+46
-28
lines changed

4 files changed

+46
-28
lines changed

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"name": "@angular-devkit/build-angular",
3-
"version": "19.1.0-next.0+sha-18b6aea",
3+
"version": "19.1.0-next.0+sha-faabbbf",
44
"description": "Angular Webpack Build Facade",
55
"main": "src/index.js",
66
"typings": "src/index.d.ts",
77
"builders": "builders.json",
88
"dependencies": {
99
"@ampproject/remapping": "2.3.0",
10-
"@angular-devkit/architect": "github:angular/angular-devkit-architect-builds#18b6aea",
11-
"@angular-devkit/build-webpack": "github:angular/angular-devkit-build-webpack-builds#18b6aea",
12-
"@angular-devkit/core": "github:angular/angular-devkit-core-builds#18b6aea",
13-
"@angular/build": "github:angular/angular-build-builds#18b6aea",
10+
"@angular-devkit/architect": "github:angular/angular-devkit-architect-builds#faabbbf",
11+
"@angular-devkit/build-webpack": "github:angular/angular-devkit-build-webpack-builds#faabbbf",
12+
"@angular-devkit/core": "github:angular/angular-devkit-core-builds#faabbbf",
13+
"@angular/build": "github:angular/angular-build-builds#faabbbf",
1414
"@babel/core": "7.26.0",
1515
"@babel/generator": "7.26.2",
1616
"@babel/helper-annotate-as-pure": "7.25.9",
@@ -21,7 +21,7 @@
2121
"@babel/preset-env": "7.26.0",
2222
"@babel/runtime": "7.26.0",
2323
"@discoveryjs/json-ext": "0.6.3",
24-
"@ngtools/webpack": "github:angular/ngtools-webpack-builds#18b6aea",
24+
"@ngtools/webpack": "github:angular/ngtools-webpack-builds#faabbbf",
2525
"@vitejs/plugin-basic-ssl": "1.1.0",
2626
"ansi-colors": "4.1.3",
2727
"autoprefixer": "10.4.20",
@@ -70,7 +70,7 @@
7070
"@angular/localize": "^19.0.0-next.0",
7171
"@angular/platform-server": "^19.0.0-next.0",
7272
"@angular/service-worker": "^19.0.0-next.0",
73-
"@angular/ssr": "github:angular/angular-ssr-builds#18b6aea",
73+
"@angular/ssr": "github:angular/angular-ssr-builds#faabbbf",
7474
"@web/test-runner": "^0.19.0",
7575
"browser-sync": "^3.0.2",
7676
"jest": "^29.5.0",
@@ -91,7 +91,7 @@
9191
"@angular/service-worker": {
9292
"optional": true
9393
},
94-
"@angular/ssr": "github:angular/angular-ssr-builds#18b6aea",
94+
"@angular/ssr": "github:angular/angular-ssr-builds#faabbbf",
9595
"@web/test-runner": {
9696
"optional": true
9797
},

src/builders/karma/application_builder.js

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class ApplicationBuildError extends Error {
5050
this.name = 'ApplicationBuildError';
5151
}
5252
}
53-
function injectKarmaReporter(context, buildOptions, karmaConfig, subscriber) {
53+
function injectKarmaReporter(context, buildOptions, buildIterator, karmaConfig, subscriber) {
5454
const reporterName = 'angular-progress-notifier';
5555
class ProgressNotifierReporter {
5656
emitter;
@@ -61,10 +61,14 @@ function injectKarmaReporter(context, buildOptions, karmaConfig, subscriber) {
6161
}
6262
startWatchingBuild() {
6363
void (async () => {
64-
for await (const buildOutput of (0, private_1.buildApplicationInternal)({
65-
...buildOptions,
66-
watch: true,
67-
}, context)) {
64+
// This is effectively "for await of but skip what's already consumed".
65+
let isDone = false; // to mark the loop condition as "not constant".
66+
while (!isDone) {
67+
const { done, value: buildOutput } = await buildIterator.next();
68+
if (done) {
69+
isDone = true;
70+
break;
71+
}
6872
if (buildOutput.kind === private_1.ResultKind.Failure) {
6973
subscriber.next({ success: false, message: 'Build failed' });
7074
}
@@ -96,11 +100,11 @@ function injectKarmaReporter(context, buildOptions, karmaConfig, subscriber) {
96100
});
97101
}
98102
function execute(options, context, karmaOptions, transforms = {}) {
99-
return (0, rxjs_1.from)(initializeApplication(options, context, karmaOptions, transforms)).pipe((0, rxjs_1.switchMap)(([karma, karmaConfig, buildOptions]) => new rxjs_1.Observable((subscriber) => {
103+
return (0, rxjs_1.from)(initializeApplication(options, context, karmaOptions, transforms)).pipe((0, rxjs_1.switchMap)(([karma, karmaConfig, buildOptions, buildIterator]) => new rxjs_1.Observable((subscriber) => {
100104
// If `--watch` is explicitly enabled or if we are keeping the Karma
101105
// process running, we should hook Karma into the build.
102-
if (options.watch ?? !karmaConfig.singleRun) {
103-
injectKarmaReporter(context, buildOptions, karmaConfig, subscriber);
106+
if (buildIterator) {
107+
injectKarmaReporter(context, buildOptions, buildIterator, karmaConfig, subscriber);
104108
}
105109
// Complete the observable once the Karma server returns.
106110
const karmaServer = new karma.Server(karmaConfig, (exitCode) => {
@@ -179,9 +183,10 @@ async function initializeApplication(options, context, karmaOptions, transforms
179183
styles: options.styles,
180184
polyfills: normalizePolyfills(options.polyfills),
181185
webWorkerTsConfig: options.webWorkerTsConfig,
186+
watch: options.watch ?? !karmaOptions.singleRun,
182187
};
183188
// Build tests with `application` builder, using test files as entry points.
184-
const buildOutput = await first((0, private_1.buildApplicationInternal)(buildOptions, context));
189+
const [buildOutput, buildIterator] = await first((0, private_1.buildApplicationInternal)(buildOptions, context), { cancel: !buildOptions.watch });
185190
if (buildOutput.kind === private_1.ResultKind.Failure) {
186191
throw new ApplicationBuildError('Build failed');
187192
}
@@ -193,22 +198,27 @@ async function initializeApplication(options, context, karmaOptions, transforms
193198
karmaOptions.files ??= [];
194199
karmaOptions.files.push(
195200
// Serve polyfills first.
196-
{ pattern: `${outputPath}/polyfills.js`, type: 'module' },
201+
{ pattern: `${outputPath}/polyfills.js`, type: 'module', watched: false },
197202
// Serve global setup script.
198-
{ pattern: `${outputPath}/${mainName}.js`, type: 'module' },
203+
{ pattern: `${outputPath}/${mainName}.js`, type: 'module', watched: false },
199204
// Serve all source maps.
200-
{ pattern: `${outputPath}/*.map`, included: false });
205+
{ pattern: `${outputPath}/*.map`, included: false, watched: false });
201206
if (hasChunkOrWorkerFiles(buildOutput.files)) {
202207
karmaOptions.files.push(
203208
// Allow loading of chunk-* files but don't include them all on load.
204-
{ pattern: `${outputPath}/{chunk,worker}-*.js`, type: 'module', included: false });
209+
{
210+
pattern: `${outputPath}/{chunk,worker}-*.js`,
211+
type: 'module',
212+
included: false,
213+
watched: false,
214+
});
205215
}
206216
karmaOptions.files.push(
207217
// Serve remaining JS on page load, these are the test entrypoints.
208-
{ pattern: `${outputPath}/*.js`, type: 'module' });
218+
{ pattern: `${outputPath}/*.js`, type: 'module', watched: false });
209219
if (options.styles?.length) {
210220
// Serve CSS outputs on page load, these are the global styles.
211-
karmaOptions.files.push({ pattern: `${outputPath}/*.css`, type: 'css' });
221+
karmaOptions.files.push({ pattern: `${outputPath}/*.css`, type: 'css', watched: false });
212222
}
213223
const parsedKarmaConfig = await karma.config.parseConfig(options.karmaConfig && path.resolve(context.workspaceRoot, options.karmaConfig), transforms.karmaOptions ? transforms.karmaOptions(karmaOptions) : karmaOptions, { promiseConfig: true, throwErrors: true });
214224
// Remove the webpack plugin/framework:
@@ -232,7 +242,7 @@ async function initializeApplication(options, context, karmaOptions, transforms
232242
!parsedKarmaConfig.reporters?.some((r) => r === 'coverage' || r === 'coverage-istanbul')) {
233243
parsedKarmaConfig.reporters = (parsedKarmaConfig.reporters ?? []).concat(['coverage']);
234244
}
235-
return [karma, parsedKarmaConfig, buildOptions];
245+
return [karma, parsedKarmaConfig, buildOptions, buildIterator];
236246
}
237247
function hasChunkOrWorkerFiles(files) {
238248
return Object.keys(files).some((filename) => {
@@ -264,9 +274,17 @@ async function writeTestFiles(files, testDir) {
264274
});
265275
}
266276
/** Returns the first item yielded by the given generator and cancels the execution. */
267-
async function first(generator) {
277+
async function first(generator, { cancel }) {
278+
if (!cancel) {
279+
const iterator = generator[Symbol.asyncIterator]();
280+
const firstValue = await iterator.next();
281+
if (firstValue.done) {
282+
throw new Error('Expected generator to emit at least once.');
283+
}
284+
return [firstValue.value, iterator];
285+
}
268286
for await (const value of generator) {
269-
return value;
287+
return [value, null];
270288
}
271289
throw new Error('Expected generator to emit at least once.');
272290
}

src/utils/normalize-cache.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
1010
exports.normalizeCacheOptions = normalizeCacheOptions;
1111
const node_path_1 = require("node:path");
1212
/** Version placeholder is replaced during the build process with actual package version */
13-
const VERSION = '19.1.0-next.0+sha-18b6aea';
13+
const VERSION = '19.1.0-next.0+sha-faabbbf';
1414
function hasCacheMetadata(value) {
1515
return (!!value &&
1616
typeof value === 'object' &&

uniqueId

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Tue Nov 05 2024 18:44:24 GMT+0000 (Coordinated Universal Time)
1+
Tue Nov 05 2024 22:40:41 GMT+0000 (Coordinated Universal Time)

0 commit comments

Comments
 (0)