@angular-devkit/build-angular 17.3.0-rc.0 → 17.3.1

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.
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "17.3.0-rc.0",
3
+ "version": "17.3.1",
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-rc.0",
11
- "@angular-devkit/build-webpack": "0.1703.0-rc.0",
12
- "@angular-devkit/core": "17.3.0-rc.0",
10
+ "@angular-devkit/architect": "0.1703.1",
11
+ "@angular-devkit/build-webpack": "0.1703.1",
12
+ "@angular-devkit/core": "17.3.1",
13
13
  "@babel/core": "7.24.0",
14
14
  "@babel/generator": "7.23.6",
15
15
  "@babel/helper-annotate-as-pure": "7.22.5",
@@ -20,7 +20,7 @@
20
20
  "@babel/preset-env": "7.24.0",
21
21
  "@babel/runtime": "7.24.0",
22
22
  "@discoveryjs/json-ext": "0.5.7",
23
- "@ngtools/webpack": "17.3.0-rc.0",
23
+ "@ngtools/webpack": "17.3.1",
24
24
  "@vitejs/plugin-basic-ssl": "1.1.0",
25
25
  "ansi-colors": "4.1.3",
26
26
  "autoprefixer": "10.4.18",
@@ -28,7 +28,7 @@
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
33
  "esbuild-wasm": "0.20.1",
34
34
  "fast-glob": "3.3.2",
@@ -58,10 +58,10 @@
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.28.1",
61
+ "terser": "5.29.1",
62
62
  "tree-kill": "1.2.2",
63
63
  "tslib": "2.6.2",
64
- "undici": "6.7.0",
64
+ "undici": "6.7.1",
65
65
  "vite": "5.1.5",
66
66
  "watchpack": "2.4.0",
67
67
  "webpack": "5.90.3",
@@ -74,16 +74,16 @@
74
74
  "esbuild": "0.20.1"
75
75
  },
76
76
  "peerDependencies": {
77
- "@angular/compiler-cli": "^17.0.0 || ^17.3.0-next.0",
78
- "@angular/localize": "^17.0.0 || ^17.3.0-next.0",
79
- "@angular/platform-server": "^17.0.0 || ^17.3.0-next.0",
80
- "@angular/service-worker": "^17.0.0 || ^17.3.0-next.0",
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",
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 || ^17.3.0-next.0",
86
+ "ng-packagr": "^17.0.0",
87
87
  "protractor": "^7.0.0",
88
88
  "tailwindcss": "^2.0.0 || ^3.0.0",
89
89
  "typescript": ">=5.2 <5.5"
@@ -11,7 +11,8 @@ 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
+ type BuildActionOutput = (ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput;
15
+ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildState) => Promise<ExecutionResult>, options: {
15
16
  workspaceRoot: string;
16
17
  projectRoot: string;
17
18
  outputOptions: NormalizedOutputOptions;
@@ -27,4 +28,7 @@ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildSta
27
28
  signal?: AbortSignal;
28
29
  preserveSymlinks?: boolean;
29
30
  clearScreen?: boolean;
30
- }): AsyncIterable<(ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput>;
31
+ colors?: boolean;
32
+ jsonLogs?: boolean;
33
+ }): AsyncIterable<BuildActionOutput>;
34
+ export {};
@@ -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
@@ -115,16 +117,7 @@ async function* runEsBuildBuildAction(action, options) {
115
117
  // Output the first build results after setting up the watcher to ensure that any code executed
116
118
  // higher in the iterator call stack will trigger the watcher. This is particularly relevant for
117
119
  // unit tests which execute the builder and modify the file system programmatically.
118
- if (writeToFileSystem) {
119
- // Write output files
120
- await (0, utils_1.writeResultFiles)(result.outputFiles, result.assetFiles, outputOptions);
121
- yield result.output;
122
- }
123
- else {
124
- // Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
125
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
- yield result.outputWithFiles;
127
- }
120
+ yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);
128
121
  // Finish if watch mode is not enabled
