@angular-devkit/build-angular 17.3.0 → 18.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/package.json +31 -31
  2. package/src/builders/app-shell/index.js +1 -1
  3. package/src/builders/application/build-action.d.ts +5 -4
  4. package/src/builders/application/build-action.js +17 -23
  5. package/src/builders/dev-server/builder.d.ts +0 -2
  6. package/src/builders/dev-server/builder.js +1 -1
  7. package/src/builders/dev-server/vite-server.js +14 -7
  8. package/src/builders/dev-server/webpack-server.js +1 -1
  9. package/src/builders/prerender/index.d.ts +2 -3
  10. package/src/builders/ssr-dev-server/utils.d.ts +1 -2
  11. package/src/tools/babel/plugins/adjust-static-class-members.js +3 -6
  12. package/src/tools/esbuild/angular/angular-host.js +4 -0
  13. package/src/tools/esbuild/angular/compilation/parallel-worker.d.ts +0 -2
  14. package/src/tools/esbuild/angular/compiler-plugin.js +5 -2
  15. package/src/tools/esbuild/bundler-context.js +2 -2
  16. package/src/tools/esbuild/utils.d.ts +3 -3
  17. package/src/tools/esbuild/utils.js +2 -2
  18. package/src/tools/vite/angular-memory-plugin.js +8 -8
  19. package/src/tools/webpack/configs/dev-server.js +20 -11
  20. package/src/tools/webpack/configs/styles.js +22 -53
  21. package/src/tools/webpack/plugins/builder-watch-plugin.js +2 -2
  22. package/src/tools/webpack/plugins/styles-webpack-plugin.js +1 -1
  23. package/src/utils/environment-options.d.ts +0 -1
  24. package/src/utils/environment-options.js +1 -11
  25. package/src/utils/i18n-options.d.ts +3 -2
  26. package/src/utils/i18n-options.js +39 -33
  27. package/src/utils/index-file/inline-fonts.d.ts +0 -2
  28. package/src/utils/normalize-asset-patterns.d.ts +1 -2
  29. package/src/utils/normalize-asset-patterns.js +1 -2
  30. package/src/utils/normalize-cache.d.ts +1 -2
  31. package/src/utils/normalize-cache.js +10 -5
  32. package/src/utils/normalize-file-replacements.d.ts +1 -2
  33. package/src/utils/normalize-file-replacements.js +1 -2
  34. package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.js +0 -2
  35. package/src/utils/server-rendering/prerender.js +11 -3
  36. package/src/utils/service-worker.d.ts +2 -2
  37. package/src/utils/supported-browsers.d.ts +3 -2
  38. package/src/utils/webpack-browser-config.d.ts +1 -2
  39. package/src/tools/sass/sass-service-legacy.d.ts +0 -51
  40. package/src/tools/sass/sass-service-legacy.js +0 -173
  41. package/src/tools/sass/worker-legacy.d.ts +0 -8
  42. package/src/tools/sass/worker-legacy.js +0 -43
  43. package/src/utils/server-rendering/esm-in-memory-loader/node-18-utils.d.ts +0 -10
  44. package/src/utils/server-rendering/esm-in-memory-loader/node-18-utils.js +0 -39
package/package.json CHANGED
@@ -1,26 +1,26 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "17.3.0",
3
+ "version": "18.0.0-next.0",
4
4
  "description": "Angular Webpack Build Facade",
5
5
  "main": "src/index.js",
6
6
  "typings": "src/index.d.ts",
7
7
  "builders": "builders.json",
