@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.
- package/.browserslistrc +7 -0
- package/package.json +11 -11
- package/src/builders/dev-server/vite-server.js +7 -3
- package/src/builders/karma/application_builder.js +40 -22
- package/src/tools/esbuild/angular/compiler-plugin.js +2 -1
- package/src/tools/esbuild/angular/component-stylesheets.js +8 -0
- package/src/tools/vite/plugins/angular-memory-plugin.js +1 -1
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/supported-browsers.js +21 -11
- package/src/builders/karma/polyfills/init_test_bed.js +0 -16
package/.browserslistrc
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "20.0.0-next.
|
|
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.
|
|
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.
|
|
32
|
+
"beasties": "0.3.3",
|
|
33
33
|
"browserslist": "^4.23.0",
|
|
34
|
-
"esbuild": "0.25.
|
|
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
|
|
38
|
+
"listr2": "8.3.2",
|
|
39
39
|
"magic-string": "0.30.17",
|
|
40
40
|
"mrmime": "2.0.1",
|
|
41
|
-
"parse5-html-rewriting-stream": "7.
|
|
41
|
+
"parse5-html-rewriting-stream": "7.1.0",
|
|
42
42
|
"picomatch": "4.0.2",
|
|
43
43
|
"piscina": "4.9.2",
|
|
44
|
-
"rollup": "4.
|
|
45
|
-
"sass": "1.
|
|
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.
|
|
49
|
-
"vite": "6.2
|
|
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.
|
|
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
|
-
|
|
251
|
-
externalMetadata.
|
|
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,
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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 (
|
|
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
|
|
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
|
-
});
|