129
122
  if (!watcher) {
130
123
  return;
@@ -144,6 +137,8 @@ async function* runEsBuildBuildAction(action, options) {
144
137
  logger.info(changes.toDebugString());
145
138
  }
146
139
  result = await withProgress('Changes detected. Rebuilding...', () => action(result.createRebuildState(changes)));
140
+ // Log all diagnostic (error/warning/logs) messages
141
+ await (0, utils_1.logMessages)(logger, result, colors, jsonLogs);
147
142
  // Update watched locations provided by the new build result.
148
143
  // Keep watching all previous files if there are any errors; otherwise consider all
149
144
  // files stale until confirmed present in the new result's watch files.
@@ -161,19 +156,7 @@ async function* runEsBuildBuildAction(action, options) {
161
156
  if (staleWatchFiles?.size) {
162
157
  watcher.remove([...staleWatchFiles]);
163
158
  }
164
- if (writeToFileSystem) {
165
- // Write output files
166
- const filesToWrite = writeToFileSystemFilter
167
- ? result.outputFiles.filter(writeToFileSystemFilter)
168
- : result.outputFiles;
169
- await (0, utils_1.writeResultFiles)(filesToWrite, result.assetFiles, outputOptions);
170
- yield result.output;
171
- }
172
- else {
173
- // Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
174
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
175
- yield result.outputWithFiles;
176
- }
159
+ yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);
177
160
  }
178
161
  }
179
162
  finally {
@@ -183,3 +166,18 @@ async function* runEsBuildBuildAction(action, options) {
183
166
  }
184
167
  }
185
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
+ }
@@ -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.
@@ -141,7 +141,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
141
141
  serverEntryPoint = node_path_1.default.join(workspaceRoot, options.server);
142
142
  }
143
143
  else if (options.server === '') {
144
- throw new Error('`server` option cannot be an empty string.');
144
+ throw new Error('The "server" option cannot be an empty string.');
145
145
  }
146
146
  let prerenderOptions;
147
147
  if (options.prerender) {
@@ -167,6 +167,9 @@ async function normalizeOptions(context, projectName, options, extensions) {
167
167
  route: 'shell',
168
168
  };
169
169
  }
170
+ if ((appShellOptions || ssrOptions || prerenderOptions) && !serverEntryPoint) {
171
+ throw new Error('The "server" option is required when enabling "ssr", "prerender" or "app-shell".');
172
+ }
170
173
  // Initial options to keep
171
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;
172
175
  // Return all the normalized options
@@ -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 "allowedHosts" 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": {
@@ -422,7 +422,6 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
422
422
  external: externalMetadata.explicit,
423
423
  indexHtmlTransformer,
424
424
  extensionMiddleware,
425
- extraHeaders: serverOptions.headers,
426
425
  normalizePath,
427
426
  }),
428
427
  ],
@@ -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
  };
@@ -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)();
@@ -111,7 +111,7 @@ exports.createBrowserPolyfillBundleOptions = createBrowserPolyfillBundleOptions;
111
111
  * @returns An esbuild BuildOptions object.
112
112
  */
113
113
  function createServerCodeBundleOptions(options, target, sourceFileCache) {
114
- const { jit, serverEntryPoint, workspaceRoot, ssrOptions, watch, externalPackages, prerenderOptions, } = options;
114
+ const { serverEntryPoint, workspaceRoot, ssrOptions, watch, externalPackages, prerenderOptions } = options;
115
115
  (0, node_assert_1.default)(serverEntryPoint, 'createServerCodeBundleOptions should not be called without a defined serverEntryPoint.');
116
116
  const { pluginOptions, styleOptions } = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, target, sourceFileCache);
117
117
  const mainServerNamespace = 'angular:server-render-utils';