8
8
  "dependencies": {
9
9
  "@ampproject/remapping": "2.3.0",
10
- "@angular-devkit/architect": "0.1703.0",
11
- "@angular-devkit/build-webpack": "0.1703.0",
12
- "@angular-devkit/core": "17.3.0",
13
- "@babel/core": "7.24.0",
14
- "@babel/generator": "7.23.6",
10
+ "@angular-devkit/architect": "0.1800.0-next.0",
11
+ "@angular-devkit/build-webpack": "0.1800.0-next.0",
12
+ "@angular-devkit/core": "18.0.0-next.0",
13
+ "@babel/core": "7.24.3",
14
+ "@babel/generator": "7.24.1",
15
15
  "@babel/helper-annotate-as-pure": "7.22.5",
16
16
  "@babel/helper-split-export-declaration": "7.22.6",
17
- "@babel/plugin-transform-async-generator-functions": "7.23.9",
18
- "@babel/plugin-transform-async-to-generator": "7.23.3",
19
- "@babel/plugin-transform-runtime": "7.24.0",
20
- "@babel/preset-env": "7.24.0",
21
- "@babel/runtime": "7.24.0",
17
+ "@babel/plugin-transform-async-generator-functions": "7.24.3",
18
+ "@babel/plugin-transform-async-to-generator": "7.24.1",
19
+ "@babel/plugin-transform-runtime": "7.24.3",
20
+ "@babel/preset-env": "7.24.3",
21
+ "@babel/runtime": "7.24.1",
22
22
  "@discoveryjs/json-ext": "0.5.7",
23
- "@ngtools/webpack": "17.3.0",
23
+ "@ngtools/webpack": "18.0.0-next.0",
24
24
  "@vitejs/plugin-basic-ssl": "1.1.0",
25
25
  "ansi-colors": "4.1.3",
26
26
  "autoprefixer": "10.4.18",
@@ -30,15 +30,15 @@
30
30
  "copy-webpack-plugin": "11.0.0",
31
31
  "critters": "0.0.22",
32
32
  "css-loader": "6.10.0",
33
- "esbuild-wasm": "0.20.1",
33
+ "esbuild-wasm": "0.20.2",
34
34
  "fast-glob": "3.3.2",
35
35
  "https-proxy-agent": "7.0.4",
36
36
  "http-proxy-middleware": "2.0.6",
37
- "inquirer": "9.2.15",
37
+ "inquirer": "9.2.16",
38
38
  "jsonc-parser": "3.2.1",
39
39
  "karma-source-map-support": "1.4.0",
40
40
  "less": "4.2.0",
41
- "less-loader": "11.1.0",
41
+ "less-loader": "12.2.0",
42
42
  "license-webpack-plugin": "4.0.2",
43
43
  "loader-utils": "3.2.1",
44
44
  "magic-string": "0.30.8",
@@ -49,41 +49,41 @@
49
49
  "parse5-html-rewriting-stream": "7.0.0",
50
50
  "picomatch": "4.0.1",
51
51
  "piscina": "4.4.0",
52
- "postcss": "8.4.35",
52
+ "postcss": "8.4.37",
53
53
  "postcss-loader": "8.1.1",
54
54
  "resolve-url-loader": "5.0.0",
55
55
  "rxjs": "7.8.1",
56
- "sass": "1.71.1",
56
+ "sass": "1.72.0",
57
57
  "sass-loader": "14.1.1",
58
58
  "semver": "7.6.0",
59
59
  "source-map-loader": "5.0.0",
60
60
  "source-map-support": "0.5.21",
61
- "terser": "5.29.1",
61
+ "terser": "5.29.2",
62
62
  "tree-kill": "1.2.2",
63
63
  "tslib": "2.6.2",
64
- "undici": "6.7.1",
65
- "vite": "5.1.5",
66
- "watchpack": "2.4.0",
67
- "webpack": "5.90.3",
68
- "webpack-dev-middleware": "6.1.1",
69
- "webpack-dev-server": "4.15.1",
64
+ "undici": "6.9.0",
65
+ "vite": "5.2.2",
66
+ "watchpack": "2.4.1",
67
+ "webpack": "5.91.0",
68
+ "webpack-dev-middleware": "7.1.1",
69
+ "webpack-dev-server": "5.0.4",
70
70
  "webpack-merge": "5.10.0",
71
71
  "webpack-subresource-integrity": "5.1.0"
72
72
  },
73
73
  "optionalDependencies": {
74
- "esbuild": "0.20.1"
74
+ "esbuild": "0.20.2"
75
75
  },
