@angular-devkit/build-angular 17.2.3 → 17.3.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 (53) hide show
  1. package/package.json +27 -27
  2. package/src/builders/app-shell/index.js +1 -0
  3. package/src/builders/app-shell/render-worker.js +1 -1
  4. package/src/builders/application/build-action.d.ts +3 -1
  5. package/src/builders/application/build-action.js +5 -1
  6. package/src/builders/application/execute-build.js +1 -1
  7. package/src/builders/application/index.js +9 -6
  8. package/src/builders/application/options.d.ts +2 -6
  9. package/src/builders/application/options.js +48 -25
  10. package/src/builders/application/schema.d.ts +6 -0
  11. package/src/builders/application/schema.json +4 -0
  12. package/src/builders/browser/index.js +1 -1
  13. package/src/builders/browser/schema.d.ts +3 -3
  14. package/src/builders/browser/schema.json +1 -2
  15. package/src/builders/browser-esbuild/schema.d.ts +3 -3
  16. package/src/builders/browser-esbuild/schema.json +1 -2
  17. package/src/builders/dev-server/builder.js +13 -4
  18. package/src/builders/dev-server/schema.d.ts +6 -3
  19. package/src/builders/dev-server/schema.json +3 -3
  20. package/src/builders/dev-server/vite-server.js +7 -4
  21. package/src/builders/prerender/index.js +2 -0
  22. package/src/builders/server/schema.d.ts +3 -4
  23. package/src/builders/server/schema.json +1 -2
  24. package/src/builders/web-test-runner/index.js +1 -1
  25. package/src/tools/esbuild/angular/compilation/parallel-compilation.js +1 -0
  26. package/src/tools/esbuild/application-code-bundle.js +1 -2
  27. package/src/tools/esbuild/bundler-execution-result.d.ts +2 -0
  28. package/src/tools/esbuild/bundler-execution-result.js +4 -0
  29. package/src/tools/esbuild/global-styles.js +1 -2
  30. package/src/tools/esbuild/i18n-inliner.js +1 -0
  31. package/src/tools/esbuild/javascript-transformer.js +1 -0
  32. package/src/tools/esbuild/utils.d.ts +2 -1
  33. package/src/tools/esbuild/utils.js +26 -24
  34. package/src/tools/sass/sass-service.d.ts +3 -3
  35. package/src/tools/sass/sass-service.js +3 -3
  36. package/src/tools/webpack/plugins/javascript-optimizer-plugin.js +1 -0
  37. package/src/tools/webpack/plugins/javascript-optimizer-worker.d.ts +1 -1
  38. package/src/tools/webpack/utils/stats.js +3 -2
  39. package/src/utils/action-executor.js +1 -0
  40. package/src/utils/color.d.ts +0 -1
  41. package/src/utils/color.js +4 -10
  42. package/src/utils/index-file/html-rewriting-stream.js +9 -26
  43. package/src/utils/index-file/index-html-generator.js +4 -5
  44. package/src/utils/purge-cache.js +17 -12
  45. package/src/utils/server-rendering/load-esm-from-memory.d.ts +10 -0
  46. package/src/utils/server-rendering/load-esm-from-memory.js +26 -0
  47. package/src/utils/server-rendering/prerender.js +2 -0
  48. package/src/utils/server-rendering/render-page.js +2 -2
  49. package/src/utils/server-rendering/render-worker.js +0 -2
  50. package/src/utils/server-rendering/routes-extractor-worker.js +3 -3
  51. package/src/utils/version.js +15 -21
  52. package/src/utils/strip-bom.d.ts +0 -8
  53. package/src/utils/strip-bom.js +0 -17
package/package.json CHANGED
@@ -1,77 +1,77 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "17.2.3",
3
+ "version": "17.3.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
- "@ampproject/remapping": "2.2.1",
10
- "@angular-devkit/architect": "0.1702.3",
11
- "@angular-devkit/build-webpack": "0.1702.3",
12
- "@angular-devkit/core": "17.2.3",
13
- "@babel/core": "7.23.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
14
  "@babel/generator": "7.23.6",
15
15
  "@babel/helper-annotate-as-pure": "7.22.5",
16
16
  "@babel/helper-split-export-declaration": "7.22.6",
17
17
  "@babel/plugin-transform-async-generator-functions": "7.23.9",
18
18
  "@babel/plugin-transform-async-to-generator": "7.23.3",
