@angular/build 19.0.0-rc.0 → 19.0.0-rc.2

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 (52) hide show
  1. package/package.json +8 -8
  2. package/src/builders/application/build-action.js +13 -1
  3. package/src/builders/application/execute-build.js +38 -31
  4. package/src/builders/application/execute-post-bundle.js +17 -14
  5. package/src/builders/application/options.d.ts +10 -1
  6. package/src/builders/application/options.js +9 -0
  7. package/src/builders/application/setup-bundling.d.ts +4 -1
  8. package/src/builders/application/setup-bundling.js +18 -11
  9. package/src/builders/dev-server/options.d.ts +2 -2
  10. package/src/builders/dev-server/options.js +2 -2
  11. package/src/builders/dev-server/schema.d.ts +2 -1
  12. package/src/builders/dev-server/schema.json +1 -2
  13. package/src/builders/dev-server/vite-server.d.ts +2 -1
  14. package/src/builders/dev-server/vite-server.js +94 -61
  15. package/src/tools/angular/angular-host.js +13 -2
  16. package/src/tools/esbuild/angular/compiler-plugin.d.ts +1 -0
  17. package/src/tools/esbuild/angular/compiler-plugin.js +24 -4
  18. package/src/tools/esbuild/angular/component-stylesheets.d.ts +1 -0
  19. package/src/tools/esbuild/angular/component-stylesheets.js +3 -0
  20. package/src/tools/esbuild/angular/source-file-cache.d.ts +1 -1
  21. package/src/tools/esbuild/angular/source-file-cache.js +6 -2
  22. package/src/tools/esbuild/application-code-bundle.d.ts +5 -4
  23. package/src/tools/esbuild/application-code-bundle.js +245 -239
  24. package/src/tools/esbuild/bundler-execution-result.d.ts +10 -2
  25. package/src/tools/esbuild/bundler-execution-result.js +12 -9
  26. package/src/tools/esbuild/compiler-plugin-options.d.ts +2 -1
  27. package/src/tools/esbuild/compiler-plugin-options.js +3 -2
  28. package/src/tools/esbuild/javascript-transformer.js +2 -1
  29. package/src/tools/esbuild/server-bundle-metadata-plugin.d.ts +1 -1
  30. package/src/tools/esbuild/server-bundle-metadata-plugin.js +1 -1
  31. package/src/tools/sass/rebasing-importer.js +1 -1
  32. package/src/tools/vite/middlewares/assets-middleware.d.ts +6 -1
  33. package/src/tools/vite/middlewares/assets-middleware.js +27 -23
  34. package/src/tools/vite/middlewares/component-middleware.js +1 -1
  35. package/src/tools/vite/middlewares/index.d.ts +1 -1
  36. package/src/tools/vite/middlewares/ssr-middleware.js +5 -2
  37. package/src/tools/vite/plugins/angular-memory-plugin.d.ts +1 -0
  38. package/src/tools/vite/plugins/angular-memory-plugin.js +5 -13
  39. package/src/tools/vite/plugins/setup-middlewares-plugin.d.ts +2 -1
  40. package/src/tools/vite/plugins/setup-middlewares-plugin.js +11 -3
  41. package/src/utils/environment-options.d.ts +1 -0
  42. package/src/utils/environment-options.js +3 -1
  43. package/src/utils/normalize-cache.js +1 -1
  44. package/src/utils/server-rendering/esm-in-memory-loader/utils.d.ts +8 -0
  45. package/src/utils/server-rendering/esm-in-memory-loader/utils.js +13 -0
  46. package/src/utils/server-rendering/manifest.d.ts +9 -8
  47. package/src/utils/server-rendering/manifest.js +17 -23
  48. package/src/utils/server-rendering/models.d.ts +1 -0
  49. package/src/utils/server-rendering/models.js +3 -4
  50. package/src/utils/server-rendering/prerender.js +41 -32
  51. package/src/utils/server-rendering/render-worker.js +4 -2
  52. package/src/utils/server-rendering/routes-extractor-worker.js +2 -1
@@ -32,54 +32,56 @@ const sourcemap_ignorelist_plugin_1 = require("./sourcemap-ignorelist-plugin");
32
32
  const utils_1 = require("./utils");
33
33
  const virtual_module_plugin_1 = require("./virtual-module-plugin");
34
34
  const wasm_plugin_1 = require("./wasm-plugin");