76
76
  "peerDependencies": {
77
- "@angular/compiler-cli": "^17.0.0",
78
- "@angular/localize": "^17.0.0",
79
- "@angular/platform-server": "^17.0.0",
80
- "@angular/service-worker": "^17.0.0",
77
+ "@angular/compiler-cli": "^18.0.0-next.0",
78
+ "@angular/localize": "^18.0.0-next.0",
79
+ "@angular/platform-server": "^18.0.0-next.0",
80
+ "@angular/service-worker": "^18.0.0-next.0",
81
81
  "@web/test-runner": "^0.18.0",
82
82
  "browser-sync": "^3.0.2",
83
83
  "jest": "^29.5.0",
84
84
  "jest-environment-jsdom": "^29.5.0",
85
85
  "karma": "^6.3.0",
86
- "ng-packagr": "^17.0.0",
86
+ "ng-packagr": "^18.0.0-next.0",
87
87
  "protractor": "^7.0.0",
88
88
  "tailwindcss": "^2.0.0 || ^3.0.0",
89
89
  "typescript": ">=5.2 <5.5"
@@ -135,7 +135,7 @@
135
135
  "url": "https://github.com/angular/angular-cli.git"
136
136
  },
137
137
  "engines": {
138
- "node": "^18.13.0 || >=20.9.0",
138
+ "node": "^18.19.1 || >=20.11.1",
139
139
  "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
140
140
  "yarn": ">= 1.13.0"
141
141
  },
@@ -44,7 +44,7 @@ const spinner_1 = require("../../utils/spinner");
44
44
  async function _renderUniversal(options, context, browserResult, serverResult, spinner) {
45
45
  // Get browser target options.
46
46
  const browserTarget = (0, architect_1.targetFromTargetString)(options.browserTarget);
47
- const rawBrowserOptions = (await context.getTargetOptions(browserTarget));
47
+ const rawBrowserOptions = await context.getTargetOptions(browserTarget);
48
48
  const browserBuilderName = await context.getBuilderNameForTarget(browserTarget);
49
49
  const browserOptions = await context.validateOptions(rawBrowserOptions, browserBuilderName);
50
50
  // Locate zone.js to load in the render worker
@@ -5,17 +5,17 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { BuilderOutput } from '@angular-devkit/architect';
9
- import type { logging } from '@angular-devkit/core';
8
+ import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
10
9
  import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
11
10
  import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result';
12
11
  import { NormalizedCachedOptions } from '../../utils/normalize-cache';
13
12
  import { NormalizedOutputOptions } from './options';
13
+ type BuildActionOutput = (ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput;
14
14
  export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildState) => Promise<ExecutionResult>, options: {
15
15
  workspaceRoot: string;
16
16
  projectRoot: string;
17
17
  outputOptions: NormalizedOutputOptions;
18
- logger: logging.LoggerApi;
18
+ logger: BuilderContext['logger'];
19
19
  cacheOptions: NormalizedCachedOptions;
20
20
  writeToFileSystem: boolean;
21
21
  writeToFileSystemFilter: ((file: BuildOutputFile) => boolean) | undefined;
@@ -29,4 +29,5 @@ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildSta
29
29
  clearScreen?: boolean;
30
30
  colors?: boolean;
31
31
  jsonLogs?: boolean;
32
- }): AsyncIterable<(ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput>;
32
+ }): AsyncIterable<BuildActionOutput>;
33
+ export {};
@@ -117,16 +117,7 @@ async function* runEsBuildBuildAction(action, options) {
117
117
  // Output the first build results after setting up the watcher to ensure that any code executed
118
118
  // higher in the iterator call stack will trigger the watcher. This is particularly relevant for
119
119
  // unit tests which execute the builder and modify the file system programmatically.
120
- if (writeToFileSystem) {
121
- // Write output files
122
- await (0, utils_1.writeResultFiles)(result.outputFiles, result.assetFiles, outputOptions);
123
- yield result.output;
124
- }
125
- else {
126
- // Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
127
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
- yield result.outputWithFiles;
129
- }
120
+ yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);
130
121
  // Finish if watch mode is not enabled
