@angular/build 19.1.5 → 19.1.6

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/build",
3
- "version": "19.1.5",
3
+ "version": "19.1.6",
4
4
  "description": "Official build system for Angular",
5
5
  "keywords": [
6
6
  "Angular CLI",
@@ -23,8 +23,8 @@
23
23
  "builders": "builders.json",
24
24
  "dependencies": {
25
25
  "@ampproject/remapping": "2.3.0",
26
- "@angular-devkit/core": "19.1.5",
27
- "@angular-devkit/architect": "0.1901.5",
26
+ "@angular-devkit/core": "19.1.6",
27
+ "@angular-devkit/architect": "0.1901.6",
28
28
  "@babel/core": "7.26.0",
29
29
  "@babel/helper-annotate-as-pure": "7.25.9",
30
30
  "@babel/helper-split-export-declaration": "7.24.7",
@@ -58,7 +58,7 @@
58
58
  "@angular/localize": "^19.0.0",
59
59
  "@angular/platform-server": "^19.0.0",
60
60
  "@angular/service-worker": "^19.0.0",
61
- "@angular/ssr": "^19.1.5",
61
+ "@angular/ssr": "^19.1.6",
62
62
  "less": "^4.2.0",
63
63
  "ng-packagr": "^19.0.0",
64
64
  "postcss": "^8.4.0",
@@ -127,6 +127,9 @@ async function* runEsBuildBuildAction(action, options) {
127
127
  if (!watcher) {
128
128
  return;
129
129
  }
130
+ // Used to force a full result on next rebuild if there were initial errors.
131
+ // This ensures at least one full result is emitted.
132
+ let hasInitialErrors = result.errors.length > 0;
130
133
  // Wait for changes and rebuild as needed
131
134
  const currentWatchFiles = new Set(result.watchFiles);
132
135
  try {
@@ -164,9 +167,11 @@ async function* runEsBuildBuildAction(action, options) {
164
167
  if (staleWatchFiles?.size) {
165
168
  watcher.remove([...staleWatchFiles]);
166
169
  }
167
- for (const outputResult of emitOutputResults(result, outputOptions, changes, incrementalResults ? rebuildState : undefined)) {
170
+ for (const outputResult of emitOutputResults(result, outputOptions, changes, incrementalResults && !hasInitialErrors ? rebuildState : undefined)) {
168
171
  yield outputResult;
169
172
  }
173
+ // Clear initial build errors flag if no errors are now present
174
+ hasInitialErrors &&= result.errors.length > 0;
170
175
  }
171
176
  }
172
177
  finally {
@@ -38,7 +38,7 @@ async function executePostBundleSteps(metafile, options, outputFiles, assetFiles
38
38
  const allErrors = [];
39
39
  const allWarnings = [];
40
40
  const prerenderedRoutes = {};
41
- const { baseHref = '/', serviceWorker, i18nOptions, indexHtmlOptions, optimizationOptions, sourcemapOptions, outputMode, serverEntryPoint, prerenderOptions, appShellOptions, publicPath, workspaceRoot, partialSSRBuild, } = options;
41
+ const { baseHref = '/', serviceWorker, ssrOptions, indexHtmlOptions, optimizationOptions, sourcemapOptions, outputMode, serverEntryPoint, prerenderOptions, appShellOptions, publicPath, workspaceRoot, partialSSRBuild, } = options;
42
42
  // Index HTML content without CSS inlining to be used for server rendering (AppShell, SSG and SSR).
43
43
  // NOTE: Critical CSS inlining is deliberately omitted here, as it will be handled during server rendering.
44
44
  // Additionally, when using prerendering or AppShell, the index HTML file may be regenerated.
@@ -57,7 +57,7 @@ async function executePostBundleSteps(metafile, options, outputFiles, assetFiles
57
57
  }
58
58
  // Create server manifest
59
59
  const initialFilesPaths = new Set(initialFiles.keys());
60
- if (serverEntryPoint) {
60
+ if (serverEntryPoint && (outputMode || prerenderOptions || appShellOptions || ssrOptions)) {
61
61
  const { manifestContent, serverAssetsChunks } = (0, manifest_1.generateAngularServerAppManifest)(additionalHtmlOutputFiles, outputFiles, optimizationOptions.styles.inlineCritical ?? false, undefined, locale, baseHref, initialFilesPaths, metafile, publicPath);
62
62
  additionalOutputFiles.push(...serverAssetsChunks, (0, utils_1.createOutputFile)(manifest_1.SERVER_APP_MANIFEST_FILENAME, manifestContent, bundler_context_1.BuildOutputFileType.ServerApplication));
63
63
  }
@@ -161,6 +161,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
161
161
  },
162
162
  });
163
163
  }
164
+ yield { baseUrl: '', success: false };
164
165
  continue;
165
166
  }
166
167
  // Clear existing error overlay on successful result
@@ -321,6 +322,29 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
321
322
  break;
322
323
  }
323
324
  });