@@ -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);
@@ -35,10 +35,12 @@ export declare class ExecutionResult {
35
35
  errors: (Message | PartialMessage)[];
36
36
  prerenderedRoutes: string[];
37
37
  warnings: (Message | PartialMessage)[];
38
+ logs: string[];
38
39
  externalMetadata?: ExternalResultMetadata;
39
40
  constructor(rebuildContexts: BundlerContext[], codeBundleCache?: SourceFileCache | undefined);
40
41
  addOutputFile(path: string, content: string, type: BuildOutputFileType): void;
41
42
  addAssets(assets: BuildOutputAsset[]): void;
43
+ addLog(value: string): void;
42
44
  addError(error: PartialMessage | string): void;
43
45
  addErrors(errors: (PartialMessage | string)[]): void;
44
46
  addPrerenderedRoutes(routes: string[]): void;
@@ -21,6 +21,7 @@ class ExecutionResult {
21
21
  errors = [];
22
22
  prerenderedRoutes = [];
23
23
  warnings = [];
24
+ logs = [];
24
25
  externalMetadata;
25
26
  constructor(rebuildContexts, codeBundleCache) {
26
27
  this.rebuildContexts = rebuildContexts;
@@ -32,6 +33,9 @@ class ExecutionResult {
32
33
  addAssets(assets) {
33
34
  this.assetFiles.push(...assets);
34
35
  }
36
+ addLog(value) {
37
+ this.logs.push(value);
38
+ }
35
39
  addError(error) {
36
40
  if (typeof error === 'string') {
37
41
  this.errors.push({ text: error, location: null });
@@ -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;
@@ -37,4 +37,5 @@ export declare function transformSupportedBrowsersToTargets(supportedBrowsers: s
37
37
  * @see https://esbuild.github.io/api/#target
38
38
  */
39
39
  export declare function getSupportedNodeTargets(): string[];
40
- export declare function logMessages(logger: logging.LoggerApi, executionResult: ExecutionResult, options: NormalizedApplicationBuildOptions): Promise<void>;
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>;
@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  return (mod && mod.__esModule) ? mod : { "default": mod };
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.logMessages = exports.getSupportedNodeTargets = exports.transformSupportedBrowsersToTargets = exports.convertOutputFile = exports.createOutputFileFromData = exports.createOutputFileFromText = exports.emitFilesToDisk = exports.writeResultFiles = exports.getFeatureSupport = exports.withNoProgress = exports.withSpinner = exports.calculateEstimatedTransferSizes = exports.logBuildStats = void 0;
13
+ exports.logMessages = exports.createJsonBuildManifest = exports.getSupportedNodeTargets = exports.transformSupportedBrowsersToTargets = exports.convertOutputFile = exports.createOutputFileFromData = exports.createOutputFileFromText = exports.emitFilesToDisk = exports.writeResultFiles = exports.getFeatureSupport = exports.withNoProgress = exports.withSpinner = exports.calculateEstimatedTransferSizes = exports.logBuildStats = void 0;
14
14
  const esbuild_1 = require("esbuild");
15
15
  const node_crypto_1 = require("node:crypto");
16
16
  const node_fs_1 = require("node:fs");
@@ -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);
@@ -344,33 +344,35 @@ function getSupportedNodeTargets() {
344
344
  return SUPPORTED_NODE_VERSIONS.split('||').map((v) => 'node' + (0, semver_1.coerce)(v)?.version);
345
345
  }
346
346
  exports.getSupportedNodeTargets = getSupportedNodeTargets;
347
- async function logMessages(logger, executionResult, options) {
348
- const { outputOptions: { base, server, browser }, ssrOptions, jsonLogs, colors: color, } = options;
349
- const { warnings, errors, prerenderedRoutes } = executionResult;
350
- const warningMessages = warnings.length
351
- ? await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color })
352
- : [];
353
- const errorMessages = errors.length ? await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color }) : [];
347
+ async function createJsonBuildManifest(result, normalizedOptions) {
348
+ const { colors: color, outputOptions: { base, server, browser }, ssrOptions, } = normalizedOptions;
349
+ const { warnings, errors, prerenderedRoutes } = result;
350
+ const manifest = {
351
+ errors: errors.length ? await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color }) : [],
352
+ warnings: warnings.length ? await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color }) : [],
353
+ outputPaths: {
354
+ root: (0, node_url_1.pathToFileURL)(base),
355
+ browser: (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, browser)),
356
+ server: ssrOptions ? (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, server)) : undefined,
357
+ },
358
+ prerenderedRoutes,
359
+ };
360
+ return JSON.stringify(manifest, undefined, 2);
361
+ }
362
+ exports.createJsonBuildManifest = createJsonBuildManifest;
363
+ async function logMessages(logger, executionResult, color, jsonLogs) {
364
+ const { warnings, errors, logs } = executionResult;
365
+ if (logs.length) {
366
+ logger.info(logs.join('\n'));
367
+ }
354
368
  if (jsonLogs) {
355
- // JSON format output
356
- const manifest = {
357
- errors: errorMessages,
358
- warnings: warningMessages,
359
- outputPaths: {
360
- root: (0, node_url_1.pathToFileURL)(base),
361
- browser: (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, browser)),
362
- server: ssrOptions ? (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, server)) : undefined,
363
- },
364
- prerenderedRoutes,
365
- };
366
- logger.info(JSON.stringify(manifest, undefined, 2));
367
369
  return;
368
370
  }
369
- if (warningMessages.length) {
370
- logger.warn(warningMessages.join('\n'));
371
+ if (warnings.length) {
372
+ logger.warn((await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color })).join('\n'));
371
373
  }
372
- if (errorMessages.length) {
373
- logger.error(errorMessages.join('\n'));
374
+ if (errors.length) {
375
+ logger.error((await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color })).join('\n'));
374
376
  }