131
122
  if (!watcher) {
132
123
  return;
@@ -165,19 +156,7 @@ async function* runEsBuildBuildAction(action, options) {
165
156
  if (staleWatchFiles?.size) {
166
157
  watcher.remove([...staleWatchFiles]);
167
158
  }
168
- if (writeToFileSystem) {
169
- // Write output files
170
- const filesToWrite = writeToFileSystemFilter
171
- ? result.outputFiles.filter(writeToFileSystemFilter)
172
- : result.outputFiles;
173
- await (0, utils_1.writeResultFiles)(filesToWrite, result.assetFiles, outputOptions);
174
- yield result.output;
175
- }
176
- else {
177
- // Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
178
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
179
- yield result.outputWithFiles;
180
- }
159
+ yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);
181
160
  }
182
161
  }
183
162
  finally {
@@ -187,3 +166,18 @@ async function* runEsBuildBuildAction(action, options) {
187
166
  }
188
167
  }
189
168
  exports.runEsBuildBuildAction = runEsBuildBuildAction;
169
+ async function writeAndEmitOutput(writeToFileSystem, { outputFiles, output, outputWithFiles, assetFiles }, outputOptions, writeToFileSystemFilter) {
170
+ if (writeToFileSystem) {
171
+ // Write output files
172
+ const outputFilesToWrite = writeToFileSystemFilter
173
+ ? outputFiles.filter(writeToFileSystemFilter)
174
+ : outputFiles;
175
+ await (0, utils_1.writeResultFiles)(outputFilesToWrite, assetFiles, outputOptions);
176
+ return output;
177
+ }
178
+ else {
179
+ // Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
180
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
181
+ return outputWithFiles;
182
+ }
183
+ }
@@ -6,8 +6,6 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  /// <reference types="node" />
9
- /// <reference types="@types/node/http" />
10
- /// <reference types="@types/node/ts4.8/http" />
11
9
  import type { BuilderContext } from '@angular-devkit/architect';
12
10
  import type { Plugin } from 'esbuild';
13
11
  import type http from 'node:http';
@@ -68,7 +68,7 @@ function execute(options, context, transforms = {}, extensions) {
68
68
  context.logger.warn(`Prebundling has been configured but will not be used because caching has been disabled.`);
69
69
  }
70
70
  if (options.allowedHosts?.length) {
71
- context.logger.warn(`The "allowedHost" option will not be used because it is not supported by the "${builderName}" builder.`);
71
+ context.logger.warn(`The "allowedHosts" option will not be used because it is not supported by the "${builderName}" builder.`);
72
72
  }
