Skip to content

Commit 9ca3a54

Browse files
committed
feat(@angular-devkit/build-angular): add deployUrl to application builder
This commit adds the deployUrl option ot the application builder. Closes #26411
1 parent 14189b2 commit 9ca3a54

File tree

9 files changed

+101
-54
lines changed

9 files changed

+101
-54
lines changed

goldens/public-api/angular_devkit/build_angular/index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export interface ApplicationBuilderOptions {
3636
[key: string]: string;
3737
};
3838
deleteOutputPath?: boolean;
39+
deployUrl?: string;
3940
externalDependencies?: string[];
4041
extractLicenses?: boolean;
4142
fileReplacements?: FileReplacement_2[];
@@ -94,7 +95,6 @@ export interface BrowserBuilderOptions {
9495
commonChunk?: boolean;
9596
crossOrigin?: CrossOrigin;
9697
deleteOutputPath?: boolean;
97-
// @deprecated
9898
deployUrl?: string;
9999
extractLicenses?: boolean;
100100
fileReplacements?: FileReplacement[];
@@ -351,7 +351,6 @@ export interface ServerBuilderOptions {
351351
assets?: AssetPattern_4[];
352352
buildOptimizer?: boolean;
353353
deleteOutputPath?: boolean;
354-
// @deprecated
355354
deployUrl?: string;
356355
externalDependencies?: string[];
357356
extractLicenses?: boolean;

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,6 @@ interface InternalOptions {
6565
* This is only used by the development server which currently only supports a single locale per build.
6666
*/
6767
forceI18nFlatOutput?: boolean;
68-
69-
/**
70-
* Allows for usage of the deprecated `deployUrl` option with the compatibility builder `browser-esbuild`.
71-
*/
72-
deployUrl?: string;
7368
}
7469

7570
/** Full set of options for `application` builder. */
@@ -345,7 +340,7 @@ export async function normalizeOptions(
345340
i18nOptions,
346341
namedChunks,
347342
budgets: budgets?.length ? budgets : undefined,
348-
publicPath: deployUrl ? deployUrl : undefined,
343+
publicPath: deployUrl,
349344
plugins: extensions?.codePlugins?.length ? extensions?.codePlugins : undefined,
350345
loaderExtensions,
351346
jsonLogs: useJSONBuildLogs,

packages/angular_devkit/build_angular/src/builders/application/schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
"type": "string",
3434
"description": "The full path for the TypeScript configuration file, relative to the current workspace."
3535
},
36+
"deployUrl": {
37+
"type": "string",
38+
"description": "Customize the base path for the URLs of resources in 'index.html' and component stylesheets. This option is only necessary for specific deployment scenarios, such as with Angular Elements or when utilizing different CDN locations."
39+
},
3640
"scripts": {
3741
"description": "Global scripts to be included in the build.",
3842
"type": "array",
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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 { buildApplication } from '../../index';
10+
import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup';
11+
12+
describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
13+
describe('Option: "deployUrl"', () => {
14+
beforeEach(async () => {
15+
// Add a global stylesheet to test link elements
16+
await harness.writeFile('src/styles.css', '/* Global styles */');
17+
18+
// Reduce the input index HTML to a single line to simplify comparing
19+
await harness.writeFile(
20+
'src/index.html',
21+
'<html><head><base href="/"></head><body><app-root></app-root></body></html>',
22+
);
23+
});
24+
25+
it('should update script src and link href attributes when option is set to relative URL', async () => {
26+
harness.useTarget('build', {
27+
...BASE_OPTIONS,
28+
styles: ['src/styles.css'],
29+
deployUrl: 'deployUrl/',
30+
});
31+
32+
const { result } = await harness.executeOnce();
33+
expect(result?.success).toBe(true);
34+
harness
35+
.expectFile('dist/browser/index.html')
36+
.content.toEqual(
37+
`<html><head><base href="/"><link rel="stylesheet" href="deployUrl/styles.css"></head>` +
38+
`<body><app-root></app-root>` +
39+
`<script src="deployUrl/main.js" type="module"></script></body></html>`,
40+
);
41+
});
42+
43+
it('should update script src and link href attributes when option is set to absolute URL', async () => {
44+
harness.useTarget('build', {
45+
...BASE_OPTIONS,
46+
styles: ['src/styles.css'],
47+
deployUrl: 'https://example.com/some/path/',
48+
});
49+
50+
const { result } = await harness.executeOnce();
51+
expect(result?.success).toBe(true);
52+
harness
53+
.expectFile('dist/browser/index.html')
54+
.content.toEqual(
55+
`<html><head><base href="/"><link rel="stylesheet" href="https://example.com/some/path/styles.css"></head>` +
56+
`<body><app-root></app-root>` +
57+
`<script src="https://example.com/some/path/main.js" type="module"></script></body></html>`,
58+
);
59+
});
60+
61+
it('should update resources component stylesheets to reference deployURL', async () => {
62+
await harness.writeFile('src/app/test.svg', '<svg></svg>');
63+
await harness.writeFile(
64+
'src/app/app.component.css',
65+
`* { background-image: url('./test.svg'); }`,
66+
);
67+
68+
harness.useTarget('build', {
69+
...BASE_OPTIONS,
70+
deployUrl: 'https://example.com/some/path/',
71+
});
72+
73+
const { result } = await harness.executeOnce();
74+
expect(result?.success).toBeTrue();
75+
76+
harness
77+
.expectFile('dist/browser/main.js')
78+
.content.toContain('background-image: url("https://example.com/some/path/media/test.svg")');
79+
});
80+
});
81+
});

packages/angular_devkit/build_angular/src/builders/browser-esbuild/schema.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,7 @@
277277
},
278278
"deployUrl": {
279279
"type": "string",
280-
"description": "URL where files will be deployed.",
281-
"x-deprecated": "Use \"baseHref\" option, \"APP_BASE_HREF\" DI token or a combination of both instead. For more information, see https://angular.io/guide/deployment#the-deploy-url."
280+
"description": "Customize the base path for the URLs of resources in 'index.html' and component stylesheets. This option is only necessary for specific deployment scenarios, such as with Angular Elements or when utilizing different CDN locations."
282281
},
283282
"verbose": {
284283
"type": "boolean",

packages/angular_devkit/build_angular/src/builders/browser-esbuild/tests/options/deploy-url_spec.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';
1212
describeBuilder(buildEsbuildBrowser, BROWSER_BUILDER_INFO, (harness) => {
1313
describe('Option: "deployUrl"', () => {
1414
beforeEach(async () => {
15-
// Application code is not needed for asset tests
16-
await harness.writeFile('src/main.ts', 'console.log("TEST");');
17-
1815
// Add a global stylesheet to test link elements
1916
await harness.writeFile('src/styles.css', '/* Global styles */');
2017

@@ -61,22 +58,24 @@ describeBuilder(buildEsbuildBrowser, BROWSER_BUILDER_INFO, (harness) => {
6158
);
6259
});
6360

64-
it('should update dynamic import statements when option is set', async () => {
61+
it('should update resources component stylesheets to reference deployURL', async () => {
62+
await harness.writeFile('src/app/test.svg', '<svg></svg>');
63+
await harness.writeFile(
64+
'src/app/app.component.css',
65+
`* { background-image: url('./test.svg'); }`,
66+
);
67+
6568
harness.useTarget('build', {
6669
...BASE_OPTIONS,
67-
styles: ['src/styles.css'],
6870
deployUrl: 'https://example.com/some/path/',
69-
namedChunks: true,
7071
});
7172

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-
7573
const { result } = await harness.executeOnce();
76-
expect(result?.success).toBe(true);
74+
expect(result?.success).toBeTrue();
75+
7776
harness
7877
.expectFile('dist/main.js')
79-
.content.toContain('import("https://example.com/some/path/a');
78+
.content.toContain('background-image: url("https://example.com/some/path/media/test.svg")');
8079
});
8180
});
8281
});

packages/angular_devkit/build_angular/src/builders/browser/schema.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,7 @@
270270
},
271271
"deployUrl": {
272272
"type": "string",
273-
"description": "URL where files will be deployed.",
274-
"x-deprecated": "Use \"baseHref\" option, \"APP_BASE_HREF\" DI token or a combination of both instead. For more information, see https://angular.io/guide/deployment#the-deploy-url."
273+
"description": "Customize the base path for the URLs of resources in 'index.html' and component stylesheets. This option is only necessary for specific deployment scenarios, such as with Angular Elements or when utilizing different CDN locations."
275274
},
276275
"verbose": {
277276
"type": "boolean",

packages/angular_devkit/build_angular/src/builders/server/schema.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@
121121
},
122122
"deployUrl": {
123123
"type": "string",
124-
"description": "URL where files will be deployed.",
125-
"x-deprecated": "Use \"baseHref\" browser builder option, \"APP_BASE_HREF\" DI token or a combination of both instead. For more information, see https://angular.io/guide/deployment#the-deploy-url."
124+
"description": "Customize the base path for the URLs of resources in 'index.html' and component stylesheets. This option is only necessary for specific deployment scenarios, such as with Angular Elements or when utilizing different CDN locations."
126125
},
127126
"vendorChunk": {
128127
"type": "boolean",

packages/schematics/angular/migrations/update-17/use-application-builder.ts

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@
77
*/
88

99
import { workspaces } from '@angular-devkit/core';
10-
import {
11-
Rule,
12-
SchematicContext,
13-
SchematicsException,
14-
chain,
15-
externalSchematic,
16-
} from '@angular-devkit/schematics';
10+
import { Rule, SchematicsException, chain, externalSchematic } from '@angular-devkit/schematics';
1711
import { dirname, join } from 'node:path/posix';
1812
import { JSONFile } from '../../utility/json-file';
1913
import { TreeWorkspaceHost, allTargetOptions, getWorkspace } from '../../utility/workspace';
@@ -52,11 +46,6 @@ export default function (): Rule {
5246
const hasServerTarget = project.targets.has('server');
5347

5448
for (const [, options] of allTargetOptions(buildTarget, false)) {
55-
// Show warnings for using no longer supported options
56-
if (usesNoLongerSupportedOptions(options, context, name)) {
57-
continue;
58-
}
59-
6049
if (options['index'] === '') {
6150
options['index'] = false;
6251
}
@@ -102,7 +91,6 @@ export default function (): Rule {
10291
}
10392

10493
// Delete removed options
105-
delete options['deployUrl'];
10694
delete options['vendorChunk'];
10795
delete options['commonChunk'];
10896
delete options['resourcesOutputPath'];
@@ -204,19 +192,3 @@ export default function (): Rule {
204192
return chain(rules);
205193
};
206194
}
207-
208-
function usesNoLongerSupportedOptions(
209-
{ deployUrl, resourcesOutputPath }: Record<string, unknown>,
210-
context: SchematicContext,
211-
projectName: string,
212-
): boolean {
213-
let hasUsage = false;
214-
if (typeof deployUrl === 'string') {
215-
hasUsage = true;
216-
context.logger.warn(
217-
`Skipping migration for project "${projectName}". "deployUrl" option is not available in the application builder.`,
218-
);
219-
}
220-
221-
return hasUsage;
222-
}

0 commit comments

Comments
 (0)