375
377
  }
376
378
  exports.logMessages = logMessages;
@@ -0,0 +1,10 @@
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
+ import { MainServerBundleExports, RenderUtilsServerBundleExports } from './main-bundle-exports';
9
+ export declare function loadEsmModuleFromMemory(path: './main.server.mjs'): Promise<MainServerBundleExports>;
10
+ export declare function loadEsmModuleFromMemory(path: './render-utils.server.mjs'): Promise<RenderUtilsServerBundleExports>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.io/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.loadEsmModuleFromMemory = void 0;
11
+ const error_1 = require("../error");
12
+ const load_esm_1 = require("../load-esm");
13
+ function loadEsmModuleFromMemory(path) {
14
+ return (0, load_esm_1.loadEsmModule)(new URL(path, 'memory://')).catch((e) => {
15
+ (0, error_1.assertIsError)(e);
16
+ // While the error is an 'instanceof Error', it is extended with non transferable properties
17
+ // and cannot be transferred from a worker when using `--import`. This results in the error object
18
+ // displaying as '[Object object]' when read outside of the worker. Therefore, we reconstruct the error message here.
19
+ const error = new Error(e.message);
20
+ error.stack = e.stack;
21
+ error.name = e.name;
22
+ error.code = e.code;
23
+ throw error;
24
+ });
25
+ }
26
+ exports.loadEsmModuleFromMemory = loadEsmModuleFromMemory;
@@ -36,11 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.renderPage = void 0;
37
37
  const node_assert_1 = __importDefault(require("node:assert"));
38
38
  const node_path_1 = require("node:path");
39
- const load_esm_1 = require("../load-esm");
39
+ const load_esm_from_memory_1 = require("./load-esm-from-memory");
40
40
  /**
41
41
  * Renders each route in routes and writes them to <outputPath>/<route>/index.html.
42
42
  */
43
- async function renderPage({ route, serverContext, document, inlineCriticalCss, outputFiles, loadBundle = load_esm_1.loadEsmModule, }) {
43
+ async function renderPage({ route, serverContext, document, inlineCriticalCss, outputFiles, loadBundle = load_esm_from_memory_1.loadEsmModuleFromMemory, }) {
44
44
  const { default: bootstrapAppFnOrModule } = await loadBundle('./main.server.mjs');
45
45
  const { ɵSERVER_CONTEXT, renderModule, renderApplication, ɵresetCompiledComponents, ɵConsole } = await loadBundle('./render-utils.server.mjs');
46
46
  // Need to clean up GENERATED_COMP_IDS map in `@angular/core`.
@@ -8,7 +8,6 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  const node_worker_threads_1 = require("node:worker_threads");
11
- const load_esm_1 = require("../load-esm");
12
11
  const fetch_patch_1 = require("./fetch-patch");
13
12
  const render_page_1 = require("./render-page");
14
13
  /**
@@ -22,7 +21,6 @@ function render(options) {
22
21
  outputFiles,
23
22
  document,
24
23
  inlineCriticalCss,
25
- loadBundle: async (path) => await (0, load_esm_1.loadEsmModule)(new URL(path, 'memory://')),
26
24
  });
27
25
  }
28
26
  function initialize() {
@@ -8,16 +8,16 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  const node_worker_threads_1 = require("node:worker_threads");
11
- const load_esm_1 = require("../load-esm");
12
11
  const fetch_patch_1 = require("./fetch-patch");
12
+ const load_esm_from_memory_1 = require("./load-esm-from-memory");
13
13
  /**
14
14
  * This is passed as workerData when setting up the worker via the `piscina` package.
15
15
  */
16
16
  const { document, verbose } = node_worker_threads_1.workerData;
17
17
  /** Renders an application based on a provided options. */
18
18
  async function extractRoutes() {
19
- const { extractRoutes } = await (0, load_esm_1.loadEsmModule)(new URL('./render-utils.server.mjs', 'memory://'));
20
- const { default: bootstrapAppFnOrModule } = await (0, load_esm_1.loadEsmModule)(new URL('./main.server.mjs', 'memory://'));
19
+ const { extractRoutes } = await (0, load_esm_from_memory_1.loadEsmModuleFromMemory)('./render-utils.server.mjs');
20
+ const { default: bootstrapAppFnOrModule } = await (0, load_esm_from_memory_1.loadEsmModuleFromMemory)('./main.server.mjs');
21
21
  const skippedRedirects = [];
22
22
  const skippedOthers = [];
23
23
  const routes = [];