@angular/build 20.0.0-next.5 → 20.0.0-next.7

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.
@@ -0,0 +1,7 @@
1
+ Chrome >= 105
2
+ ChromeAndroid >= 105
3
+ Edge >= 105
4
+ Firefox >= 104
5
+ FirefoxAndroid >= 104
6
+ Safari >= 16
7
+ iOS >= 16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/build",
3
- "version": "20.0.0-next.5",
3
+ "version": "20.0.0-next.7",
4
4
  "description": "Official build system for Angular",
5
5
  "keywords": [
6
6
  "Angular CLI",
@@ -23,30 +23,30 @@
23
23
  "builders": "builders.json",
24
24
  "dependencies": {
25
25
  "@ampproject/remapping": "2.3.0",
26
- "@angular-devkit/architect": "0.2000.0-next.5",
26
+ "@angular-devkit/architect": "0.2000.0-next.7",
27
27
  "@babel/core": "7.26.10",
28
28
  "@babel/helper-annotate-as-pure": "7.25.9",
29
29
  "@babel/helper-split-export-declaration": "7.24.7",
30
30
  "@inquirer/confirm": "5.1.9",
31
31
  "@vitejs/plugin-basic-ssl": "2.0.0",
32
- "beasties": "0.3.2",
32
+ "beasties": "0.3.3",
33
33
  "browserslist": "^4.23.0",
34
- "esbuild": "0.25.2",
34
+ "esbuild": "0.25.3",
35
35
  "https-proxy-agent": "7.0.6",
36
36
  "istanbul-lib-instrument": "6.0.3",
37
37
  "jsonc-parser": "3.3.1",
38
- "listr2": "8.2.5",
38
+ "listr2": "8.3.2",
39
39
  "magic-string": "0.30.17",
40
40
  "mrmime": "2.0.1",
41
- "parse5-html-rewriting-stream": "7.0.0",
41
+ "parse5-html-rewriting-stream": "7.1.0",
42
42
  "picomatch": "4.0.2",
43
43
  "piscina": "4.9.2",
44
- "rollup": "4.39.0",
45
- "sass": "1.86.3",
44
+ "rollup": "4.40.0",
45
+ "sass": "1.87.0",
46
46
  "semver": "7.7.1",
47
47
  "source-map-support": "0.5.21",
48
- "tinyglobby": "0.2.12",
49
- "vite": "6.2.5",
48
+ "tinyglobby": "0.2.13",
49
+ "vite": "6.3.2",
50
50
  "watchpack": "2.4.2"
51
51
  },
52
52
  "optionalDependencies": {
@@ -60,7 +60,7 @@
60
60
  "@angular/platform-browser": "^20.0.0 || ^20.0.0-next.0",
61
61
  "@angular/platform-server": "^20.0.0 || ^20.0.0-next.0",
62
62
  "@angular/service-worker": "^20.0.0 || ^20.0.0-next.0",
63
- "@angular/ssr": "^20.0.0-next.5",
63
+ "@angular/ssr": "^20.0.0-next.7",
64
64
  "karma": "^6.4.0",
65
65
  "less": "^4.2.0",
66
66
  "ng-packagr": "^20.0.0 || ^20.0.0-next.0",
@@ -247,8 +247,9 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
247
247
  externalMetadata.explicitServer.length = 0;
248
248
  externalMetadata.implicitServer.length = 0;
249
249
  externalMetadata.implicitBrowser.length = 0;
250
- externalMetadata.explicitBrowser.push(...explicit);
251
- externalMetadata.explicitServer.push(...explicit, ...node_module_1.builtinModules);
250
+ const externalDeps = browserOptions.externalDependencies ?? [];
251
+ externalMetadata.explicitBrowser.push(...explicit, ...externalDeps);
252
+ externalMetadata.explicitServer.push(...explicit, ...externalDeps, ...node_module_1.builtinModules);
252
253
  externalMetadata.implicitServer.push(...implicitServerFiltered);
253
254
  externalMetadata.implicitBrowser.push(...implicitBrowserFiltered);
254
255
  // The below needs to be sorted as Vite uses these options are part of the hashing invalidation algorithm.
@@ -307,7 +308,10 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
307
308
  });