19
- "@babel/plugin-transform-runtime": "7.23.9",
20
- "@babel/preset-env": "7.23.9",
21
- "@babel/runtime": "7.23.9",
19
+ "@babel/plugin-transform-runtime": "7.24.0",
20
+ "@babel/preset-env": "7.24.0",
21
+ "@babel/runtime": "7.24.0",
22
22
  "@discoveryjs/json-ext": "0.5.7",
23
- "@ngtools/webpack": "17.2.3",
23
+ "@ngtools/webpack": "17.3.0",
24
24
  "@vitejs/plugin-basic-ssl": "1.1.0",
25
25
  "ansi-colors": "4.1.3",
26
- "autoprefixer": "10.4.17",
26
+ "autoprefixer": "10.4.18",
27
27
  "babel-loader": "9.1.3",
28
28
  "babel-plugin-istanbul": "6.1.1",
29
29
  "browserslist": "^4.21.5",
30
30
  "copy-webpack-plugin": "11.0.0",
31
- "critters": "0.0.20",
31
+ "critters": "0.0.22",
32
32
  "css-loader": "6.10.0",
33
- "esbuild-wasm": "0.20.0",
33
+ "esbuild-wasm": "0.20.1",
34
34
  "fast-glob": "3.3.2",
35
- "https-proxy-agent": "7.0.2",
35
+ "https-proxy-agent": "7.0.4",
36
36
  "http-proxy-middleware": "2.0.6",
37
- "inquirer": "9.2.14",
37
+ "inquirer": "9.2.15",
38
38
  "jsonc-parser": "3.2.1",
39
39
  "karma-source-map-support": "1.4.0",
40
40
  "less": "4.2.0",
41
41
  "less-loader": "11.1.0",
42
42
  "license-webpack-plugin": "4.0.2",
43
43
  "loader-utils": "3.2.1",
44
- "magic-string": "0.30.7",
45
- "mini-css-extract-plugin": "2.8.0",
44
+ "magic-string": "0.30.8",
45
+ "mini-css-extract-plugin": "2.8.1",
46
46
  "mrmime": "2.0.0",
47
47
  "open": "8.4.2",
48
48
  "ora": "5.4.1",
49
49
  "parse5-html-rewriting-stream": "7.0.0",
50
50
  "picomatch": "4.0.1",
51
- "piscina": "4.3.1",
51
+ "piscina": "4.4.0",
52
52
  "postcss": "8.4.35",
53
- "postcss-loader": "8.1.0",
53
+ "postcss-loader": "8.1.1",
54
54
  "resolve-url-loader": "5.0.0",
55
55
  "rxjs": "7.8.1",
56
- "sass": "1.70.0",
57
- "sass-loader": "14.1.0",
56
+ "sass": "1.71.1",
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.27.0",
61
+ "terser": "5.29.1",
62
62
  "tree-kill": "1.2.2",
63
63
  "tslib": "2.6.2",
64
- "undici": "6.6.2",
65
- "vite": "5.0.12",
64
+ "undici": "6.7.1",
65
+ "vite": "5.1.5",
66
66
  "watchpack": "2.4.0",
67
- "webpack": "5.90.1",
67
+ "webpack": "5.90.3",
68
68
  "webpack-dev-middleware": "6.1.1",
69
69
  "webpack-dev-server": "4.15.1",
70
70
  "webpack-merge": "5.10.0",
71
71
  "webpack-subresource-integrity": "5.1.0"
72
72
  },
73
73
  "optionalDependencies": {
74
- "esbuild": "0.20.0"
74
+ "esbuild": "0.20.1"
75
75
  },
76
76
  "peerDependencies": {
77
77
  "@angular/compiler-cli": "^17.0.0",
@@ -86,7 +86,7 @@
86
86
  "ng-packagr": "^17.0.0",
87
87
  "protractor": "^7.0.0",
88
88
  "tailwindcss": "^2.0.0 || ^3.0.0",
89
- "typescript": ">=5.2 <5.4"
89
+ "typescript": ">=5.2 <5.5"
90
90
  },
