@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
@@ -10,12 +10,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.prerenderPages = prerenderPages;
11
11
  const promises_1 = require("node:fs/promises");
12
12
  const node_path_1 = require("node:path");
13
- const node_url_1 = require("node:url");
14
13
  const schema_1 = require("../../builders/application/schema");
15
14
  const bundler_context_1 = require("../../tools/esbuild/bundler-context");
16
15
  const error_1 = require("../error");
17
16
  const url_1 = require("../url");
18
17
  const worker_pool_1 = require("../worker-pool");
18
+ const utils_1 = require("./esm-in-memory-loader/utils");
19
19
  const models_1 = require("./models");
20
20
  async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerenderOptions, outputFiles, assets, outputMode, sourcemap = false, maxThreads = 1) {
21
21
  const outputFilesForWorker = {};
@@ -51,12 +51,11 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
51
51
  assetsReversed[addLeadingSlash(destination.replace(/\\/g, node_path_1.posix.sep))] = source;
52
52
  }
53
53
  // Get routes to prerender
54
- const { errors: extractionErrors, serializedRouteTree: serializableRouteTreeNode } = await getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, assetsReversed, appShellOptions, prerenderOptions, sourcemap, outputMode).catch((err) => {
54
+ const { errors: extractionErrors, serializedRouteTree: serializableRouteTreeNode, appShellRoute, } = await getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, assetsReversed, appShellOptions, prerenderOptions, sourcemap, outputMode).catch((err) => {
55
55
  return {
56
- errors: [
57
- `An error occurred while extracting routes.\n\n${err.stack ?? err.message ?? err}`,
58
- ],
56
+ errors: [`An error occurred while extracting routes.\n\n${err.stack ?? err.message ?? err}`],
59
57
  serializedRouteTree: [],
58
+ appShellRoute: undefined,
60
59
  };
61
60
  });
62
61
  errors.push(...extractionErrors);
@@ -73,7 +72,6 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
73
72
  switch (metadata.renderMode) {
74
73
  case undefined: /* Legacy building mode */
75
74
  case models_1.RouteRenderMode.Prerender:
76
- case models_1.RouteRenderMode.AppShell:
77
75
  serializableRouteTreeNodeForPrerender.push(metadata);
78
76
  break;
79
77
  case models_1.RouteRenderMode.Server:
@@ -92,7 +90,7 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
92
90
  };
93
91
  }
94
92
  // Render routes
95
- const { errors: renderingErrors, output } = await renderPages(baseHref, sourcemap, serializableRouteTreeNodeForPrerender, maxThreads, workspaceRoot, outputFilesForWorker, assetsReversed, appShellOptions, outputMode);
93
+ const { errors: renderingErrors, output } = await renderPages(baseHref, sourcemap, serializableRouteTreeNodeForPrerender, maxThreads, workspaceRoot, outputFilesForWorker, assetsReversed, appShellOptions, outputMode, appShellRoute ?? appShellOptions?.route);
96
94
  errors.push(...renderingErrors);
97
95
  return {
98
96
  errors,
@@ -101,14 +99,10 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
101
99
  serializableRouteTreeNode,
102
100
  };
103
101
  }
104
- async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxThreads, workspaceRoot, outputFilesForWorker, assetFilesForWorker, appShellOptions, outputMode) {
102
+ async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxThreads, workspaceRoot, outputFilesForWorker, assetFilesForWorker, appShellOptions, outputMode, appShellRoute) {
105
103
  const output = {};
106
104
  const errors = [];
107
- const workerExecArgv = [
108
- '--import',
109
- // Loader cannot be an absolute path on Windows.
110
- (0, node_url_1.pathToFileURL)((0, node_path_1.join)(__dirname, 'esm-in-memory-loader/register-hooks.js')).href,
111
- ];
105
+ const workerExecArgv = [utils_1.IMPORT_EXEC_ARGV];
112
106
  if (sourcemap) {
113
107
  workerExecArgv.push('--enable-source-maps');
114
108
  }
@@ -126,24 +120,26 @@ async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxTh
126
120
  });
