Skip to content

Commit 771e036

Browse files
clydinalan-agius4
authored andcommitted
feat(@angular-devkit/build-angular): support deploy URL option for browser-esbuild builder
The `browser-esbuild` builder now provides support for using the `deployUrl` option when building applications. This option is still considered deprecated which is the same status as with the Webpack-based `browser` application builder. This option is only available with the `browser-esbuild` builder and not other esbuild-based builders. The `browser-esbuild` builder is primarily intended to be used as a compatibility builder with the `browser` builder that requires only minimal changes to use.
1 parent b5a8174 commit 771e036

File tree

8 files changed

+95
-3
lines changed

8 files changed

+95
-3
lines changed

packages/angular_devkit/build_angular/src/builders/application/options.ts

+7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ interface InternalOptions {
4747
* This is only used by the development server which currently only supports a single locale per build.
4848
*/
4949
forceI18nFlatOutput?: boolean;
50+
51+
/**
52+
* Allows for usage of the deprecated `deployUrl` option with the compatibility builder `browser-esbuild`.
53+
*/
54+
deployUrl?: string;
5055
}
5156

5257
/** Full set of options for `application` builder. */
@@ -239,6 +244,7 @@ export async function normalizeOptions(
239244
deleteOutputPath,
240245
namedChunks,
241246
budgets,
247+
deployUrl,
242248
} = options;
243249

244250
// Return all the normalized options
@@ -288,6 +294,7 @@ export async function normalizeOptions(
288294
i18nOptions,
289295
namedChunks,
290296
budgets: budgets?.length ? budgets : undefined,
297+
publicPath: deployUrl ? deployUrl : undefined,
291298
};
292299
}
293300

packages/angular_devkit/build_angular/src/builders/browser-esbuild/builder-status-warnings.ts

-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ import { BuilderContext } from '@angular-devkit/architect';
1010
import { Schema as BrowserBuilderOptions } from './schema';
1111

1212
const UNSUPPORTED_OPTIONS: Array<keyof BrowserBuilderOptions> = [
13-
// * Deprecated
14-
'deployUrl',
15-
1613
// * Always enabled with esbuild
1714
// 'commonChunk',
1815

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 { buildEsbuildBrowser } from '../../index';
10+
import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';
11+
12+
describeBuilder(buildEsbuildBrowser, BROWSER_BUILDER_INFO, (harness) => {
13+
describe('Option: "deployUrl"', () => {
14+
beforeEach(async () => {
15+
// Application code is not needed for asset tests
16+
await harness.writeFile('src/main.ts', 'console.log("TEST");');
17+
18+
// Add a global stylesheet to test link elements
19+
await harness.writeFile('src/styles.css', '/* Global styles */');
20+
21+
// Reduce the input index HTML to a single line to simplify comparing
22+
await harness.writeFile(
23+
'src/index.html',
24+
'<html><head><base href="/"></head><body><app-root></app-root></body></html>',
25+
);
26+
});
27+
28+
it('should update script src and link href attributes when option is set to relative URL', async () => {
29+
harness.useTarget('build', {
30+
...BASE_OPTIONS,
31+
styles: ['src/styles.css'],
32+
deployUrl: 'deployUrl/',
33+
});
34+
35+
const { result } = await harness.executeOnce();
36+
expect(result?.success).toBe(true);
37+
harness
38+
.expectFile('dist/index.html')
39+
.content.toEqual(
40+
`<html><head><base href="/"><link rel="stylesheet" href="deployUrl/styles.css"></head>` +
41+
`<body><app-root></app-root>` +
42+
`<script src="deployUrl/main.js" type="module"></script></body></html>`,
43+
);
44+
});
45+
46+
it('should update script src and link href attributes when option is set to absolute URL', async () => {
47+
harness.useTarget('build', {
48+
...BASE_OPTIONS,
49+
styles: ['src/styles.css'],
50+
deployUrl: 'https://example.com/some/path/',
51+
});
52+
53+
const { result } = await harness.executeOnce();
54+
expect(result?.success).toBe(true);
55+
harness
56+
.expectFile('dist/index.html')
57+
.content.toEqual(
58+
`<html><head><base href="/"><link rel="stylesheet" href="https://example.com/some/path/styles.css"></head>` +
59+
`<body><app-root></app-root>` +
60+
`<script src="https://example.com/some/path/main.js" type="module"></script></body></html>`,
61+
);
62+
});
63+
64+
it('should update dynamic import statements when option is set', async () => {
65+
harness.useTarget('build', {
66+
...BASE_OPTIONS,
67+
styles: ['src/styles.css'],
68+
deployUrl: 'https://example.com/some/path/',
69+
namedChunks: true,
70+
});
71+
72+
await harness.writeFile('src/main.ts', 'console.log("TEST");\nimport("./a");\nexport {}');
73+
await harness.writeFile('src/a.ts', 'console.log("A");\nexport {}');
74+
75+
const { result } = await harness.executeOnce();
76+
expect(result?.success).toBe(true);
77+
harness
78+
.expectFile('dist/main.js')
79+
.content.toContain('import("https://example.com/some/path/a');
80+
});
81+
});
82+
});

packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts

+1
Original file line numberDiff line numberDiff line change
@@ -405,5 +405,6 @@ function getEsBuildCommonOptions(options: NormalizedApplicationBuildOptions): Bu
405405
'ngJitMode': jit ? 'true' : 'false',
406406
},
407407
footer,
408+
publicPath: options.publicPath,
408409
};
409410
}

packages/angular_devkit/build_angular/src/tools/esbuild/compiler-plugin-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export function createCompilerPluginOptions(
6464
inlineStyleLanguage,
6565
preserveSymlinks,
6666
tailwindConfiguration,
67+
publicPath: options.publicPath,
6768
},
6869
};
6970
}

packages/angular_devkit/build_angular/src/tools/esbuild/global-styles.ts

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export function createGlobalStylesBundleOptions(
6262
},
6363
includePaths: stylePreprocessorOptions?.includePaths,
6464
tailwindConfiguration,
65+
publicPath: options.publicPath,
6566
},
6667
cache,
6768
);

packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export async function generateIndexHtml(
8282
},
8383
},
8484
crossOrigin: crossOrigin,
85+
deployUrl: buildOptions.publicPath,
8586
});
8687

8788
indexHtmlGenerator.readAsset = readAsset;

packages/angular_devkit/build_angular/src/tools/esbuild/stylesheets/bundle-options.ts

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface BundleStylesheetOptions {
2525
externalDependencies?: string[];
2626
target: string[];
2727
tailwindConfiguration?: { file: string; package: string };
28+
publicPath?: string;
2829
}
2930

3031
export function createStylesheetBundleOptions(
@@ -62,6 +63,7 @@ export function createStylesheetBundleOptions(
6263
target: options.target,
6364
preserveSymlinks: options.preserveSymlinks,
6465
external: options.externalDependencies,
66+
publicPath: options.publicPath,
6567
conditions: ['style', 'sass'],
6668
mainFields: ['style', 'sass'],
6769
plugins: [

0 commit comments

Comments
 (0)