308
309
  }
309
310
  // Setup server and start listening
310
- const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), componentStyles, templateUpdates, browserOptions.loader, browserOptions.define, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
311
+ const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), componentStyles, templateUpdates, browserOptions.loader, {
312
+ ...browserOptions.define,
313
+ 'ngHmrMode': browserOptions.templateUpdates ? 'true' : 'false',
314
+ }, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
311
315
  server = await createServer(serverConfiguration);
312
316
  await server.listen();
313
317
  // Setup builder context logging for browser clients
@@ -49,6 +49,7 @@ const path = __importStar(require("node:path"));
49
49
  const tinyglobby_1 = require("tinyglobby");
50
50
  const bundler_context_1 = require("../../tools/esbuild/bundler-context");
51
51
  const utils_1 = require("../../tools/esbuild/utils");
52
+ const virtual_module_plugin_1 = require("../../tools/esbuild/virtual-module-plugin");
52
53
  const index_1 = require("../application/index");
53
54
  const results_1 = require("../application/results");
54
55
  const schema_1 = require("../application/schema");
@@ -72,30 +73,27 @@ class AngularAssetsMiddleware {
72
73
  this.latestBuildFiles = latestBuildFiles;
73
74
  }
74
75
  handle(req, res, next) {
75
- let err = null;
76
- try {
77
- const url = new URL(`http://${req.headers['host']}${req.url}`);
78
- // Remove the leading slash from the URL path and convert to platform specific.
79
- // The latest build files will use the platform path separator.
80
- let pathname = url.pathname.slice(1);
81
- if (isWindows) {
82
- pathname = pathname.replaceAll(path.posix.sep, path.win32.sep);
83
- }
84
- const file = this.latestBuildFiles.files[pathname];
85
- if (file?.origin === 'disk') {
76
+ const url = new URL(`http://${req.headers['host']}${req.url}`);
77
+ // Remove the leading slash from the URL path and convert to platform specific.
78
+ // The latest build files will use the platform path separator.
79
+ let pathname = url.pathname.slice(1);
80
+ if (isWindows) {
81
+ pathname = pathname.replaceAll(path.posix.sep, path.win32.sep);
82
+ }
83
+ const file = this.latestBuildFiles.files[pathname];
84
+ if (!file) {
85
+ next();
86
+ return;
87
+ }
88
+ switch (file.origin) {
89
+ case 'disk':
86
90
  this.serveFile(file.inputPath, undefined, res);
87
- return;
88
- }
89
- else if (file?.origin === 'memory') {
91
+ break;
92
+ case 'memory':
90
93
  // Include pathname to help with Content-Type headers.
91
94
  this.serveFile(`/unused/${url.pathname}`, undefined, res, undefined, file.contents, true);
92
- return;
93
- }
94
- }
95
- catch (e) {
96
- err = e;
95
+ break;
97
96
  }
98
- next(err);
99
97
  }
100
98
  static createPlugin(initialFiles) {
101
99
  return {
@@ -309,7 +307,7 @@ async function initializeApplication(options, context, karmaOptions, transforms
309
307
  entryPoints.set(mainName, options.main);
310
308
  }
311
309
  else {
312
- entryPoints.set(mainName, localResolve('./polyfills/init_test_bed.js'));
310
+ entryPoints.set(mainName, 'angular:test-bed-init');
313
311
  }
314
312
  const instrumentForCoverage = options.codeCoverage
315
313
  ? createInstrumentationFilter(projectSourceRoot, getInstrumentationExcludedPaths(context.workspaceRoot, options.codeCoverageExclude ?? []))
@@ -323,6 +321,7 @@ async function initializeApplication(options, context, karmaOptions, transforms
323
321
  entryPoints,
324
322
  tsConfig: options.tsConfig,
325
323
  outputPath,
324
+ preserveSymlinks: options.preserveSymlinks,
326
325
  aot: options.aot,
327
326
  index: false,
328
327
  outputHashing: schema_1.OutputHashing.None,
@@ -347,8 +346,27 @@ async function initializeApplication(options, context, karmaOptions, transforms
347
346
  loader: options.loader,
348
347
  externalDependencies: options.externalDependencies,
349
348
  };
349
+ const virtualTestBedInit = (0, virtual_module_plugin_1.createVirtualModulePlugin)({
350
+ namespace: 'angular:test-bed-init',
351
+ loadContent: async () => {
352
+ const contents = [
353
+ // Initialize the Angular testing environment
354
+ `import { getTestBed } from '@angular/core/testing';`,
355
+ `import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';`,
356
+ `getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting(), {`,
357
+ ` errorOnUnknownElements: true,`,
358
+ ` errorOnUnknownProperties: true,`,
359
+ '});',
360
+ ];
361
+ return {
362
+ contents: contents.join('\n'),
363
+ loader: 'js',
364
+ resolveDir: projectSourceRoot,
365
+ };
366
+ },
367
+ });
350
368
  // Build tests with `application` builder, using test files as entry points.
351
- const [buildOutput, buildIterator] = await first((0, index_1.buildApplicationInternal)(buildOptions, context), { cancel: !buildOptions.watch });
369
+ const [buildOutput, buildIterator] = await first((0, index_1.buildApplicationInternal)(buildOptions, context, { codePlugins: [virtualTestBedInit] }), { cancel: !buildOptions.watch });
352
370
  if (buildOutput.kind === results_1.ResultKind.Failure) {
353
371
  throw new ApplicationBuildError('Build failed');
354
372
  }
@@ -536,7 +536,8 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
536
536
  }
537
537
  // Synchronize custom resolve conditions.
538
538
  // Set if using the supported bundler resolution mode (bundler is the default in new projects)
539
- if (compilerOptions.moduleResolution === 100 /* ModuleResolutionKind.Bundler */) {
539
+ if (compilerOptions.moduleResolution === 100 /* ModuleResolutionKind.Bundler */ ||
540
+ compilerOptions.module === 200 /** ModuleKind.Preserve */) {
540
541
  compilerOptions.customConditions = customConditions;
541
542
  }
542
543
  return {
@@ -58,6 +58,10 @@ class ComponentStylesheetBundler {
58
58
  else {
59
59
  buildOptions.entryPoints = [entry];
60
60
  }
61
+ // Angular encapsulation does not support nesting
62
+ // See: https://github.com/angular/angular/issues/58996
63
+ buildOptions.supported ??= {};
64
+ buildOptions.supported['nesting'] = false;
61
65
  return buildOptions;
62
66
  });
63
67
  });
@@ -89,6 +93,10 @@ class ComponentStylesheetBundler {
89
93
  else {
90
94
  buildOptions.entryPoints = [`${namespace};${entry}`];
91
95
  }
96
+ // Angular encapsulation does not support nesting
97
+ // See: https://github.com/angular/angular/issues/58996
98
+ buildOptions.supported ??= {};
99
+ buildOptions.supported['nesting'] = false;
92
100
  buildOptions.plugins.push({
93
101
  name: 'angular-component-styles',
94
102
  setup(build) {
@@ -108,7 +108,7 @@ async function loadViteClientCode(file, disableViteTransport = false) {
108
108
  (0, node_assert_1.default)(originalContents !== updatedContents, 'Failed to update Vite client error overlay text.');
109
109
  if (disableViteTransport) {
110
110
  const previousUpdatedContents = updatedContents;
111
- updatedContents = updatedContents.replace('transport.connect(handleMessage)', '');
111
+ updatedContents = updatedContents.replace('transport.connect(createHMRHandler(handleMessage));', '');
112
112
  (0, node_assert_1.default)(previousUpdatedContents !== updatedContents, 'Failed to update Vite client WebSocket disable.');
113
113
  updatedContents = updatedContents.replace('console.debug("[vite] connecting...")', '');
114
114
  }
@@ -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 = '20.0.0-next.5';
13
+ const VERSION = '20.0.0-next.7';
14
14
  function hasCacheMetadata(value) {
15
15
  return (!!value &&
16
16
  typeof value === 'object' &&
@@ -13,30 +13,40 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.getSupportedBrowsers = getSupportedBrowsers;
14
14
  const browserslist_1 = __importDefault(require("browserslist"));
15
15
  function getSupportedBrowsers(projectRoot, logger) {
16
- browserslist_1.default.defaults = [
17
- 'last 2 Chrome versions',
18
- 'last 1 Firefox version',
19
- 'last 2 Edge major versions',
20
- 'last 2 Safari major versions',
21
- 'last 2 iOS major versions',
22
- 'last 2 Android major versions',
23
- 'Firefox ESR',
24
- ];
16
+ // Read the browserslist configuration containing Angular's browser support policy.
17
+ const angularBrowserslist = (0, browserslist_1.default)(undefined, {
18
+ path: require.resolve('../../.browserslistrc'),
19
+ });
20
+ // Use Angular's configuration as the default.
21
+ browserslist_1.default.defaults = angularBrowserslist;
22
+ // Get the minimum set of browser versions supported by Angular.
23
+ const minimumBrowsers = new Set(angularBrowserslist);
25
24
  // Get browsers from config or default.
26
25
  const browsersFromConfigOrDefault = new Set((0, browserslist_1.default)(undefined, { path: projectRoot }));
27
26
  // Get browsers that support ES6 modules.
28
27
  const browsersThatSupportEs6 = new Set((0, browserslist_1.default)('supports es6-module'));
28
+ const nonEs6Browsers = [];
29
29
  const unsupportedBrowsers = [];
30
30
  for (const browser of browsersFromConfigOrDefault) {
31
31
  if (!browsersThatSupportEs6.has(browser)) {
32
+ // Any browser which does not support ES6 is explicitly ignored, as Angular will not build successfully.
32
33
  browsersFromConfigOrDefault.delete(browser);
34
+ nonEs6Browsers.push(browser);
35
+ }
36
+ else if (!minimumBrowsers.has(browser)) {
37
+ // Any other unsupported browser we will attempt to use, but provide no support for.
33
38
  unsupportedBrowsers.push(browser);
34
39
  }
35
40
  }
36
- if (unsupportedBrowsers.length) {
41
+ if (nonEs6Browsers.length) {
37
42
  logger.warn(`One or more browsers which are configured in the project's Browserslist configuration ` +
38
43
  'will be ignored as ES5 output is not supported by the Angular CLI.\n' +
39
- `Ignored browsers: ${unsupportedBrowsers.join(', ')}`);
44
+ `Ignored browsers:\n${nonEs6Browsers.join(', ')}`);
45
+ }
46
+ if (unsupportedBrowsers.length) {
47
+ logger.warn(`One or more browsers which are configured in the project's Browserslist configuration ` +
48
+ "fall outside Angular's browser support for this version.\n" +
49
+ `Unsupported browsers:\n${unsupportedBrowsers.join(', ')}`);
40
50
  }
41
51
  return Array.from(browsersFromConfigOrDefault);
42
52
  }
@@ -1,16 +0,0 @@
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.dev/license
7
- */
8
-
9
- import { getTestBed } from '@angular/core/testing';
10
- import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
11
-
12
- // Initialize the Angular testing environment.
13
- getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting(), {
14
- errorOnUnknownElements: true,
15
- errorOnUnknownProperties: true,
16
- });