127
121
  try {
128
122
  const renderingPromises = [];
129
- const appShellRoute = appShellOptions && addLeadingSlash(appShellOptions.route);
123
+ const appShellRouteWithLeadingSlash = appShellRoute && addLeadingSlash(appShellRoute);
130
124
  const baseHrefWithLeadingSlash = addLeadingSlash(baseHref);
131
125
  for (const { route, redirectTo, renderMode } of serializableRouteTreeNode) {
132
- // Remove base href from file output path.
133
- const routeWithoutBaseHref = addLeadingSlash(route.slice(baseHrefWithLeadingSlash.length - 1));
126
+ // Remove the base href from the file output path.
127
+ const routeWithoutBaseHref = addTrailingSlash(route).startsWith(baseHrefWithLeadingSlash)
128
+ ? addLeadingSlash(route.slice(baseHrefWithLeadingSlash.length - 1))
129
+ : route;
134
130
  const outPath = node_path_1.posix.join(removeLeadingSlash(routeWithoutBaseHref), 'index.html');
135
131
  if (typeof redirectTo === 'string') {
136
132
  output[outPath] = { content: generateRedirectStaticPage(redirectTo), appShellRoute: false };
137
133
  continue;
138
134
  }
139
- const isAppShellRoute = renderMode === models_1.RouteRenderMode.AppShell ||
140
- // Legacy handling
141
- (renderMode === undefined && appShellRoute === routeWithoutBaseHref);
142
- const render = renderWorker.run({ url: route, isAppShellRoute });
135
+ const render = renderWorker.run({ url: route });
143
136
  const renderResult = render
144
137
  .then((content) => {
145
138
  if (content !== null) {
146
- output[outPath] = { content, appShellRoute: isAppShellRoute };
139
+ output[outPath] = {
140
+ content,
141
+ appShellRoute: appShellRouteWithLeadingSlash === routeWithoutBaseHref,
142
+ };
147
143
  }
148
144
  })
149
145
  .catch((err) => {
@@ -165,27 +161,27 @@ async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxTh
165
161
  async function getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, assetFilesForWorker, appShellOptions, prerenderOptions, sourcemap, outputMode) {
166
162
  const { routesFile, discoverRoutes } = prerenderOptions ?? {};
167
163
  const routes = [];
164
+ let appShellRoute;
168
165
  if (appShellOptions) {
166
+ appShellRoute = (0, url_1.urlJoin)(baseHref, appShellOptions.route);
169
167
  routes.push({
170
- route: (0, url_1.urlJoin)(baseHref, appShellOptions.route),
168
+ renderMode: models_1.RouteRenderMode.Prerender,
169
+ route: appShellRoute,
171
170
  });
172
171
  }
173
172
  if (routesFile) {
174
173
  const routesFromFile = (await (0, promises_1.readFile)(routesFile, 'utf8')).split(/\r?\n/);
175
174
  for (const route of routesFromFile) {
176
175
  routes.push({
176
+ renderMode: models_1.RouteRenderMode.Prerender,
177
177
  route: (0, url_1.urlJoin)(baseHref, route.trim()),
178
178
  });
179
179
  }
180
180
  }
181
181
  if (!discoverRoutes) {
182
- return { errors: [], serializedRouteTree: routes };
182
+ return { errors: [], appShellRoute, serializedRouteTree: routes };
183
183
  }
184
- const workerExecArgv = [
185
- '--import',
186
- // Loader cannot be an absolute path on Windows.
187
- (0, node_url_1.pathToFileURL)((0, node_path_1.join)(__dirname, 'esm-in-memory-loader/register-hooks.js')).href,
188
- ];
184
+ const workerExecArgv = [utils_1.IMPORT_EXEC_ARGV];
189
185
  if (sourcemap) {
190
186
  workerExecArgv.push('--enable-source-maps');
191
187
  }
@@ -202,8 +198,18 @@ async function getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, asset
202
198
  execArgv: workerExecArgv,
203
199
  });
204
200
  try {
205
- const { serializedRouteTree, errors } = await renderWorker.run({});
206
- return { errors, serializedRouteTree: [...routes, ...serializedRouteTree] };
201
+ const { serializedRouteTree, appShellRoute, errors } = await renderWorker.run({});
202
+ if (!routes.length) {
203
+ return { errors, appShellRoute, serializedRouteTree };
204
+ }
205
+ // Merge the routing trees
206
+ const uniqueRoutes = new Map();
207
+ for (const item of [...routes, ...serializedRouteTree]) {
208
+ if (!uniqueRoutes.has(item.route)) {
209
+ uniqueRoutes.set(item.route, item);
210
+ }
211
+ }
212
+ return { errors, serializedRouteTree: Array.from(uniqueRoutes.values()) };
207
213
  }
208
214
  catch (err) {
209
215
  (0, error_1.assertIsError)(err);
@@ -219,10 +225,13 @@ async function getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, asset
219
225
  }
220
226
  }
221
227
  function addLeadingSlash(value) {
222
- return value.charAt(0) === '/' ? value : '/' + value;
228
+ return value[0] === '/' ? value : '/' + value;
229
+ }
230
+ function addTrailingSlash(url) {
231
+ return url[url.length - 1] === '/' ? url : `${url}/`;
223
232
  }
224
233
  function removeLeadingSlash(value) {
225
- return value.charAt(0) === '/' ? value.slice(1) : value;
234
+ return value[0] === '/' ? value.slice(1) : value;
226
235
  }
227
236
  /**
228
237
  * Generates a static HTML page with a meta refresh tag to redirect the user to a specified URL.
@@ -21,8 +21,10 @@ let serverURL = launch_server_1.DEFAULT_URL;
21
21
  */
22
22
  async function renderPage({ url }) {
23
23
  const { ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp } = await (0, load_esm_from_memory_1.loadEsmModuleFromMemory)('./main.server.mjs');
24
- const angularServerApp = getOrCreateAngularServerApp();
25
- const response = await angularServerApp.renderStatic(new URL(url, serverURL), AbortSignal.timeout(30_000));
24
+ const angularServerApp = getOrCreateAngularServerApp({
25
+ allowStaticRouteRender: true,
26
+ });
27
+ const response = await angularServerApp.handle(new Request(new URL(url, serverURL), { signal: AbortSignal.timeout(30_000) }));
26
28
  return response ? response.text() : null;
27
29
  }
28
30
  async function initialize() {
@@ -20,9 +20,10 @@ let serverURL = launch_server_1.DEFAULT_URL;
20
20
  /** Renders an application based on a provided options. */
21
21
  async function extractRoutes() {
22
22
  const { ɵextractRoutesAndCreateRouteTree: extractRoutesAndCreateRouteTree } = await (0, load_esm_from_memory_1.loadEsmModuleFromMemory)('./main.server.mjs');
23
- const { routeTree, errors } = await extractRoutesAndCreateRouteTree(serverURL, undefined /** manifest */, true /** invokeGetPrerenderParams */, outputMode === schema_1.OutputMode.Server /** includePrerenderFallbackRoutes */);
23
+ const { routeTree, appShellRoute, errors } = await extractRoutesAndCreateRouteTree(serverURL, undefined /** manifest */, true /** invokeGetPrerenderParams */, outputMode === schema_1.OutputMode.Server /** includePrerenderFallbackRoutes */);
24
24
  return {
25
25
  errors,
26
+ appShellRoute,
26
27
  serializedRouteTree: routeTree.toObject(),
27
28
  };
28
29
  }