91
91
  "peerDependenciesMeta": {
92
92
  "@angular/localize": {
@@ -69,6 +69,7 @@ async function _renderUniversal(options, context, browserResult, serverResult, s
69
69
  filename: require.resolve('./render-worker'),
70
70
  maxThreads: 1,
71
71
  workerData: { zonePackage },
72
+ recordTiming: false,
72
73
  });
73
74
  try {
74
75
  for (const { path: outputPath, baseHref } of browserResult.outputs) {
@@ -76,7 +76,7 @@ async function render({ serverBundlePath, document, url }) {
76
76
  }
77
77
  // The below should really handled by the framework!!!.
78
78
  let timer;
79
- const renderingTimeout = new Promise((_, reject) => (timer = setTimeout(() => reject(new Error(`Page ${new URL(url, 'resolve://').pathname} did not render in 30 seconds.`)), 30000)));
79
+ const renderingTimeout = new Promise((_, reject) => (timer = setTimeout(() => reject(new Error(`Page ${new URL(url, 'resolve://').pathname} did not render in 30 seconds.`)), 30_000)));
80
80
  return Promise.race([renderAppPromise, renderingTimeout]).finally(() => clearTimeout(timer));
81
81
  }
82
82
  function isBootstrapFn(value) {
@@ -11,7 +11,7 @@ import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
11
11
  import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result';
12
12
  import { NormalizedCachedOptions } from '../../utils/normalize-cache';
13
13
  import { NormalizedOutputOptions } from './options';
14
- export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildState) => ExecutionResult | Promise<ExecutionResult>, options: {
14
+ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildState) => Promise<ExecutionResult>, options: {
15
15
  workspaceRoot: string;
16
16
  projectRoot: string;
17
17
  outputOptions: NormalizedOutputOptions;
@@ -27,4 +27,6 @@ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildSta
27
27
  signal?: AbortSignal;
28
28
  preserveSymlinks?: boolean;
29
29
  clearScreen?: boolean;
30
+ colors?: boolean;
31
+ jsonLogs?: boolean;
30
32
  }): AsyncIterable<(ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput>;
@@ -54,7 +54,7 @@ const packageWatchFiles = [
54
54
  '.pnp.data.json',
55
55
  ];
56
56
  async function* runEsBuildBuildAction(action, options) {
57
- const { writeToFileSystemFilter, writeToFileSystem, watch, poll, clearScreen, logger, deleteOutputPath, cacheOptions, outputOptions, verbose, projectRoot, workspaceRoot, progress, preserveSymlinks, } = options;
57
+ const { writeToFileSystemFilter, writeToFileSystem, watch, poll, clearScreen, logger, deleteOutputPath, cacheOptions, outputOptions, verbose, projectRoot, workspaceRoot, progress, preserveSymlinks, colors, jsonLogs, } = options;
58
58
  if (deleteOutputPath && writeToFileSystem) {
59
59
  await (0, delete_output_dir_1.deleteOutputDir)(workspaceRoot, outputOptions.base, [
60
60
  outputOptions.browser,
@@ -67,6 +67,8 @@ async function* runEsBuildBuildAction(action, options) {
67
67
  try {
68
68
  // Perform the build action
69
69
  result = await withProgress('Building...', () => action());
70
+ // Log all diagnostic (error/warning/logs) messages
71
+ await (0, utils_1.logMessages)(logger, result, colors, jsonLogs);
70
72
  }
71
73
  finally {
72
74
  // Ensure Sass workers are shutdown if not watching
@@ -144,6 +146,8 @@ async function* runEsBuildBuildAction(action, options) {
144
146
  logger.info(changes.toDebugString());
145
147
  }
146
148
  result = await withProgress('Changes detected. Rebuilding...', () => action(result.createRebuildState(changes)));
149
+ // Log all diagnostic (error/warning/logs) messages
150
+ await (0, utils_1.logMessages)(logger, result, colors, jsonLogs);
147
151
  // Update watched locations provided by the new build result.
148
152
  // Keep watching all previous files if there are any errors; otherwise consider all
149
153
  // files stale until confirmed present in the new result's watch files.
@@ -120,7 +120,7 @@ async function executeBuild(options, context, rebuildState) {
120
120
  executionResult.addOutputFile('stats.json', JSON.stringify(metafile, null, 2), bundler_context_1.BuildOutputFileType.Root);
121
121
  }
122
122
  if (!jsonLogs) {
123
- context.logger.info((0, utils_1.logBuildStats)(metafile, initialFiles, budgetFailures, colors, changedFiles, estimatedTransferSizes, !!ssrOptions, verbose));
123
+ executionResult.addLog((0, utils_1.logBuildStats)(metafile, initialFiles, budgetFailures, colors, changedFiles, estimatedTransferSizes, !!ssrOptions, verbose));
124
124
  }
125
125
  return executionResult;
126
126
  }
@@ -62,22 +62,23 @@ context, infrastructureSettings, extensions) {
62
62
  const { prerenderOptions, outputOptions, jsonLogs } = normalizedOptions;
63
63
  const startTime = process.hrtime.bigint();
64
64
  const result = await (0, execute_build_1.executeBuild)(normalizedOptions, context, rebuildState);
65
- if (!jsonLogs) {
65
+ if (jsonLogs) {
66
+ result.addLog(await (0, utils_1.createJsonBuildManifest)(result, normalizedOptions));
67
+ }
68
+ else {
66
69
  if (prerenderOptions) {
67
70
  const prerenderedRoutesLength = result.prerenderedRoutes.length;
68
71
  let prerenderMsg = `Prerendered ${prerenderedRoutesLength} static route`;
69
72
  prerenderMsg += prerenderedRoutesLength !== 1 ? 's.' : '.';
70
- logger.info(color_1.colors.magenta(prerenderMsg));
73
+ result.addLog(color_1.colors.magenta(prerenderMsg));
71
74
  }
72
75
  const buildTime = Number(process.hrtime.bigint() - startTime) / 10 ** 9;
73
76
  const hasError = result.errors.length > 0;
74
77
  if (writeToFileSystem && !hasError) {
75
- logger.info(`Output location: ${outputOptions.base}\n`);
78
+ result.addLog(`Output location: ${outputOptions.base}\n`);
76
79
  }
77
- logger.info(`Application bundle generation ${hasError ? 'failed' : 'complete'}. [${buildTime.toFixed(3)} seconds]`);
80
+ result.addLog(`Application bundle generation ${hasError ? 'failed' : 'complete'}. [${buildTime.toFixed(3)} seconds]\n`);
78
81
  }
79
- // Log all diagnostic (error/warning) messages
80
- await (0, utils_1.logMessages)(logger, result, normalizedOptions);
81
82
  return result;
82
83
  }, {
83
84
  watch: normalizedOptions.watch,
@@ -91,6 +92,8 @@ context, infrastructureSettings, extensions) {
91
92
  workspaceRoot: normalizedOptions.workspaceRoot,
92
93
  progress: normalizedOptions.progress,
93
94
  clearScreen: normalizedOptions.clearScreen,
95
+ colors: normalizedOptions.colors,
96
+ jsonLogs: normalizedOptions.jsonLogs,
94
97
  writeToFileSystem,
95
98
  // For app-shell and SSG server files are not required by users.
96
99
  // Omit these when SSR is not enabled.
@@ -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 { BuilderContext } from '@angular-devkit/architect';
8
+ import type { BuilderContext } from '@angular-devkit/architect';
9
9
  import type { Plugin } from 'esbuild';
10
10
  import { I18nOptions } from '../../utils/i18n-options';
11
11
  import { IndexHtmlTransform } from '../../utils/index-file/index-html-generator';
@@ -39,10 +39,6 @@ interface InternalOptions {
39
39
  * This is only used by the development server which currently only supports a single locale per build.
40
40
  */
41
41
  forceI18nFlatOutput?: boolean;
42
- /**
43
- * Allows for usage of the deprecated `deployUrl` option with the compatibility builder `browser-esbuild`.
44
- */
45
- deployUrl?: string;
46
42
  }
47
43
  /** Full set of options for `application` builder. */
48
44
  export type ApplicationBuilderInternalOptions = Omit<ApplicationBuilderOptions & InternalOptions, 'browser'> & {
@@ -123,7 +119,7 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
123
119
  indexHtmlOptions: {
124
120
  input: string;
125
121
  output: string;
126
- insertionOrder: import("../../utils/package-chunk-sort").EntryPointsType[];
122
+ insertionOrder: [string, boolean][];
127
123
  transformer: IndexHtmlTransform | undefined;
128
124
  preloadInitial: boolean;
129
125
  } | undefined;
@@ -15,16 +15,13 @@ const node_fs_1 = require("node:fs");
15
15
  const promises_1 = require("node:fs/promises");
16
16
  const node_module_1 = require("node:module");
17
17
  const node_path_1 = __importDefault(require("node:path"));
18
- const helpers_1 = require("../../tools/webpack/utils/helpers");
19
18
  const utils_1 = require("../../utils");
20
19
  const color_1 = require("../../utils/color");
21
20
  const environment_options_1 = require("../../utils/environment-options");
22
21
  const i18n_options_1 = require("../../utils/i18n-options");
23
22
  const normalize_cache_1 = require("../../utils/normalize-cache");
24
- const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
25
23
  const postcss_configuration_1 = require("../../utils/postcss-configuration");
26
24
  const tailwind_1 = require("../../utils/tailwind");
27
- const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
28
25
  const schema_1 = require("./schema");
29
26
  /**
30
27
  * Normalize the user provided options by creating full paths for all path based options
@@ -116,31 +113,24 @@ async function normalizeOptions(context, projectName, options, extensions) {
116
113
  const tailwindConfiguration = postcssConfiguration
117
114
  ? undefined
118
115
  : await getTailwindConfig(workspaceRoot, projectRoot, context);
119
- const globalStyles = [];
120
- if (options.styles?.length) {
121
- const { entryPoints: stylesheetEntrypoints, noInjectNames } = (0, helpers_1.normalizeGlobalStyles)(options.styles || []);
122
- for (const [name, files] of Object.entries(stylesheetEntrypoints)) {
123
- globalStyles.push({ name, files, initial: !noInjectNames.includes(name) });
124
- }
125
- }
126
- const globalScripts = [];
127
- if (options.scripts?.length) {
128
- for (const { bundleName, paths, inject } of (0, helpers_1.globalScriptsByBundleName)(options.scripts)) {
129
- globalScripts.push({ name: bundleName, files: paths, initial: inject });
130
- }
131
- }
116
+ const globalStyles = normalizeGlobalEntries(options.styles, 'styles');
117
+ const globalScripts = normalizeGlobalEntries(options.scripts, 'scripts');
132
118
  let indexHtmlOptions;
133
119
  // index can never have a value of `true` but in the schema it's of type `boolean`.
134
120
  if (typeof options.index !== 'boolean') {
135
121
  indexHtmlOptions = {
136
- input: node_path_1.default.join(workspaceRoot, (0, webpack_browser_config_1.getIndexInputFile)(options.index)),
122
+ input: node_path_1.default.join(workspaceRoot, typeof options.index === 'string' ? options.index : options.index.input),
137
123
  // The output file will be created within the configured output path
138
- output: (0, webpack_browser_config_1.getIndexOutputFile)(options.index),
139
- // TODO: Use existing information from above to create the insertion order
140
- insertionOrder: (0, package_chunk_sort_1.generateEntryPoints)({
141
- scripts: options.scripts ?? [],
142
- styles: options.styles ?? [],
143
- }),
124
+ output: typeof options.index === 'string'
125
+ ? node_path_1.default.basename(options.index)
126
+ : options.index.output || 'index.html',
127
+ insertionOrder: [
128
+ ['polyfills', true],
129
+ ...globalStyles.filter((s) => s.initial).map((s) => [s.name, false]),
130
+ ...globalScripts.filter((s) => s.initial).map((s) => [s.name, false]),
131
+ ['main', true],
132
+ // [name, esm]
133
+ ],
144
134
  transformer: extensions?.indexHtmlTransformer,
145
135
  // Preload initial defaults to true
146
136
  preloadInitial: typeof options.index !== 'object' || (options.index.preloadInitial ?? true),
@@ -151,7 +141,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
151
141
  serverEntryPoint = node_path_1.default.join(workspaceRoot, options.server);
152
142
  }
153
143
  else if (options.server === '') {
154
- throw new Error('`server` option cannot be an empty string.');
144
+ throw new Error('The "server" option cannot be an empty string.');
155
145
  }
156
146
  let prerenderOptions;
157
147
  if (options.prerender) {
@@ -177,6 +167,9 @@ async function normalizeOptions(context, projectName, options, extensions) {
177
167
  route: 'shell',
178
168
  };
179
169
  }
170
+ if ((appShellOptions || ssrOptions || prerenderOptions) && !serverEntryPoint) {
171
+ throw new Error('The "server" option is required when enabling "ssr", "prerender" or "app-shell".');
172
+ }
180
173
  // Initial options to keep
181
174
  const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, deleteOutputPath, namedChunks, budgets, deployUrl, clearScreen, define, } = options;
182
175
  // Return all the normalized options
@@ -225,7 +218,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
225
218
  i18nOptions,
226
219
  namedChunks,
227
220
  budgets: budgets?.length ? budgets : undefined,
228
- publicPath: deployUrl ? deployUrl : undefined,
221
+ publicPath: deployUrl,
229
222
  plugins: extensions?.codePlugins?.length ? extensions?.codePlugins : undefined,
230
223
  loaderExtensions,
231
224
  jsonLogs: environment_options_1.useJSONBuildLogs,
@@ -324,3 +317,33 @@ function normalizeDirectoryPath(path) {
324
317
  }
325
318
  return path;
326
319
  }
320
+ function normalizeGlobalEntries(rawEntries, defaultName) {
321
+ if (!rawEntries?.length) {
322
+ return [];
323
+ }
324
+ const bundles = new Map();
325
+ for (const rawEntry of rawEntries) {
326
+ let entry;
327
+ if (typeof rawEntry === 'string') {
328
+ // string entries use default bundle name and inject values
329
+ entry = { input: rawEntry };
330
+ }
331
+ else {
332
+ entry = rawEntry;
333
+ }
334
+ const { bundleName, input, inject = true } = entry;
335
+ // Non-injected entries default to the file name
336
+ const name = bundleName || (inject ? defaultName : node_path_1.default.basename(input, node_path_1.default.extname(input)));
337
+ const existing = bundles.get(name);
338
+ if (!existing) {
339
+ bundles.set(name, { name, files: [input], initial: inject });
340
+ continue;
341
+ }
342
+ if (existing.initial !== inject) {
343
+ throw new Error(`The "${name}" bundle is mixing injected and non-injected entries. ` +
344
+ 'Verify that the project options are correct.');
345
+ }
346
+ existing.files.push(input);
347
+ }
348
+ return [...bundles.values()];
349
+ }
@@ -54,6 +54,12 @@ export interface Schema {
54
54
  * Delete the output path before building.
55
55
  */
56
56
  deleteOutputPath?: boolean;
57
+ /**
58
+ * Customize the base path for the URLs of resources in 'index.html' and component
59
+ * stylesheets. This option is only necessary for specific deployment scenarios, such as
60
+ * with Angular Elements or when utilizing different CDN locations.
61
+ */
62
+ deployUrl?: string;
57
63
  /**
58
64
  * Exclude the listed external dependencies from being bundled into the bundle. Instead, the
59
65
  * created bundle relies on these dependencies to be available during runtime.
@@ -33,6 +33,10 @@
33
33
  "type": "string",
34
34
  "description": "The full path for the TypeScript configuration file, relative to the current workspace."
35
35
  },
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
+ },
36
40
  "scripts": {
37
41
  "description": "Global scripts to be included in the build.",
38
42
  "type": "array",
@@ -60,7 +60,7 @@ const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
60
60
  * Maximum time in milliseconds for single build/rebuild
61
61
  * This accounts for CI variability.
62
62
  */
63
- exports.BUILD_TIMEOUT = 30000;
63
+ exports.BUILD_TIMEOUT = 30_000;
64
64
  async function initialize(options, context, webpackConfigurationTransform) {
65
65
  const originalOutputPath = options.outputPath;
66
66
  // Assets are processed directly by the builder except when watching
@@ -41,9 +41,9 @@ export interface Schema {
41
41
  */
42
42
  deleteOutputPath?: boolean;
43
43
  /**
44
- * URL where files will be deployed.
45
- * @deprecated Use "baseHref" option, "APP_BASE_HREF" DI token or a combination of both
46
- * instead. For more information, see https://angular.io/guide/deployment#the-deploy-url.
44
+ * Customize the base path for the URLs of resources in 'index.html' and component
45
+ * stylesheets. This option is only necessary for specific deployment scenarios, such as
46
+ * with Angular Elements or when utilizing different CDN locations.
47
47
  */
48
48
  deployUrl?: string;
49
49
  /**
@@ -270,8 +270,7 @@
270
270
  },
271
271
  "deployUrl": {
272
272
  "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."
275
274
  },
276
275
  "verbose": {
277
276
  "type": "boolean",
@@ -41,9 +41,9 @@ export interface Schema {
41
41
  */
42
42
  deleteOutputPath?: boolean;
43
43
  /**
44
- * URL where files will be deployed.
45
- * @deprecated Use "baseHref" option, "APP_BASE_HREF" DI token or a combination of both
46
- * instead. For more information, see https://angular.io/guide/deployment#the-deploy-url.
44
+ * Customize the base path for the URLs of resources in 'index.html' and component
45
+ * stylesheets. This option is only necessary for specific deployment scenarios, such as
46
+ * with Angular Elements or when utilizing different CDN locations.
47
47
  */
48
48
  deployUrl?: string;
49
49
  /**
@@ -277,8 +277,7 @@
277
277
  },
278
278
  "deployUrl": {
279
279
  "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."
282
281
  },
283
282
  "verbose": {
284
283
  "type": "boolean",
@@ -54,19 +54,28 @@ function execute(options, context, transforms = {}, extensions) {
54
54
  // Determine project name from builder context target
55
55
  const projectName = context.target?.project;
56
56
  if (!projectName) {
57
- context.logger.error(`The 'dev-server' builder requires a target to be specified.`);
57
+ context.logger.error(`The "dev-server" builder requires a target to be specified.`);
58
58
  return rxjs_1.EMPTY;
59
59
  }
60
60
  return (0, rxjs_1.defer)(() => initialize(options, projectName, context, extensions?.builderSelector)).pipe((0, rxjs_1.switchMap)(({ builderName, normalizedOptions }) => {
61
61
  // Use vite-based development server for esbuild-based builds
62
62
  if (isEsbuildBased(builderName)) {
63
63
  if (transforms?.logging || transforms?.webpackConfiguration) {
64
- throw new Error('The `application` and `browser-esbuild` builders do not support Webpack transforms.');
64
+ throw new Error(`The "application" and "browser-esbuild" builders do not support Webpack transforms.`);
65
65
  }
66
66
  // Warn if the initial options provided by the user enable prebundling but caching is disabled
67
67
  if (options.prebundle && !normalizedOptions.cacheOptions.enabled) {
68
68
  context.logger.warn(`Prebundling has been configured but will not be used because caching has been disabled.`);
69
69
  }
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.`);
72
+ }
73
+ if (options.publicHost) {
74
+ context.logger.warn(`The "publicHost" option will not be used because it is not supported by the "${builderName}" builder.`);
75
+ }
76
+ if (options.disableHostCheck) {
77
+ context.logger.warn(`The "disableHostCheck" option will not be used because it is not supported by the "${builderName}" builder.`);
78
+ }
70
79
  return (0, rxjs_1.defer)(() => Promise.resolve().then(() => __importStar(require('./vite-server')))).pipe((0, rxjs_1.switchMap)(({ serveWithVite }) => serveWithVite(normalizedOptions, builderName, context, transforms, extensions)));
71
80
  }
72
81
  // Warn if the initial options provided by the user enable prebundling with Webpack-based builders
@@ -74,10 +83,10 @@ function execute(options, context, transforms = {}, extensions) {
74
83
  context.logger.warn(`Prebundling has been configured but will not be used because it is not supported by the "${builderName}" builder.`);
75
84
  }
76
85
  if (extensions?.buildPlugins?.length) {
77
- throw new Error('Only the `application` and `browser-esbuild` builders support plugins.');
86
+ throw new Error('Only the "application" and "browser-esbuild" builders support plugins.');
78
87
  }
79
88
  if (extensions?.middleware?.length) {
80
- throw new Error('Only the `application` and `browser-esbuild` builders support middleware.');
89
+ throw new Error('Only the "application" and "browser-esbuild" builders support middleware.');
81
90
  }
82
91
  // Use Webpack for all other browser targets
83
92
  return (0, rxjs_1.defer)(() => Promise.resolve().then(() => __importStar(require('./webpack-server')))).pipe((0, rxjs_1.switchMap)(({ serveWebpackBrowser }) => serveWebpackBrowser(normalizedOptions, builderName, context, transforms)));
@@ -3,7 +3,8 @@
3
3
  */
4
4
  export interface Schema {
5
5
  /**
6
- * List of hosts that are allowed to access the dev server.
6
+ * List of hosts that are allowed to access the dev server. This option has no effect when
7
+ * using the 'application' or other esbuild-based builders.
7
8
  */
8
9
  allowedHosts?: string[];
9
10
  /**
@@ -20,7 +21,8 @@ export interface Schema {
20
21
  */
21
22
  buildTarget?: string;
22
23
  /**
23
- * Don't verify connected clients are part of allowed hosts.
24
+ * Don't verify connected clients are part of allowed hosts. This option has no effect when
25
+ * using the 'application' or other esbuild-based builders.
24
26
  */
25
27
  disableHostCheck?: boolean;
26
28
  /**
@@ -72,7 +74,8 @@ export interface Schema {
72
74
  /**
73
75
  * The URL that the browser client (or live-reload client, if enabled) should use to connect
74
76
  * to the development server. Use for a complex dev server setup, such as one with reverse
75
- * proxies.
77
+ * proxies. This option has no effect when using the 'application' or other esbuild-based
78
+ * builders.
76
79
  */
77
80
  publicHost?: string;
78
81
  /**
@@ -69,11 +69,11 @@
69
69
  },
70
70
  "publicHost": {
71
71
  "type": "string",
72
- "description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies."
72
+ "description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies. This option has no effect when using the 'application' or other esbuild-based builders."
73
73
  },
74
74
  "allowedHosts": {
75
75
  "type": "array",
76
- "description": "List of hosts that are allowed to access the dev server.",
76
+ "description": "List of hosts that are allowed to access the dev server. This option has no effect when using the 'application' or other esbuild-based builders.",
77
77
  "default": [],
78
78
  "items": {
79
79
  "type": "string"
@@ -85,7 +85,7 @@
85
85
  },
86
86
  "disableHostCheck": {
87
87
  "type": "boolean",
88
- "description": "Don't verify connected clients are part of allowed hosts.",
88
+ "description": "Don't verify connected clients are part of allowed hosts. This option has no effect when using the 'application' or other esbuild-based builders.",
89
89
  "default": false
90
90
  },
91
91
  "hmr": {
@@ -373,6 +373,10 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
373
373
  // the Vite client-side code for browser reloading. These would be available by default but when
374
374
  // the `allow` option is explicitly configured, they must be included manually.
375
375
  allow: [cacheDir, (0, node_path_1.join)(serverOptions.workspaceRoot, 'node_modules'), ...assets.values()],
376
+ // Temporary disable cached FS checks.
377
+ // This is because we configure `config.base` to a virtual directory which causes `getRealPath` to fail.
378
+ // See: https://github.com/vitejs/vite/blob/b2873ac3936de25ca8784327cb9ef16bd4881805/packages/vite/src/node/fsUtils.ts#L45-L67
379
+ cachedChecks: false,
376
380
  },
377
381
  // This is needed when `externalDependencies` is used to prevent Vite load errors.
378
382
  // NOTE: If Vite adds direct support for externals, this can be removed.
@@ -418,7 +422,6 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
418
422
  external: externalMetadata.explicit,
419
423
  indexHtmlTransformer,
420
424
  extensionMiddleware,
421
- extraHeaders: serverOptions.headers,
422
425
  normalizePath,
423
426
  }),
424
427
  ],
@@ -474,12 +477,12 @@ function getDepOptimizationConfig({ disabled, exclude, include, target, prebundl
474
477
  plugins.unshift((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
475
478
  }
476
479
  return {
477
- // Only enable with caching since it causes prebundle dependencies to be cached
478
- disabled,
479
480
  // Exclude any explicitly defined dependencies (currently build defined externals)
480
481
  exclude,
482
+ // NB: to disable the deps optimizer, set optimizeDeps.noDiscovery to true and optimizeDeps.include as undefined.
481
483
  // Include all implict dependencies from the external packages internal option
482
- include,
484
+ include: disabled ? undefined : include,
485
+ noDiscovery: disabled,
483
486
  // Add an esbuild plugin to run the Angular linker on dependencies
484
487
  esbuildOptions: {
485
488
  // Set esbuild supported targets.
@@ -69,6 +69,7 @@ async function getRoutes(indexFile, outputPath, serverBundlePath, options, works
69
69
  serverBundlePath,
70
70
  zonePackage: require.resolve('zone.js', { paths: [workspaceRoot] }),
71
71
  },
72
+ recordTiming: false,
72
73
  });
73
74
  const extractedRoutes = await renderWorker
74
75
  .run({})
@@ -140,6 +141,7 @@ async function _renderUniversal(options, context, browserResult, serverResult, b
140
141
  filename: path.join(__dirname, 'render-worker.js'),
141
142
  maxThreads: environment_options_1.maxWorkers,
142
143
  workerData: { zonePackage },
144
+ recordTiming: false,
143
145
  });
144
146
  let routes;
145
147
  try {