35
- function createBrowserCodeBundleOptions(options, target, sourceFileCache, stylesheetBundler) {
36
- const { entryPoints, outputNames, polyfills } = options;
37
- const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache);
38
- const zoneless = (0, utils_1.isZonelessApp)(polyfills);
39
- const buildOptions = {
40
- ...getEsBuildCommonOptions(options),
41
- platform: 'browser',
42
- // Note: `es2015` is needed for RxJS v6. If not specified, `module` would
43
- // match and the ES5 distribution would be bundled and ends up breaking at
44
- // runtime with the RxJS testing library.
45
- // More details: https://github.com/angular/angular-cli/issues/25405.
46
- mainFields: ['es2020', 'es2015', 'browser', 'module', 'main'],
47
- entryNames: outputNames.bundles,
48
- entryPoints,
49
- target,
50
- supported: (0, utils_1.getFeatureSupport)(target, zoneless),
51
- plugins: [
52
- (0, loader_import_attribute_plugin_1.createLoaderImportAttributePlugin)(),
53
- (0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: sourceFileCache?.loadResultCache }),
54
- (0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
55
- (0, compiler_plugin_1.createCompilerPlugin)(
56
- // JS/TS options
57
- pluginOptions,
58
- // Component stylesheet bundler
59
- stylesheetBundler),
60
- ],
61
- };
62
- if (options.plugins) {
63
- buildOptions.plugins?.push(...options.plugins);
64
- }
65
- if (options.externalPackages) {
66
- // Package files affected by a customized loader should not be implicitly marked as external
67
- if (options.loaderExtensions ||
68
- options.plugins ||
69
- typeof options.externalPackages === 'object') {
70
- // Plugin must be added after custom plugins to ensure any added loader options are considered
71
- buildOptions.plugins?.push((0, external_packages_plugin_1.createExternalPackagesPlugin)(options.externalPackages !== true ? options.externalPackages : undefined));
35
+ function createBrowserCodeBundleOptions(options, target, sourceFileCache, stylesheetBundler, templateUpdates) {
36
+ return (loadCache) => {
37
+ const { entryPoints, outputNames, polyfills } = options;
38
+ const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache, loadCache, templateUpdates);
39
+ const zoneless = (0, utils_1.isZonelessApp)(polyfills);
40
+ const buildOptions = {
41
+ ...getEsBuildCommonOptions(options),
42
+ platform: 'browser',
43
+ // Note: `es2015` is needed for RxJS v6. If not specified, `module` would
44
+ // match and the ES5 distribution would be bundled and ends up breaking at
45
+ // runtime with the RxJS testing library.
46
+ // More details: https://github.com/angular/angular-cli/issues/25405.
47
+ mainFields: ['es2020', 'es2015', 'browser', 'module', 'main'],
48
+ entryNames: outputNames.bundles,
49
+ entryPoints,
50
+ target,
51
+ supported: (0, utils_1.getFeatureSupport)(target, zoneless),
52
+ plugins: [
53
+ (0, loader_import_attribute_plugin_1.createLoaderImportAttributePlugin)(),
54
+ (0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: loadCache }),
55
+ (0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
56
+ (0, compiler_plugin_1.createCompilerPlugin)(
57
+ // JS/TS options
58
+ pluginOptions,
59
+ // Component stylesheet bundler
60
+ stylesheetBundler),
61
+ ],
62
+ };
63
+ if (options.plugins) {
64
+ buildOptions.plugins?.push(...options.plugins);
72
65
  }
73
- else {
74
- // Safe to use the packages external option directly
75
- buildOptions.packages = 'external';
66
+ if (options.externalPackages) {
67
+ // Package files affected by a customized loader should not be implicitly marked as external
68
+ if (options.loaderExtensions ||
69
+ options.plugins ||
70
+ typeof options.externalPackages === 'object') {
71
+ // Plugin must be added after custom plugins to ensure any added loader options are considered
72
+ buildOptions.plugins?.push((0, external_packages_plugin_1.createExternalPackagesPlugin)(options.externalPackages !== true ? options.externalPackages : undefined));
73
+ }
74
+ else {
75
+ // Safe to use the packages external option directly
76
+ buildOptions.packages = 'external';
77
+ }
76
78
  }
77
- }
78
- return buildOptions;
79
+ return buildOptions;
80
+ };
79
81
  }
80
82
  function createBrowserPolyfillBundleOptions(options, target, sourceFileCache, stylesheetBundler) {
81
83
  const namespace = 'angular:polyfills';
82
- const polyfillBundleOptions = getEsBuildCommonPolyfillsOptions(options, namespace, true, sourceFileCache);
84
+ const polyfillBundleOptions = getEsBuildCommonPolyfillsOptions(options, namespace, true, sourceFileCache.loadResultCache);
83
85
  if (!polyfillBundleOptions) {
84
86
  return;
85
87
  }
@@ -114,7 +116,7 @@ function createBrowserPolyfillBundleOptions(options, target, sourceFileCache, st
114
116
  // cannot be used with fully incremental bundling yet.
115
117
  return hasTypeScriptEntries ? buildOptions : () => buildOptions;
116
118
  }
117
- function createServerPolyfillBundleOptions(options, target, sourceFileCache) {
119
+ function createServerPolyfillBundleOptions(options, target, loadResultCache) {
118
120
  const serverPolyfills = [];
119
121
  const polyfillsFromConfig = new Set(options.polyfills);
120
122
  const isNodePlatform = options.ssrOptions?.platform !== schema_1.ExperimentalPlatform.Neutral;
@@ -130,7 +132,7 @@ function createServerPolyfillBundleOptions(options, target, sourceFileCache) {
130
132
  const polyfillBundleOptions = getEsBuildCommonPolyfillsOptions({
131
133
  ...options,
132
134
  polyfills: serverPolyfills,
133
- }, namespace, false, sourceFileCache);
135
+ }, namespace, false, loadResultCache);
134
136
  if (!polyfillBundleOptions) {
135
137
  return;
136
138
  }
@@ -166,210 +168,214 @@ function createServerPolyfillBundleOptions(options, target, sourceFileCache) {
166
168
  function createServerMainCodeBundleOptions(options, target, sourceFileCache, stylesheetBundler) {
167
169
  const { serverEntryPoint: mainServerEntryPoint, workspaceRoot, outputMode, externalPackages, ssrOptions, polyfills, } = options;
168
170
  (0, node_assert_1.default)(mainServerEntryPoint, 'createServerCodeBundleOptions should not be called without a defined serverEntryPoint.');
169
- const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache);
170
- const mainServerNamespace = 'angular:main-server';
171
- const mainServerInjectPolyfillsNamespace = 'angular:main-server-inject-polyfills';
172
- const mainServerInjectManifestNamespace = 'angular:main-server-inject-manifest';
173
- const zoneless = (0, utils_1.isZonelessApp)(polyfills);
174
- const entryPoints = {
175
- 'main.server': mainServerNamespace,
176
- };
177
- const ssrEntryPoint = ssrOptions?.entry;
178
- const isOldBehaviour = !outputMode;
179
- if (ssrEntryPoint && isOldBehaviour) {
180
- // Old behavior: 'server.ts' was bundled together with the SSR (Server-Side Rendering) code.
181
- // This approach combined server-side logic and rendering into a single bundle.
182
- entryPoints['server'] = ssrEntryPoint;
183
- }
184
- const buildOptions = {
185
- ...getEsBuildServerCommonOptions(options),
186
- target,
187
- inject: [mainServerInjectPolyfillsNamespace, mainServerInjectManifestNamespace],
188
- entryPoints,
189
- supported: (0, utils_1.getFeatureSupport)(target, zoneless),
190
- plugins: [
191
- (0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: sourceFileCache?.loadResultCache }),
192
- (0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
193
- (0, compiler_plugin_1.createCompilerPlugin)(
194
- // JS/TS options
195
- { ...pluginOptions, noopTypeScriptCompilation: true },
196
- // Component stylesheet bundler
197
- stylesheetBundler),
198
- ],
199
- };
200
- buildOptions.plugins ??= [];
201
- if (externalPackages) {
202
- buildOptions.packages = 'external';
203
- }
204
- else {
205
- buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
206
- }
207
- // Mark manifest and polyfills file as external as these are generated by a different bundle step.
208
- (buildOptions.external ??= []).push(...utils_1.SERVER_GENERATED_EXTERNALS);
209
- const isNodePlatform = options.ssrOptions?.platform !== schema_1.ExperimentalPlatform.Neutral;
210
- if (!isNodePlatform) {
211
- // `@angular/platform-server` lazily depends on `xhr2` for XHR usage with the HTTP client.
212
- // Since `xhr2` has Node.js dependencies, it cannot be used when targeting non-Node.js platforms.
213
- // Note: The framework already issues a warning when using XHR with SSR.
214
- buildOptions.external.push('xhr2');
215
- }
216
- buildOptions.plugins.push((0, server_bundle_metadata_plugin_1.createServerBundleMetadata)(), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
217
- namespace: mainServerInjectPolyfillsNamespace,
218
- cache: sourceFileCache?.loadResultCache,
219
- loadContent: () => ({
220
- contents: `import './polyfills.server.mjs';`,
221
- loader: 'js',
222
- resolveDir: workspaceRoot,
223
- }),
224
- }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
225
- namespace: mainServerInjectManifestNamespace,
226
- cache: sourceFileCache?.loadResultCache,
227
- loadContent: async () => {
228
- const contents = [
229
- // Configure `@angular/ssr` manifest.
230
- `import manifest from './${manifest_1.SERVER_APP_MANIFEST_FILENAME}';`,
231
- `import { ɵsetAngularAppManifest } from '@angular/ssr';`,
232
- `ɵsetAngularAppManifest(manifest);`,
233
- ];
234
- return {
235
- contents: contents.join('\n'),
171
+ return (loadResultCache) => {
172
+ const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache, loadResultCache);
173
+ const mainServerNamespace = 'angular:main-server';
174
+ const mainServerInjectPolyfillsNamespace = 'angular:main-server-inject-polyfills';
175
+ const mainServerInjectManifestNamespace = 'angular:main-server-inject-manifest';
176
+ const zoneless = (0, utils_1.isZonelessApp)(polyfills);
177
+ const entryPoints = {
178
+ 'main.server': mainServerNamespace,
179
+ };
180
+ const ssrEntryPoint = ssrOptions?.entry;
181
+ const isOldBehaviour = !outputMode;
182
+ if (ssrEntryPoint && isOldBehaviour) {
183
+ // Old behavior: 'server.ts' was bundled together with the SSR (Server-Side Rendering) code.
184
+ // This approach combined server-side logic and rendering into a single bundle.
185
+ entryPoints['server'] = ssrEntryPoint;
186
+ }
187
+ const buildOptions = {
188
+ ...getEsBuildServerCommonOptions(options),
189
+ target,
190
+ inject: [mainServerInjectPolyfillsNamespace, mainServerInjectManifestNamespace],
191
+ entryPoints,
192
+ supported: (0, utils_1.getFeatureSupport)(target, zoneless),
193
+ plugins: [
194
+ (0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: loadResultCache }),
195
+ (0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
196
+ (0, compiler_plugin_1.createCompilerPlugin)(
197
+ // JS/TS options
198
+ { ...pluginOptions, noopTypeScriptCompilation: true },
199
+ // Component stylesheet bundler
200
+ stylesheetBundler),
201
+ ],
202
+ };
203
+ buildOptions.plugins ??= [];
204
+ if (externalPackages) {
205
+ buildOptions.packages = 'external';
206
+ }
207
+ else {
208
+ buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
209
+ }
210
+ // Mark manifest and polyfills file as external as these are generated by a different bundle step.
211
+ (buildOptions.external ??= []).push(...utils_1.SERVER_GENERATED_EXTERNALS);
212
+ const isNodePlatform = options.ssrOptions?.platform !== schema_1.ExperimentalPlatform.Neutral;
213
+ if (!isNodePlatform) {
214
+ // `@angular/platform-server` lazily depends on `xhr2` for XHR usage with the HTTP client.
215
+ // Since `xhr2` has Node.js dependencies, it cannot be used when targeting non-Node.js platforms.
216
+ // Note: The framework already issues a warning when using XHR with SSR.
217
+ buildOptions.external.push('xhr2');
218
+ }
219
+ buildOptions.plugins.push((0, server_bundle_metadata_plugin_1.createServerBundleMetadata)(), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
220
+ namespace: mainServerInjectPolyfillsNamespace,
221
+ cache: loadResultCache,
222
+ loadContent: () => ({
223
+ contents: `import './polyfills.server.mjs';`,
236
224
  loader: 'js',
237
225
  resolveDir: workspaceRoot,
238
- };
239
- },
240
- }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
241
- namespace: mainServerNamespace,
242
- cache: sourceFileCache?.loadResultCache,
243
- loadContent: async () => {
244
- const mainServerEntryPointJsImport = entryFileToWorkspaceRelative(workspaceRoot, mainServerEntryPoint);
245
- const contents = [
246
- // Re-export all symbols including default export from 'main.server.ts'
247
- `export { default } from '${mainServerEntryPointJsImport}';`,
248
- `export * from '${mainServerEntryPointJsImport}';`,
249
- // Add @angular/ssr exports
250
- `export {
226
+ }),
227
+ }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
228
+ namespace: mainServerInjectManifestNamespace,
229
+ cache: loadResultCache,
230
+ loadContent: async () => {
231
+ const contents = [
232
+ // Configure `@angular/ssr` manifest.
233
+ `import manifest from './${manifest_1.SERVER_APP_MANIFEST_FILENAME}';`,
234
+ `import { ɵsetAngularAppManifest } from '@angular/ssr';`,
235
+ `ɵsetAngularAppManifest(manifest);`,
236
+ ];
237
+ return {
238
+ contents: contents.join('\n'),
239
+ loader: 'js',
240
+ resolveDir: workspaceRoot,
241
+ };
242
+ },
243
+ }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
244
+ namespace: mainServerNamespace,
245
+ cache: loadResultCache,
246
+ loadContent: async () => {
247
+ const mainServerEntryPointJsImport = entryFileToWorkspaceRelative(workspaceRoot, mainServerEntryPoint);
248
+ const contents = [
249
+ // Re-export all symbols including default export from 'main.server.ts'
250
+ `export { default } from '${mainServerEntryPointJsImport}';`,
251
+ `export * from '${mainServerEntryPointJsImport}';`,
252
+ // Add @angular/ssr exports
253
+ `export {
251
254
  ɵdestroyAngularServerApp,
252
255
  ɵextractRoutesAndCreateRouteTree,
253
256
  ɵgetOrCreateAngularServerApp,
254
257
  } from '@angular/ssr';`,
255
- ];
256
- return {
257
- contents: contents.join('\n'),
258
- loader: 'js',
259
- resolveDir: workspaceRoot,
260
- };
261
- },
262
- }));
263
- if (options.plugins) {
264
- buildOptions.plugins.push(...options.plugins);
265
- }
266
- return buildOptions;
258
+ ];
259
+ return {
260
+ contents: contents.join('\n'),
261
+ loader: 'js',
262
+ resolveDir: workspaceRoot,
263
+ };
264
+ },
265
+ }));
266
+ if (options.plugins) {
267
+ buildOptions.plugins.push(...options.plugins);
268
+ }
269
+ return buildOptions;
270
+ };
267
271
  }
268
272
  function createSsrEntryCodeBundleOptions(options, target, sourceFileCache, stylesheetBundler) {
269
273
  const { workspaceRoot, ssrOptions, externalPackages } = options;
270
274
  const serverEntryPoint = ssrOptions?.entry;
271
275
  (0, node_assert_1.default)(serverEntryPoint, 'createSsrEntryCodeBundleOptions should not be called without a defined serverEntryPoint.');
272
- const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache);
273
- const ssrEntryNamespace = 'angular:ssr-entry';
274
- const ssrInjectManifestNamespace = 'angular:ssr-entry-inject-manifest';
275
- const ssrInjectRequireNamespace = 'angular:ssr-entry-inject-require';
276
- const isNodePlatform = options.ssrOptions?.platform !== schema_1.ExperimentalPlatform.Neutral;
277
- const inject = [ssrInjectManifestNamespace];
278
- if (isNodePlatform) {
279
- inject.unshift(ssrInjectRequireNamespace);
280
- }
281
- const buildOptions = {
282
- ...getEsBuildServerCommonOptions(options),
283
- target,
284
- entryPoints: {
285
- // TODO: consider renaming to index
286
- 'server': ssrEntryNamespace,
287
- },
288
- supported: (0, utils_1.getFeatureSupport)(target, true),
289
- plugins: [
290
- (0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
291
- (0, compiler_plugin_1.createCompilerPlugin)(
292
- // JS/TS options
293
- { ...pluginOptions, noopTypeScriptCompilation: true },
294
- // Component stylesheet bundler
295
- stylesheetBundler),
296
- ],
297
- inject,
276
+ return (loadResultCache) => {
277
+ const pluginOptions = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, sourceFileCache, loadResultCache);
278
+ const ssrEntryNamespace = 'angular:ssr-entry';
279
+ const ssrInjectManifestNamespace = 'angular:ssr-entry-inject-manifest';
280
+ const ssrInjectRequireNamespace = 'angular:ssr-entry-inject-require';
281
+ const isNodePlatform = options.ssrOptions?.platform !== schema_1.ExperimentalPlatform.Neutral;
282
+ const inject = [ssrInjectManifestNamespace];
283
+ if (isNodePlatform) {
284
+ inject.unshift(ssrInjectRequireNamespace);
285
+ }
286
+ const buildOptions = {
287
+ ...getEsBuildServerCommonOptions(options),
288
+ target,
289
+ entryPoints: {
290
+ // TODO: consider renaming to index
291
+ 'server': ssrEntryNamespace,
292
+ },
293
+ supported: (0, utils_1.getFeatureSupport)(target, true),
294
+ plugins: [
295
+ (0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
296
+ (0, compiler_plugin_1.createCompilerPlugin)(
297
+ // JS/TS options
298
+ { ...pluginOptions, noopTypeScriptCompilation: true },
299
+ // Component stylesheet bundler
300
+ stylesheetBundler),
301
+ ],
302
+ inject,
303
+ };
304
+ buildOptions.plugins ??= [];
305
+ if (externalPackages) {
306
+ buildOptions.packages = 'external';
307
+ }
308
+ else {
309
+ buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
310
+ }
311
+ // Mark manifest file as external. As this will be generated later on.
312
+ (buildOptions.external ??= []).push('*/main.server.mjs', ...utils_1.SERVER_GENERATED_EXTERNALS);
313
+ if (!isNodePlatform) {
314
+ // `@angular/platform-server` lazily depends on `xhr2` for XHR usage with the HTTP client.
315
+ // Since `xhr2` has Node.js dependencies, it cannot be used when targeting non-Node.js platforms.
316
+ // Note: The framework already issues a warning when using XHR with SSR.
317
+ buildOptions.external.push('xhr2');
318
+ }
319
+ buildOptions.plugins.push((0, server_bundle_metadata_plugin_1.createServerBundleMetadata)({ ssrEntryBundle: true }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
320
+ namespace: ssrInjectRequireNamespace,
321
+ cache: loadResultCache,
322
+ loadContent: () => {
323
+ const contents = [
324
+ // Note: Needed as esbuild does not provide require shims / proxy from ESModules.
325
+ // See: https://github.com/evanw/esbuild/issues/1921.
326
+ `import { createRequire } from 'node:module';`,
327
+ `globalThis['require'] ??= createRequire(import.meta.url);`,
328
+ ];
329
+ return {
330
+ contents: contents.join('\n'),
331
+ loader: 'js',
332
+ resolveDir: workspaceRoot,
333
+ };
334
+ },
335
+ }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
336
+ namespace: ssrInjectManifestNamespace,
337
+ cache: loadResultCache,
338
+ loadContent: () => {
339
+ const contents = [
340
+ // Configure `@angular/ssr` app engine manifest.
341
+ `import manifest from './${manifest_1.SERVER_APP_ENGINE_MANIFEST_FILENAME}';`,
342
+ `import { ɵsetAngularAppEngineManifest } from '@angular/ssr';`,
343
+ `ɵsetAngularAppEngineManifest(manifest);`,
344
+ ];
345
+ return {
346
+ contents: contents.join('\n'),
347
+ loader: 'js',
348
+ resolveDir: workspaceRoot,
349
+ };
350
+ },
351
+ }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
352
+ namespace: ssrEntryNamespace,
353
+ cache: loadResultCache,
354
+ loadContent: () => {
355
+ const serverEntryPointJsImport = entryFileToWorkspaceRelative(workspaceRoot, serverEntryPoint);
356
+ const contents = [
357
+ // Re-export all symbols including default export
358
+ `import * as server from '${serverEntryPointJsImport}';`,
359
+ `export * from '${serverEntryPointJsImport}';`,
360
+ // The below is needed to avoid
361
+ // `Import "default" will always be undefined because there is no matching export` warning when no default is present.
362
+ `const defaultExportName = 'default';`,
363
+ `export default server[defaultExportName]`,
364
+ // Add @angular/ssr exports
365
+ `export { AngularAppEngine } from '@angular/ssr';`,
366
+ ];
367
+ return {
368
+ contents: contents.join('\n'),
369
+ loader: 'js',
370
+ resolveDir: workspaceRoot,
371
+ };
372
+ },
373
+ }));
374
+ if (options.plugins) {
375
+ buildOptions.plugins.push(...options.plugins);
376
+ }
377
+ return buildOptions;
298
378
  };
299
- buildOptions.plugins ??= [];
300
- if (externalPackages) {
301
- buildOptions.packages = 'external';
302
- }
303
- else {
304
- buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
305
- }
306
- // Mark manifest file as external. As this will be generated later on.
307
- (buildOptions.external ??= []).push('*/main.server.mjs', ...utils_1.SERVER_GENERATED_EXTERNALS);
308
- if (!isNodePlatform) {
309
- // `@angular/platform-server` lazily depends on `xhr2` for XHR usage with the HTTP client.
310
- // Since `xhr2` has Node.js dependencies, it cannot be used when targeting non-Node.js platforms.
311
- // Note: The framework already issues a warning when using XHR with SSR.
312
- buildOptions.external.push('xhr2');
313
- }
314
- buildOptions.plugins.push((0, server_bundle_metadata_plugin_1.createServerBundleMetadata)({ ssrEntryBundle: true }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
315
- namespace: ssrInjectRequireNamespace,
316
- cache: sourceFileCache?.loadResultCache,
317
- loadContent: () => {
318
- const contents = [
319
- // Note: Needed as esbuild does not provide require shims / proxy from ESModules.
320
- // See: https://github.com/evanw/esbuild/issues/1921.
321
- `import { createRequire } from 'node:module';`,
322
- `globalThis['require'] ??= createRequire(import.meta.url);`,
323
- ];
324
- return {
325
- contents: contents.join('\n'),
326
- loader: 'js',
327
- resolveDir: workspaceRoot,
328
- };
329
- },
330
- }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
331
- namespace: ssrInjectManifestNamespace,
332
- cache: sourceFileCache?.loadResultCache,
333
- loadContent: () => {
334
- const contents = [
335
- // Configure `@angular/ssr` app engine manifest.
336
- `import manifest from './${manifest_1.SERVER_APP_ENGINE_MANIFEST_FILENAME}';`,
337
- `import { ɵsetAngularAppEngineManifest } from '@angular/ssr';`,
338
- `ɵsetAngularAppEngineManifest(manifest);`,
339
- ];
340
- return {
341
- contents: contents.join('\n'),
342
- loader: 'js',
343
- resolveDir: workspaceRoot,
344
- };
345
- },
346
- }), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
347
- namespace: ssrEntryNamespace,
348
- cache: sourceFileCache?.loadResultCache,
349
- loadContent: () => {
350
- const serverEntryPointJsImport = entryFileToWorkspaceRelative(workspaceRoot, serverEntryPoint);
351
- const contents = [
352
- // Re-export all symbols including default export
353
- `import * as server from '${serverEntryPointJsImport}';`,
354
- `export * from '${serverEntryPointJsImport}';`,
355
- // The below is needed to avoid
356
- // `Import "default" will always be undefined because there is no matching export` warning when no default is present.
357
- `const defaultExportName = 'default';`,
358
- `export default server[defaultExportName]`,
359
- // Add @angular/ssr exports
360
- `export { AngularAppEngine } from '@angular/ssr';`,
361
- ];
362
- return {
363
- contents: contents.join('\n'),
364
- loader: 'js',
365
- resolveDir: workspaceRoot,
366
- };
367
- },
368
- }));
369
- if (options.plugins) {
370
- buildOptions.plugins.push(...options.plugins);
371
- }
372
- return buildOptions;
373
379
  }
374
380
  function getEsBuildServerCommonOptions(options) {
375
381
  const isNodePlatform = options.ssrOptions?.platform !== schema_1.ExperimentalPlatform.Neutral;
@@ -442,7 +448,7 @@ function getEsBuildCommonOptions(options) {
442
448
  footer,
443
449
  };
444
450
  }
445
- function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfillsAsRelative, sourceFileCache) {
451
+ function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfillsAsRelative, loadResultCache) {
446
452
  const { jit, workspaceRoot, i18nOptions } = options;
447
453
  const buildOptions = {
448
454
  ...getEsBuildCommonOptions(options),
@@ -480,7 +486,7 @@ function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfi
480
486
  }
481
487
  buildOptions.plugins?.push((0, virtual_module_plugin_1.createVirtualModulePlugin)({
482
488
  namespace,
483
- cache: sourceFileCache?.loadResultCache,
489
+ cache: loadResultCache,
484
490
  loadContent: async (_, build) => {
485
491
  let polyfillPaths = polyfills;
486
492
  let warnings;
@@ -15,11 +15,15 @@ export interface BuildOutputAsset {
15
15
  destination: string;
16
16
  }
17
17
  export interface RebuildState {
18
- rebuildContexts: BundlerContext[];
18
+ rebuildContexts: {
19
+ typescriptContexts: BundlerContext[];
20
+ otherContexts: BundlerContext[];
21
+ };
19
22
  componentStyleBundler: ComponentStylesheetBundler;
20
23
  codeBundleCache?: SourceFileCache;
21
24
  fileChanges: ChangedFiles;
22
25
  previousOutputHashes: Map<string, string>;
26
+ templateUpdates?: Map<string, string>;
23
27
  }
24
28
  export interface ExternalResultMetadata {
25
29
  implicitBrowser: string[];
@@ -36,6 +40,7 @@ export declare class ExecutionResult {
36
40
  private rebuildContexts;
37
41
  private componentStyleBundler;
38
42
  private codeBundleCache?;
43
+ readonly templateUpdates?: Map<string, string> | undefined;
39
44
  outputFiles: BuildOutputFile[];
40
45
  assetFiles: BuildOutputAsset[];
41
46
  errors: (Message | PartialMessage)[];
@@ -46,7 +51,10 @@ export declare class ExecutionResult {
46
51
  extraWatchFiles: string[];
47
52
  htmlIndexPath?: string;
48
53
  htmlBaseHref?: string;
49
- constructor(rebuildContexts: BundlerContext[], componentStyleBundler: ComponentStylesheetBundler, codeBundleCache?: SourceFileCache | undefined);
54
+ constructor(rebuildContexts: {
55
+ typescriptContexts: BundlerContext[];
56
+ otherContexts: BundlerContext[];
57
+ }, componentStyleBundler: ComponentStylesheetBundler, codeBundleCache?: SourceFileCache | undefined, templateUpdates?: Map<string, string> | undefined);
50
58
  addOutputFile(path: string, content: string | Uint8Array, type: BuildOutputFileType): void;
51
59
  addAssets(assets: BuildOutputAsset[]): void;
52
60
  addLog(value: string): void;
@@ -17,6 +17,7 @@ class ExecutionResult {
17
17
  rebuildContexts;
18
18
  componentStyleBundler;
19
19
  codeBundleCache;
20
+ templateUpdates;
20
21
  outputFiles = [];
21
22
  assetFiles = [];
22
23
  errors = [];
@@ -27,10 +28,11 @@ class ExecutionResult {
27
28
  extraWatchFiles = [];
28
29
  htmlIndexPath;
29
30
  htmlBaseHref;
30
- constructor(rebuildContexts, componentStyleBundler, codeBundleCache) {
31
+ constructor(rebuildContexts, componentStyleBundler, codeBundleCache, templateUpdates) {
31
32
  this.rebuildContexts = rebuildContexts;
32
33
  this.componentStyleBundler = componentStyleBundler;
33
34
  this.codeBundleCache = codeBundleCache;
35
+ this.templateUpdates = templateUpdates;
34
36
  }
35
37
  addOutputFile(path, content, type) {
36
38
  this.outputFiles.push((0, utils_1.createOutputFile)(path, content, type));
@@ -102,26 +104,24 @@ class ExecutionResult {
102
104
  }
103
105
  get watchFiles() {
104
106
  // Bundler contexts internally normalize file dependencies
105
- const files = this.rebuildContexts.flatMap((context) => [...context.watchFiles]);
107
+ const files = this.rebuildContexts.typescriptContexts
108
+ .flatMap((context) => [...context.watchFiles])
109
+ .concat(this.rebuildContexts.otherContexts.flatMap((context) => [...context.watchFiles]));
106
110
  if (this.codeBundleCache?.referencedFiles) {
107
111
  // These files originate from TS/NG and can have POSIX path separators even on Windows.
108
112
  // To ensure path comparisons are valid, all these paths must be normalized.
109
113
  files.push(...this.codeBundleCache.referencedFiles.map(node_path_1.normalize));
110
114
  }
111
- if (this.codeBundleCache?.loadResultCache) {
112
- // Load result caches internally normalize file dependencies
113
- files.push(...this.codeBundleCache.loadResultCache.watchFiles);
114
- }
115
115
  return files.concat(this.extraWatchFiles);
116
116
  }
117
117
  createRebuildState(fileChanges) {
118
- this.codeBundleCache?.invalidate([...fileChanges.modified, ...fileChanges.removed]);
119
118
  return {
120
119
  rebuildContexts: this.rebuildContexts,
121
120
  codeBundleCache: this.codeBundleCache,
122
121
  componentStyleBundler: this.componentStyleBundler,
123
122
  fileChanges,
124
123
  previousOutputHashes: new Map(this.outputFiles.map((file) => [file.path, file.hash])),
124
+ templateUpdates: this.templateUpdates,
125
125
  };
126
126
  }
127
127
  findChangedFiles(previousOutputHashes) {
@@ -135,8 +135,11 @@ class ExecutionResult {
135
135
  return changed;
136
136
  }
137
137
  async dispose() {
138
- await Promise.allSettled(this.rebuildContexts.map((context) => context.dispose()));
139
- await this.componentStyleBundler.dispose();
138
+ await Promise.allSettled([
139
+ ...this.rebuildContexts.typescriptContexts.map((context) => context.dispose()),
140
+ ...this.rebuildContexts.otherContexts.map((context) => context.dispose()),
141
+ this.componentStyleBundler.dispose(),
142
+ ]);
140
143
  }
141
144
  }
142
145
  exports.ExecutionResult = ExecutionResult;