325
+ // Setup component HMR invalidation
326
+ // Invalidation occurs when the runtime cannot update a component
327
+ server.hot.on('angular:invalidate', (data) => {
328
+ if (typeof data?.id !== 'string') {
329
+ context.logger.warn('Development server client sent invalid internal invalidate event.');
330
+ }
331
+ // Clear invalid template update
332
+ templateUpdates.delete(data.id);
333
+ // Some cases are expected unsupported update scenarios but some may be errors.
334
+ // If an error occurred, log the error in addition to the invalidation.
335
+ if (data.error) {
336
+ context.logger.error(`Component update failed${data.message ? `: ${data.message}` : '.'}` +
337
+ '\nPlease consider reporting the error at https://github.com/angular/angular-cli/issues');
338
+ }
339
+ else {
340
+ context.logger.warn(`Component update unsupported${data.message ? `: ${data.message}` : '.'}`);
341
+ }
342
+ server?.ws.send({
343
+ type: 'full-reload',
344
+ path: '*',
345
+ });
346
+ context.logger.info('Page reload sent to client(s).');
347
+ });
324
348
  const urls = server.resolvedUrls;
325
349
  if (urls && (urls.local.length || urls.network.length)) {
326
350
  serverUrl = new URL(urls.local[0] ?? urls.network[0]);
@@ -550,6 +574,14 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
550
574
  mainFields: ['es2020', 'browser', 'module', 'main'],
551
575
  preserveSymlinks,
552
576
  },
577
+ dev: {
578
+ // This is needed when `externalDependencies` is used to prevent Vite load errors.
579
+ // NOTE: If Vite adds direct support for externals, this can be removed.
580
+ // NOTE: Vite breaks the resolution of browser modules in SSR
581
+ // when accessing a url with two or more segments (e.g., 'foo/bar'),
582
+ // as they are not re-based from the base href.
583
+ preTransformRequests: externalMetadata.explicitBrowser.length === 0 && ssrMode === plugins_1.ServerSsrMode.NoSsr,
584
+ },
553
585
  server: {
554
586
  warmup: {
555
587
  ssrFiles,
@@ -587,9 +619,6 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
587
619
  ...[...assets.values()].map(({ source }) => source),
588
620
  ],
589
621
  },
590
- // This is needed when `externalDependencies` is used to prevent Vite load errors.
591
- // NOTE: If Vite adds direct support for externals, this can be removed.
592
- preTransformRequests: externalMetadata.explicitBrowser.length === 0,
593
622
  },
594
623
  ssr: {
595
624
  // Note: `true` and `/.*/` have different sematics. When true, the `external` option is ignored.
@@ -47,24 +47,13 @@ async function createAngularMemoryPlugin(options) {
47
47
  // `/@id/${source}` but is currently closer to a raw external than a resolved file path.
48
48
  return source;
49
49
  }
50
- if (importer) {
50
+ if (importer && source[0] === '.') {
51
51
  const normalizedImporter = normalizePath(importer);
52
- if (source[0] === '.' && normalizedImporter.startsWith(virtualProjectRoot)) {
52
+ if (normalizedImporter.startsWith(virtualProjectRoot)) {
53
53
  // Remove query if present
54
54
  const [importerFile] = normalizedImporter.split('?', 1);
55
55
  source = '/' + (0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.relative)(virtualProjectRoot, importerFile)), source);
56
56
  }
57
- else if (!ssr &&
58
- source[0] === '/' &&
59
- importer.endsWith('index.html') &&
60
- normalizedImporter.startsWith(virtualProjectRoot)) {
61
- // This is only needed when using SSR and `angularSsrMiddleware` (old style) to correctly resolve
62
- // .js files when using lazy-loading.
63
- // Remove query if present
64
- const [importerFile] = normalizedImporter.split('?', 1);
65
- source =
66
- '/' + (0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.relative)(virtualProjectRoot, importerFile)), (0, node_path_1.basename)(source));
67
- }
68
57
  }
69
58
  const [file] = source.split('?', 1);
70
59
  if (outputFiles.has(normalizePath(file))) {
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.normalizeCacheOptions = normalizeCacheOptions;
11
11
  const node_path_1 = require("node:path");
12
12
  /** Version placeholder is replaced during the build process with actual package version */
13
- const VERSION = '19.1.5';
13
+ const VERSION = '19.1.6';
14
14
  function hasCacheMetadata(value) {
15
15
  return (!!value &&
16
16
  typeof value === 'object' &&