Skip to content

Commit d07ef2f

Browse files
committed
fix(@angular-devkit/build-angular): ensure browser-esbuild is used in dev server with browser builder and forceEsbuild
To ensure that the `forceEsbuild` development server option chooses the correct underlying build implementation when the project contains the `browser` builder within the build target, an explicit check and conversion of the builder name is now performed during the initialization phase of the development server builder.
1 parent 5b8e2d5 commit d07ef2f

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

packages/angular_devkit/build_angular/src/builders/dev-server/builder.ts

+8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ export function execute(
7272
);
7373
}
7474

75+
if (
76+
normalizedOptions.forceEsbuild &&
77+
builderName === '@angular-devkit/build-angular:browser'
78+
) {
79+
// The compatibility builder should be used if esbuild is force enabled with the official Webpack-based builder.
80+
builderName = '@angular-devkit/build-angular:browser-esbuild';
81+
}
82+
7583
return defer(() => import('./vite-server')).pipe(
7684
switchMap(({ serveWithVite }) =>
7785
serveWithVite(normalizedOptions, builderName, context, transforms, extensions),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { executeDevServer } from '../../index';
10+
import { executeOnceAndFetch } from '../execute-fetch';
11+
import { describeServeBuilder } from '../jasmine-helpers';
12+
import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup';
13+
14+
const ESBUILD_LOG_TEXT = 'Application bundle generation complete.';
15+
const WEBPACK_LOG_TEXT = 'Compiled successfully.';
16+
17+
describeServeBuilder(
18+
executeDevServer,
19+
DEV_SERVER_BUILDER_INFO,
20+
(harness, setupTarget, isViteRun) => {
21+
describe('option: "forceEsbuild"', () => {
22+
beforeEach(async () => {
23+
setupTarget(harness, {});
24+
25+
// Application code is not needed for these tests
26+
await harness.writeFile('src/main.ts', 'console.log("foo");');
27+
});
28+
29+
it('should use build target specified build system when not present', async () => {
30+
harness.useTarget('serve', {
31+
...BASE_OPTIONS,
32+
forceEsbuild: undefined,
33+
});
34+
35+
const { result, response, logs } = await executeOnceAndFetch(harness, '/main.js');
36+
37+
expect(result?.success).toBeTrue();
38+
expect(await response?.text()).toContain('console.log');
39+
expect(logs).toContain(
40+
jasmine.objectContaining({
41+
message: jasmine.stringMatching(isViteRun ? ESBUILD_LOG_TEXT : WEBPACK_LOG_TEXT),
42+
}),
43+
);
44+
});
45+
46+
it('should use build target specified build system when false', async () => {
47+
harness.useTarget('serve', {
48+
...BASE_OPTIONS,
49+
forceEsbuild: false,
50+
});
51+
52+
const { result, response, logs } = await executeOnceAndFetch(harness, '/main.js');
53+
54+
expect(result?.success).toBeTrue();
55+
expect(await response?.text()).toContain('console.log');
56+
expect(logs).toContain(
57+
jasmine.objectContaining({
58+
message: jasmine.stringMatching(isViteRun ? ESBUILD_LOG_TEXT : WEBPACK_LOG_TEXT),
59+
}),
60+
);
61+
});
62+
63+
it('should always use the esbuild build system with Vite when true', async () => {
64+
harness.useTarget('serve', {
65+
...BASE_OPTIONS,
66+
forceEsbuild: true,
67+
});
68+
69+
const { result, response, logs } = await executeOnceAndFetch(harness, '/main.js');
70+
71+
expect(result?.success).toBeTrue();
72+
expect(await response?.text()).toContain('console.log');
73+
expect(logs).toContain(
74+
jasmine.objectContaining({ message: jasmine.stringMatching(ESBUILD_LOG_TEXT) }),
75+
);
76+
});
77+
});
78+
},
79+
);

0 commit comments

Comments
 (0)