73
73
  if (options.publicHost) {
74
74
  context.logger.warn(`The "publicHost" option will not be used because it is not supported by the "${builderName}" builder.`);
@@ -49,18 +49,25 @@ const supported_browsers_1 = require("../../utils/supported-browsers");
49
49
  const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
50
50
  const application_1 = require("../application");
51
51
  const browser_esbuild_1 = require("../browser-esbuild");
52
+ /**
53
+ * Build options that are also present on the dev server but are only passed
54
+ * to the build.
55
+ */
56
+ const CONVENIENCE_BUILD_OPTIONS = ['watch', 'poll', 'verbose'];
52
57
  // eslint-disable-next-line max-lines-per-function
53
58
  async function* serveWithVite(serverOptions, builderName, context, transformers, extensions) {
54
59
  // Get the browser configuration from the target name.
55
- const rawBrowserOptions = (await context.getTargetOptions(serverOptions.buildTarget));
60
+ const rawBrowserOptions = await context.getTargetOptions(serverOptions.buildTarget);
56
61
  // Deploy url is not used in the dev-server.
57
62
  delete rawBrowserOptions.deployUrl;
58
- const browserOptions = (await context.validateOptions({
59
- ...rawBrowserOptions,
60
- watch: serverOptions.watch,
61
- poll: serverOptions.poll,
62
- verbose: serverOptions.verbose,
63
- }, builderName));
63
+ // Copy convenience options to build
64
+ for (const optionName of CONVENIENCE_BUILD_OPTIONS) {
65
+ const optionValue = serverOptions[optionName];
66
+ if (optionValue !== undefined) {
67
+ rawBrowserOptions[optionName] = optionValue;
68
+ }
69
+ }
70
+ const browserOptions = await context.validateOptions(rawBrowserOptions, builderName);
64
71
  if (browserOptions.prerender || browserOptions.ssr) {
65
72
  // Disable prerendering if enabled and force SSR.
66
73
  // This is so instead of prerendering all the routes for every change, the page is "prerendered" when it is requested.
@@ -68,7 +68,7 @@ function serveWebpackBrowser(options, builderName, context, transforms = {}) {
68
68
  See https://webpack.js.org/guides/hot-module-replacement for information on working with HMR for Webpack.`);
69
69
  }
70
70
  // Get the browser configuration from the target name.
71
- const rawBrowserOptions = (await context.getTargetOptions(options.buildTarget));
71
+ const rawBrowserOptions = await context.getTargetOptions(options.buildTarget);
72
72
  if (rawBrowserOptions.outputHashing && rawBrowserOptions.outputHashing !== schema_1.OutputHashing.None) {
73
73
  // Disable output hashing for dev build as this can cause memory leaks
74
74
  // See: https://github.com/webpack/webpack-dev-server/issues/377#issuecomment-241258405
@@ -6,9 +6,8 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
9
- import { json } from '@angular-devkit/core';
10
9
  import { Schema } from './schema';
11
- type PrerenderBuilderOptions = Schema & json.JsonObject;
10
+ type PrerenderBuilderOptions = Schema;
12
11
  type PrerenderBuilderOutput = BuilderOutput;
13
12
  /**
14
13
  * Builds the browser and server, then renders each route in options.routes
@@ -16,5 +15,5 @@ type PrerenderBuilderOutput = BuilderOutput;
16
15
  * the browser result.
17
16
  */
18
17
  export declare function execute(options: PrerenderBuilderOptions, context: BuilderContext): Promise<PrerenderBuilderOutput>;
19
- declare const _default: import("../../../../architect/src/internal").Builder<Schema & json.JsonObject>;
18
+ declare const _default: import("../../../../architect/src/internal").Builder<Schema & import("../../../../core/src").JsonObject>;
20
19
  export default _default;
@@ -5,8 +5,7 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- /// <reference types="@types/node/child_process" />
9
- /// <reference types="@types/node/ts4.8/child_process" />
8
+ /// <reference types="node" />
10
9
  import { SpawnOptions } from 'child_process';
11
10
  import { Observable } from 'rxjs';
12
11
  export declare function getAvailablePort(): Promise<number>;
@@ -315,10 +315,7 @@ function default_1() {
315
315
  if (!wrapDecorators || visitedClasses.has(classNode)) {
316
316
  return;
317
317
  }
318
- if (!classNode.id ||
319
- !parentPath.isVariableDeclarator() ||
320
- !core_1.types.isIdentifier(parentPath.node.id) ||
321
- parentPath.node.id.name !== classNode.id.name) {
318
+ if (!parentPath.isVariableDeclarator() || !core_1.types.isIdentifier(parentPath.node.id)) {
322
319
  return;
323
320
  }
324
321
  const origin = parentPath.parentPath;
@@ -338,10 +335,10 @@ function default_1() {
338
335
  // Wrap class and safe static assignments in a pure annotated IIFE
339
336
  const container = core_1.types.arrowFunctionExpression([], core_1.types.blockStatement([
340
337
  core_1.types.variableDeclaration('let', [
341
- core_1.types.variableDeclarator(core_1.types.cloneNode(classNode.id), classNode),
338
+ core_1.types.variableDeclarator(core_1.types.cloneNode(parentPath.node.id), classNode),
342
339
  ]),
343
340
  ...wrapStatementNodes,
344
- core_1.types.returnStatement(core_1.types.cloneNode(classNode.id)),
341
+ core_1.types.returnStatement(core_1.types.cloneNode(parentPath.node.id)),
345
342
  ]));
346
343
  const replacementInitializer = core_1.types.callExpression(core_1.types.parenthesizedExpression(container), []);
347
344
  (0, helper_annotate_as_pure_1.default)(replacementInitializer);
@@ -45,6 +45,10 @@ function createAngularCompilerHost(compilerOptions, hostOptions) {
45
45
  if (context.type !== 'style') {
46
46
  return null;
47
47
  }
48
+ // No transformation required if the resource is empty
49
+ if (data.trim().length === 0) {
50
+ return { content: '' };
51
+ }
48
52
  const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined);
49
53
  return typeof result === 'string' ? { content: result } : null;
50
54
  };
@@ -6,8 +6,6 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  /// <reference types="node" />
9
- /// <reference types="@types/node/worker_threads" />
10
- /// <reference types="@types/node/ts4.8/worker_threads" />
11
9
  import type { PartialMessage } from 'esbuild';
12
10
  import { type MessagePort } from 'node:worker_threads';
13
11
  import type { DiagnosticModes } from './angular-compilation';
@@ -307,8 +307,11 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
307
307
  }
308
308
  // Combine additional metafiles with main metafile
309
309
  if (result.metafile && metafile) {
310
- result.metafile.inputs = { ...result.metafile.inputs, ...metafile.inputs };
311
- result.metafile.outputs = { ...result.metafile.outputs, ...metafile.outputs };
310
+ // Append the existing object, by appending to it we prevent unnecessary new objections creations with spread
311
+ // mitigating significant performance overhead for large apps.
312
+ // See: https://bugs.chromium.org/p/v8/issues/detail?id=11536
313
+ Object.assign(result.metafile.inputs, metafile.inputs);
314
+ Object.assign(result.metafile.outputs, metafile.outputs);
312
315
  }
313
316
  }
314
317
  (0, profiling_1.logCumulativeDurations)();
@@ -85,8 +85,8 @@ class BundlerContext {
85
85
  }
86
86
  // Combine metafiles used for the stats option as well as bundle budgets and console output
87
87
  if (result.metafile) {
88
- metafile.inputs = { ...metafile.inputs, ...result.metafile.inputs };
89
- metafile.outputs = { ...metafile.outputs, ...result.metafile.outputs };
88
+ Object.assign(metafile.inputs, result.metafile.inputs);
89
+ Object.assign(metafile.outputs, result.metafile.outputs);
90
90
  }
91
91
  result.initialFiles.forEach((value, key) => initialFiles.set(key, value));
92
92
  outputFiles.push(...result.outputFiles);
@@ -5,7 +5,7 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { logging } from '@angular-devkit/core';
8
+ import { BuilderContext } from '@angular-devkit/architect';
9
9
  import { BuildOptions, Metafile, OutputFile } from 'esbuild';
10
10
  import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from '../../builders/application/options';
11
11
  import { BudgetCalculatorResult } from '../../utils/bundle-calculator';
@@ -22,7 +22,7 @@ export declare function withNoProgress<T>(text: string, action: () => T | Promis
22
22
  * @returns An object that can be used with the esbuild build `supported` option.
23
23
  */
24
24
  export declare function getFeatureSupport(target: string[]): BuildOptions['supported'];
25
- export declare function writeResultFiles(outputFiles: BuildOutputFile[], assetFiles: BuildOutputAsset[] | undefined, { base, browser, media, server }: NormalizedOutputOptions): Promise<void>;
25
+ export declare function writeResultFiles(outputFiles: BuildOutputFile[], assetFiles: BuildOutputAsset[] | undefined, { base, browser, server }: NormalizedOutputOptions): Promise<void>;
26
26
  export declare function emitFilesToDisk<T = BuildOutputAsset | BuildOutputFile>(files: T[], writeFileCallback: (file: T) => Promise<void>): Promise<void>;
27
27
  export declare function createOutputFileFromText(path: string, text: string, type: BuildOutputFileType): BuildOutputFile;
28
28
  export declare function createOutputFileFromData(path: string, data: Uint8Array, type: BuildOutputFileType): BuildOutputFile;
@@ -38,4 +38,4 @@ export declare function transformSupportedBrowsersToTargets(supportedBrowsers: s
38
38
  */
39
39
  export declare function getSupportedNodeTargets(): string[];
40
40
  export declare function createJsonBuildManifest(result: ExecutionResult, normalizedOptions: NormalizedApplicationBuildOptions): Promise<string>;
41
- export declare function logMessages(logger: logging.LoggerApi, executionResult: ExecutionResult, color?: boolean, jsonLogs?: boolean): Promise<void>;
41
+ export declare function logMessages(logger: BuilderContext['logger'], executionResult: ExecutionResult, color?: boolean, jsonLogs?: boolean): Promise<void>;
@@ -179,7 +179,7 @@ function getFeatureSupport(target) {
179
179
  return supported;
180
180
  }
181
181
  exports.getFeatureSupport = getFeatureSupport;
182
- async function writeResultFiles(outputFiles, assetFiles, { base, browser, media, server }) {
182
+ async function writeResultFiles(outputFiles, assetFiles, { base, browser, server }) {
183
183
  const directoryExists = new Set();
184
184
  const ensureDirectoryExists = async (destPath) => {
185
185
  const basePath = (0, node_path_1.dirname)(destPath);
@@ -331,7 +331,7 @@ function transformSupportedBrowsersToTargets(supportedBrowsers) {
331
331
  return transformed;
332
332
  }
333
333
  exports.transformSupportedBrowsersToTargets = transformSupportedBrowsersToTargets;
334
- const SUPPORTED_NODE_VERSIONS = '^18.13.0 || >=20.9.0';
334
+ const SUPPORTED_NODE_VERSIONS = '^18.19.1 || >=20.11.1';
335
335
  /**
336
336
  * Transform supported Node.js versions to esbuild target.
337
337
  * @see https://esbuild.github.io/api/#target
@@ -159,9 +159,11 @@ function createAngularMemoryPlugin(options) {
159
159
  return;
160
160
  }
161
161
  transformIndexHtmlAndAddHeaders(req.url, rawHtml, res, next, async (html) => {
162
+ const resolvedUrls = server.resolvedUrls;
163
+ const baseUrl = resolvedUrls?.local[0] ?? resolvedUrls?.network[0];
162
164
  const { content } = await (0, render_page_1.renderPage)({
163
165
  document: html,
164
- route: new URL(req.originalUrl ?? '/', server.resolvedUrls?.local[0]).toString(),
166
+ route: new URL(req.originalUrl ?? '/', baseUrl).toString(),
165
167
  serverContext: 'ssr',
166
168
  loadBundle: (uri) =>
167
169
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -230,13 +232,11 @@ exports.createAngularMemoryPlugin = createAngularMemoryPlugin;
230
232
  */
231
233
  async function loadViteClientCode(file) {
232
234
  const originalContents = await (0, promises_1.readFile)(file, 'utf-8');
233
- const firstUpdate = originalContents.replace('You can also disable this overlay by setting', '');
234
- (0, node_assert_1.default)(originalContents !== firstUpdate, 'Failed to update Vite client error overlay text. (1)');
235
- const secondUpdate = firstUpdate.replace(
236
- // eslint-disable-next-line max-len
237
- '<code part="config-option-name">server.hmr.overlay</code> to <code part="config-option-value">false</code> in <code part="config-file-name">${hmrConfigName}.</code>', '');
238
- (0, node_assert_1.default)(firstUpdate !== secondUpdate, 'Failed to update Vite client error overlay text. (2)');
239
- return secondUpdate;
235
+ const updatedContents = originalContents.replace(`h('br'), 'You can also disable this overlay by setting ', ` +
236
+ `h('code', { part: 'config-option-name' }, 'server.hmr.overlay'), '` +
237
+ ` to ', h('code', { part: 'config-option-value' }, 'false'), ' in ', h('code', { part: 'config-file-name' }, hmrConfigName), '.'`, '');
238
+ (0, node_assert_1.default)(originalContents !== updatedContents, 'Failed to update Vite client error overlay text.');
239
+ return updatedContents;
240
240
  }
241
241
  function pathnameWithoutBasePath(url, basePath) {
242
242
  const parsedUrl = new URL(url, 'http://localhost');
@@ -162,12 +162,13 @@ async function addProxyConfig(root, proxyConfig) {
162
162
  if (!(0, fs_1.existsSync)(proxyPath)) {
163
163
  throw new Error(`Proxy configuration file ${proxyPath} does not exist.`);
164
164
  }
165
+ let proxyConfiguration;
165
166
  switch ((0, path_1.extname)(proxyPath)) {
166
167
  case '.json': {
167
168
  const content = await fs_1.promises.readFile(proxyPath, 'utf-8');
168
169
  const { parse, printParseErrorCode } = await Promise.resolve().then(() => __importStar(require('jsonc-parser')));
169
170
  const parseErrors = [];
170
- const proxyConfiguration = parse(content, parseErrors, { allowTrailingComma: true });
171
+ proxyConfiguration = parse(content, parseErrors, { allowTrailingComma: true });
171
172
  if (parseErrors.length > 0) {
172
173
  let errorMessage = `Proxy configuration file ${proxyPath} contains parse errors:`;
173
174
  for (const parseError of parseErrors) {
@@ -176,32 +177,35 @@ async function addProxyConfig(root, proxyConfig) {
176
177
  }
177
178
  throw new Error(errorMessage);
178
179
  }
179
- return proxyConfiguration;
180
+ break;
180
181
  }
181
182
  case '.mjs':
182
183
  // Load the ESM configuration file using the TypeScript dynamic import workaround.
183
184
  // Once TypeScript provides support for keeping the dynamic import this workaround can be
184
185
  // changed to a direct dynamic import.
185
- return (await (0, load_esm_1.loadEsmModule)((0, url_1.pathToFileURL)(proxyPath))).default;
186
+ proxyConfiguration = (await (0, load_esm_1.loadEsmModule)((0, url_1.pathToFileURL)(proxyPath))).default;
187
+ break;
186
188
  case '.cjs':
187
- return require(proxyPath);
189
+ proxyConfiguration = require(proxyPath);
190
+ break;
188
191
  default:
189
192
  // The file could be either CommonJS or ESM.
190
193
  // CommonJS is tried first then ESM if loading fails.
191
194
  try {
192
- return require(proxyPath);
195
+ proxyConfiguration = require(proxyPath);
193
196
  }
194
197
  catch (e) {
195
198
  (0, error_1.assertIsError)(e);
196
- if (e.code === 'ERR_REQUIRE_ESM') {
197
- // Load the ESM configuration file using the TypeScript dynamic import workaround.
198
- // Once TypeScript provides support for keeping the dynamic import this workaround can be
199
- // changed to a direct dynamic import.
200
- return (await (0, load_esm_1.loadEsmModule)((0, url_1.pathToFileURL)(proxyPath))).default;
199
+ if (e.code !== 'ERR_REQUIRE_ESM') {
200
+ throw e;
201
201
  }
202
- throw e;
202
+ // Load the ESM configuration file using the TypeScript dynamic import workaround.
203
+ // Once TypeScript provides support for keeping the dynamic import this workaround can be
204
+ // changed to a direct dynamic import.
205
+ proxyConfiguration = (await (0, load_esm_1.loadEsmModule)((0, url_1.pathToFileURL)(proxyPath))).default;
203
206
  }
204
207
  }
208
+ return normalizeProxyConfiguration(proxyConfiguration);
205
209
  }
206
210
  /**
207
211
  * Calculates the line and column for an error offset in the content of a JSON file.
@@ -301,3 +305,8 @@ function getPublicHostOptions(options, webSocketPath) {
301
305
  }
302
306
  return `auto://${publicHost || '0.0.0.0:0'}${webSocketPath}`;
303
307
  }
308
+ function normalizeProxyConfiguration(proxy) {
309
+ return Array.isArray(proxy)
310
+ ? proxy
311
+ : Object.entries(proxy).map(([context, value]) => ({ context: [context], ...value }));
312
+ }