@angular/build 20.2.0-next.2 → 20.2.0-rc.0
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": "20.2.0-
|
|
3
|
+
"version": "20.2.0-rc.0",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"builders": "builders.json",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ampproject/remapping": "2.3.0",
|
|
26
|
-
"@angular-devkit/architect": "0.2002.0-
|
|
26
|
+
"@angular-devkit/architect": "0.2002.0-rc.0",
|
|
27
27
|
"@babel/core": "7.28.0",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.27.3",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@vitejs/plugin-basic-ssl": "2.1.0",
|
|
32
32
|
"beasties": "0.3.5",
|
|
33
33
|
"browserslist": "^4.23.0",
|
|
34
|
-
"esbuild": "0.25.
|
|
34
|
+
"esbuild": "0.25.9",
|
|
35
35
|
"https-proxy-agent": "7.0.6",
|
|
36
36
|
"istanbul-lib-instrument": "6.0.3",
|
|
37
37
|
"jsonc-parser": "3.3.1",
|
|
@@ -41,16 +41,16 @@
|
|
|
41
41
|
"parse5-html-rewriting-stream": "8.0.0",
|
|
42
42
|
"picomatch": "4.0.3",
|
|
43
43
|
"piscina": "5.1.3",
|
|
44
|
-
"rolldown": "1.0.0-beta.
|
|
45
|
-
"sass": "1.
|
|
44
|
+
"rolldown": "1.0.0-beta.32",
|
|
45
|
+
"sass": "1.90.0",
|
|
46
46
|
"semver": "7.7.2",
|
|
47
47
|
"source-map-support": "0.5.21",
|
|
48
48
|
"tinyglobby": "0.2.14",
|
|
49
|
-
"vite": "7.
|
|
49
|
+
"vite": "7.1.2",
|
|
50
50
|
"watchpack": "2.4.4"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
|
-
"lmdb": "3.4.
|
|
53
|
+
"lmdb": "3.4.2"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"@angular/core": "^20.0.0 || ^20.2.0-next.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@angular/platform-browser": "^20.0.0 || ^20.2.0-next.0",
|
|
61
61
|
"@angular/platform-server": "^20.0.0 || ^20.2.0-next.0",
|
|
62
62
|
"@angular/service-worker": "^20.0.0 || ^20.2.0-next.0",
|
|
63
|
-
"@angular/ssr": "^20.2.0-
|
|
63
|
+
"@angular/ssr": "^20.2.0-rc.0",
|
|
64
64
|
"karma": "^6.4.0",
|
|
65
65
|
"less": "^4.2.0",
|
|
66
66
|
"ng-packagr": "^20.0.0 || ^20.2.0-next.0",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"type": "git",
|
|
113
113
|
"url": "https://github.com/angular/angular-cli.git"
|
|
114
114
|
},
|
|
115
|
-
"packageManager": "pnpm@
|
|
115
|
+
"packageManager": "pnpm@10.14.0",
|
|
116
116
|
"engines": {
|
|
117
117
|
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
|
118
118
|
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
|
@@ -6,4 +6,16 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
8
|
import { BundleContextResult } from '../../tools/esbuild/bundler-context';
|
|
9
|
+
/**
|
|
10
|
+
* Optimizes the chunks of a build result using rolldown.
|
|
11
|
+
*
|
|
12
|
+
* This function takes the output of an esbuild build, identifies the main browser entry point,
|
|
13
|
+
* and uses rolldown to bundle and optimize the JavaScript chunks. The optimized chunks
|
|
14
|
+
* replace the original ones in the build result, and the metafile is updated to reflect
|
|
15
|
+
* the changes.
|
|
16
|
+
*
|
|
17
|
+
* @param original The original build result from esbuild.
|
|
18
|
+
* @param sourcemap A boolean or 'hidden' to control sourcemap generation.
|
|
19
|
+
* @returns A promise that resolves to the updated build result with optimized chunks.
|
|
20
|
+
*/
|
|
9
21
|
export declare function optimizeChunks(original: BundleContextResult, sourcemap: boolean | 'hidden'): Promise<BundleContextResult>;
|
|
@@ -16,6 +16,123 @@ const rolldown_1 = require("rolldown");
|
|
|
16
16
|
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
17
17
|
const utils_1 = require("../../tools/esbuild/utils");
|
|
18
18
|
const error_1 = require("../../utils/error");
|
|
19
|
+
/**
|
|
20
|
+
* Converts the output of a rolldown build into an esbuild-compatible metafile.
|
|
21
|
+
* @param rolldownOutput The output of a rolldown build.
|
|
22
|
+
* @param originalMetafile The original esbuild metafile from the build.
|
|
23
|
+
* @returns An esbuild-compatible metafile.
|
|
24
|
+
*/
|
|
25
|
+
function rolldownToEsbuildMetafile(rolldownOutput, originalMetafile) {
|
|
26
|
+
const newMetafile = {
|
|
27
|
+
inputs: originalMetafile.inputs,
|
|
28
|
+
outputs: {},
|
|
29
|
+
};
|
|
30
|
+
const intermediateChunkSizes = {};
|
|
31
|
+
for (const [path, output] of Object.entries(originalMetafile.outputs)) {
|
|
32
|
+
intermediateChunkSizes[path] = Object.values(output.inputs).reduce((s, i) => s + i.bytesInOutput, 0);
|
|
33
|
+
}
|
|
34
|
+
for (const chunk of rolldownOutput) {
|
|
35
|
+
if (chunk.type === 'asset') {
|
|
36
|
+
newMetafile.outputs[chunk.fileName] = {
|
|
37
|
+
bytes: typeof chunk.source === 'string'
|
|
38
|
+
? Buffer.byteLength(chunk.source, 'utf8')
|
|
39
|
+
: chunk.source.length,
|
|
40
|
+
inputs: {},
|
|
41
|
+
imports: [],
|
|
42
|
+
exports: [],
|
|
43
|
+
};
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const newOutputInputs = {};
|
|
47
|
+
if (chunk.modules) {
|
|
48
|
+
for (const [moduleId, renderedModule] of Object.entries(chunk.modules)) {
|
|
49
|
+
const originalOutputEntry = originalMetafile.outputs[moduleId];
|
|
50
|
+
if (!originalOutputEntry?.inputs) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const totalOriginalBytesInModule = intermediateChunkSizes[moduleId];
|
|
54
|
+
if (totalOriginalBytesInModule === 0) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
for (const [originalInputPath, originalInputInfo] of Object.entries(originalOutputEntry.inputs)) {
|
|
58
|
+
const proportion = originalInputInfo.bytesInOutput / totalOriginalBytesInModule;
|
|
59
|
+
const newBytesInOutput = Math.floor(renderedModule.renderedLength * proportion);
|
|
60
|
+
const existing = newOutputInputs[originalInputPath];
|
|
61
|
+
if (existing) {
|
|
62
|
+
existing.bytesInOutput += newBytesInOutput;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
newOutputInputs[originalInputPath] = { bytesInOutput: newBytesInOutput };
|
|
66
|
+
}
|
|
67
|
+
if (!newMetafile.inputs[originalInputPath]) {
|
|
68
|
+
newMetafile.inputs[originalInputPath] = originalMetafile.inputs[originalInputPath];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const imports = [
|
|
74
|
+
...chunk.imports.map((path) => ({ path, kind: 'import-statement' })),
|
|
75
|
+
...(chunk.dynamicImports?.map((path) => ({ path, kind: 'dynamic-import' })) ?? []),
|
|
76
|
+
];
|
|
77
|
+
newMetafile.outputs[chunk.fileName] = {
|
|
78
|
+
bytes: Buffer.byteLength(chunk.code, 'utf8'),
|
|
79
|
+
inputs: newOutputInputs,
|
|
80
|
+
imports,
|
|
81
|
+
exports: chunk.exports ?? [],
|
|
82
|
+
entryPoint: chunk.isEntry && chunk.facadeModuleId
|
|
83
|
+
? originalMetafile.outputs[chunk.facadeModuleId]?.entryPoint
|
|
84
|
+
: undefined,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return newMetafile;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Creates an InitialFileRecord object with a specified depth.
|
|
91
|
+
* @param depth The depth of the file in the dependency graph.
|
|
92
|
+
* @returns An InitialFileRecord object.
|
|
93
|
+
*/
|
|
94
|
+
function createInitialFileRecord(depth) {
|
|
95
|
+
return {
|
|
96
|
+
type: 'script',
|
|
97
|
+
entrypoint: false,
|
|
98
|
+
external: false,
|
|
99
|
+
serverFile: false,
|
|
100
|
+
depth,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Creates an esbuild message object for a chunk optimization failure.
|
|
105
|
+
* @param message The error message detailing the cause of the failure.
|
|
106
|
+
* @returns A partial esbuild message object.
|
|
107
|
+
*/
|
|
108
|
+
function createChunkOptimizationFailureMessage(message) {
|
|
109
|
+
// Most of these fields are not actually needed for printing the error
|
|
110
|
+
return {
|
|
111
|
+
id: '',
|
|
112
|
+
text: 'Chunk optimization failed',
|
|
113
|
+
detail: undefined,
|
|
114
|
+
pluginName: '',
|
|
115
|
+
location: null,
|
|
116
|
+
notes: [
|
|
117
|
+
{
|
|
118
|
+
text: message,
|
|
119
|
+
location: null,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Optimizes the chunks of a build result using rolldown.
|
|
126
|
+
*
|
|
127
|
+
* This function takes the output of an esbuild build, identifies the main browser entry point,
|
|
128
|
+
* and uses rolldown to bundle and optimize the JavaScript chunks. The optimized chunks
|
|
129
|
+
* replace the original ones in the build result, and the metafile is updated to reflect
|
|
130
|
+
* the changes.
|
|
131
|
+
*
|
|
132
|
+
* @param original The original build result from esbuild.
|
|
133
|
+
* @param sourcemap A boolean or 'hidden' to control sourcemap generation.
|
|
134
|
+
* @returns A promise that resolves to the updated build result with optimized chunks.
|
|
135
|
+
*/
|
|
19
136
|
async function optimizeChunks(original, sourcemap) {
|
|
20
137
|
// Failed builds cannot be optimized
|
|
21
138
|
if (original.errors) {
|
|
@@ -32,8 +149,8 @@ async function optimizeChunks(original, sourcemap) {
|
|
|
32
149
|
break;
|
|
33
150
|
}
|
|
34
151
|
}
|
|
35
|
-
// No action required if no browser main entrypoint
|
|
36
|
-
if (!mainFile) {
|
|
152
|
+
// No action required if no browser main entrypoint or metafile for stats
|
|
153
|
+
if (!mainFile || !original.metafile) {
|
|
37
154
|
return original;
|
|
38
155
|
}
|
|
39
156
|
const chunks = {};
|
|
@@ -90,28 +207,28 @@ async function optimizeChunks(original, sourcemap) {
|
|
|
90
207
|
catch (e) {
|
|
91
208
|
(0, error_1.assertIsError)(e);
|
|
92
209
|
return {
|
|
93
|
-
errors: [
|
|
94
|
-
// Most of these fields are not actually needed for printing the error
|
|
95
|
-
{
|
|
96
|
-
id: '',
|
|
97
|
-
text: 'Chunk optimization failed',
|
|
98
|
-
detail: undefined,
|
|
99
|
-
pluginName: '',
|
|
100
|
-
location: null,
|
|
101
|
-
notes: [
|
|
102
|
-
{
|
|
103
|
-
text: e.message,
|
|
104
|
-
location: null,
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
},
|
|
108
|
-
],
|
|
210
|
+
errors: [createChunkOptimizationFailureMessage(e.message)],
|
|
109
211
|
warnings: original.warnings,
|
|
110
212
|
};
|
|
111
213
|
}
|
|
112
214
|
finally {
|
|
113
215
|
await bundle?.close();
|
|
114
216
|
}
|
|
217
|
+
// Update metafile
|
|
218
|
+
const newMetafile = rolldownToEsbuildMetafile(optimizedOutput, original.metafile);
|
|
219
|
+
// Add back the outputs that were not part of the optimization
|
|
220
|
+
for (const [path, output] of Object.entries(original.metafile.outputs)) {
|
|
221
|
+
if (usedChunks.has(path)) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
newMetafile.outputs[path] = output;
|
|
225
|
+
for (const inputPath of Object.keys(output.inputs)) {
|
|
226
|
+
if (!newMetafile.inputs[inputPath]) {
|
|
227
|
+
newMetafile.inputs[inputPath] = original.metafile.inputs[inputPath];
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
original.metafile = newMetafile;
|
|
115
232
|
// Remove used chunks and associated sourcemaps from the original result
|
|
116
233
|
original.outputFiles = original.outputFiles.filter((file) => !usedChunks.has(file.path) &&
|
|
117
234
|
!(file.path.endsWith('.map') && usedChunks.has(file.path.slice(0, -4))));
|
|
@@ -152,13 +269,7 @@ async function optimizeChunks(original, sourcemap) {
|
|
|
152
269
|
}
|
|
153
270
|
continue;
|
|
154
271
|
}
|
|
155
|
-
const record =
|
|
156
|
-
type: 'script',
|
|
157
|
-
entrypoint: false,
|
|
158
|
-
external: false,
|
|
159
|
-
serverFile: false,
|
|
160
|
-
depth: entryRecord.depth + 1,
|
|
161
|
-
};
|
|
272
|
+
const record = createInitialFileRecord(entryRecord.depth + 1);
|
|
162
273
|
entriesToAnalyze.push([importPath, record]);
|
|
163
274
|
}
|
|
164
275
|
}
|
package/src/private.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export declare function createCompilerPlugin(pluginOptions: CompilerPluginOption
|
|
|
34
34
|
}): import('esbuild').Plugin;
|
|
35
35
|
export type { AngularCompilation } from './tools/angular/compilation';
|
|
36
36
|
export { createAngularCompilation };
|
|
37
|
+
export { ComponentStylesheetBundler } from './tools/esbuild/angular/component-stylesheets';
|
|
37
38
|
export * from './utils/bundle-calculator';
|
|
38
39
|
export { checkPort } from './utils/check-port';
|
|
39
40
|
export { deleteOutputDir } from './utils/delete-output-dir';
|
package/src/private.js
CHANGED
|
@@ -21,7 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.loadPostcssConfiguration = exports.generateSearchDirectories = exports.findTailwindConfiguration = exports.getTestEntrypoints = exports.findTests = exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.generateBuildStatsTable = exports.augmentAppWithServiceWorker = exports.purgeStaleBuildCache = exports.createTranslationLoader = exports.loadProxyConfiguration = exports.InlineCriticalCssProcessor = exports.IndexHtmlGenerator = exports.loadTranslations = exports.createI18nOptions = exports.deleteOutputDir = exports.checkPort = exports.createAngularCompilation = exports.JavaScriptTransformer = exports.createJitResourceTransformer = exports.SourceFileCache = exports.SassWorkerImplementation = exports.transformSupportedBrowsersToTargets = exports.emitFilesToDisk = exports.serveWithVite = exports.ResultKind = exports.buildApplicationInternal = void 0;
|
|
24
|
+
exports.loadPostcssConfiguration = exports.generateSearchDirectories = exports.findTailwindConfiguration = exports.getTestEntrypoints = exports.findTests = exports.assertCompatibleAngularVersion = exports.getSupportedBrowsers = exports.generateBuildStatsTable = exports.augmentAppWithServiceWorker = exports.purgeStaleBuildCache = exports.createTranslationLoader = exports.loadProxyConfiguration = exports.InlineCriticalCssProcessor = exports.IndexHtmlGenerator = exports.loadTranslations = exports.createI18nOptions = exports.deleteOutputDir = exports.checkPort = exports.ComponentStylesheetBundler = exports.createAngularCompilation = exports.JavaScriptTransformer = exports.createJitResourceTransformer = exports.SourceFileCache = exports.SassWorkerImplementation = exports.transformSupportedBrowsersToTargets = exports.emitFilesToDisk = exports.serveWithVite = exports.ResultKind = exports.buildApplicationInternal = void 0;
|
|
25
25
|
exports.createCompilerPlugin = createCompilerPlugin;
|
|
26
26
|
/**
|
|
27
27
|
* @fileoverview
|
|
@@ -59,6 +59,8 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
59
59
|
? new compilation_1.NoopCompilation()
|
|
60
60
|
: () => (0, compilation_1.createAngularCompilation)(!!pluginOptions.jit, !!pluginOptions.browserOnlyBuild), new component_stylesheets_1.ComponentStylesheetBundler(styleOptions, styleOptions.inlineStyleLanguage, pluginOptions.incremental));
|
|
61
61
|
}
|
|
62
|
+
var component_stylesheets_2 = require("./tools/esbuild/angular/component-stylesheets");
|
|
63
|
+
Object.defineProperty(exports, "ComponentStylesheetBundler", { enumerable: true, get: function () { return component_stylesheets_2.ComponentStylesheetBundler; } });
|
|
62
64
|
// Utilities
|
|
63
65
|
__exportStar(require("./utils/bundle-calculator"), exports);
|
|
64
66
|
var check_port_1 = require("./utils/check-port");
|
|
@@ -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.2.0-
|
|
13
|
+
const VERSION = '20.2.0-rc.0';
|
|
14
14
|
function hasCacheMetadata(value) {
|
|
15
15
|
return (!!value &&
|
|
16
16
|
typeof value === 'object' &&
|