@angular/build 18.1.0-rc.0 → 18.1.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 +11 -9
- package/src/builders/application/chunk-optimizer.d.ts +9 -0
- package/src/builders/application/chunk-optimizer.js +169 -0
- package/src/builders/application/execute-build.js +9 -3
- package/src/builders/application/execute-post-bundle.js +4 -4
- package/src/builders/dev-server/vite-server.js +0 -1
- package/src/tools/angular/compilation/aot-compilation.js +3 -1
- package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
- package/src/tools/angular/compilation/parallel-worker.js +2 -1
- package/src/tools/esbuild/angular/compiler-plugin.js +3 -1
- package/src/tools/esbuild/application-code-bundle.js +7 -2
- package/src/tools/esbuild/budget-stats.d.ts +2 -2
- package/src/tools/esbuild/budget-stats.js +19 -14
- package/src/tools/esbuild/bundler-context.d.ts +1 -0
- package/src/tools/esbuild/bundler-execution-result.d.ts +1 -1
- package/src/tools/esbuild/bundler-execution-result.js +1 -1
- package/src/tools/esbuild/i18n-inliner.js +2 -2
- package/src/tools/esbuild/javascript-transformer-worker.js +3 -1
- package/src/tools/esbuild/utils.d.ts +4 -3
- package/src/tools/esbuild/utils.js +97 -56
- package/src/tools/esbuild/wasm-plugin.d.ts +28 -0
- package/src/tools/esbuild/wasm-plugin.js +210 -0
- package/src/tools/esbuild/wasm.d.ts +25 -0
- package/src/tools/vite/angular-memory-plugin.d.ts +2 -5
- package/src/tools/vite/angular-memory-plugin.js +7 -161
- package/src/tools/vite/middlewares/assets-middleware.d.ts +10 -0
- package/src/tools/vite/middlewares/assets-middleware.js +94 -0
- package/src/tools/vite/middlewares/html-fallback-middleware.d.ts +10 -0
- package/src/tools/vite/middlewares/html-fallback-middleware.js +24 -0
- package/src/tools/vite/middlewares/index-html-middleware.d.ts +10 -0
- package/src/tools/vite/middlewares/index-html-middleware.js +43 -0
- package/src/tools/vite/middlewares/index.d.ts +11 -0
- package/src/tools/vite/middlewares/index.js +18 -0
- package/src/tools/vite/middlewares/ssr-middleware.d.ts +12 -0
- package/src/tools/vite/middlewares/ssr-middleware.js +57 -0
- package/src/tools/vite/utils.d.ts +16 -0
- package/src/tools/vite/utils.js +40 -0
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +4 -2
- package/src/utils/normalize-cache.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "18.1.0
|
|
3
|
+
"version": "18.1.0",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,18 +23,19 @@
|
|
|
23
23
|
"builders": "builders.json",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ampproject/remapping": "2.3.0",
|
|
26
|
-
"@angular-devkit/architect": "0.1801.0
|
|
26
|
+
"@angular-devkit/architect": "0.1801.0",
|
|
27
27
|
"@babel/core": "7.24.7",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.24.7",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
30
|
-
"@
|
|
30
|
+
"@babel/plugin-syntax-import-attributes": "7.24.7",
|
|
31
|
+
"@inquirer/confirm": "3.1.11",
|
|
31
32
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
32
33
|
"ansi-colors": "4.1.3",
|
|
33
34
|
"browserslist": "^4.23.0",
|
|
34
35
|
"critters": "0.0.24",
|
|
35
36
|
"esbuild": "0.21.5",
|
|
36
37
|
"fast-glob": "3.3.2",
|
|
37
|
-
"https-proxy-agent": "7.0.
|
|
38
|
+
"https-proxy-agent": "7.0.5",
|
|
38
39
|
"lmdb": "3.0.12",
|
|
39
40
|
"magic-string": "0.30.10",
|
|
40
41
|
"mrmime": "2.0.0",
|
|
@@ -42,17 +43,18 @@
|
|
|
42
43
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
43
44
|
"picomatch": "4.0.2",
|
|
44
45
|
"piscina": "4.6.1",
|
|
46
|
+
"rollup": "4.18.0",
|
|
45
47
|
"sass": "1.77.6",
|
|
46
48
|
"semver": "7.6.2",
|
|
47
49
|
"undici": "6.19.2",
|
|
48
|
-
"vite": "5.3.
|
|
50
|
+
"vite": "5.3.2",
|
|
49
51
|
"watchpack": "2.4.1"
|
|
50
52
|
},
|
|
51
53
|
"peerDependencies": {
|
|
52
|
-
"@angular/compiler-cli": "^18.0.0
|
|
53
|
-
"@angular/localize": "^18.0.0
|
|
54
|
-
"@angular/platform-server": "^18.0.0
|
|
55
|
-
"@angular/service-worker": "^18.0.0
|
|
54
|
+
"@angular/compiler-cli": "^18.0.0",
|
|
55
|
+
"@angular/localize": "^18.0.0",
|
|
56
|
+
"@angular/platform-server": "^18.0.0",
|
|
57
|
+
"@angular/service-worker": "^18.0.0",
|
|
56
58
|
"less": "^4.2.0",
|
|
57
59
|
"postcss": "^8.4.0",
|
|
58
60
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
+
import { BundleContextResult } from '../../tools/esbuild/bundler-context';
|
|
9
|
+
export declare function optimizeChunks(original: BundleContextResult, sourcemap: boolean | 'hidden'): Promise<BundleContextResult>;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.optimizeChunks = optimizeChunks;
|
|
14
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
|
+
const rollup_1 = require("rollup");
|
|
16
|
+
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
17
|
+
const utils_1 = require("../../tools/esbuild/utils");
|
|
18
|
+
const error_1 = require("../../utils/error");
|
|
19
|
+
async function optimizeChunks(original, sourcemap) {
|
|
20
|
+
// Failed builds cannot be optimized
|
|
21
|
+
if (original.errors) {
|
|
22
|
+
return original;
|
|
23
|
+
}
|
|
24
|
+
// Find the main browser entrypoint
|
|
25
|
+
let mainFile;
|
|
26
|
+
for (const [file, record] of original.initialFiles) {
|
|
27
|
+
if (record.name === 'main' &&
|
|
28
|
+
record.entrypoint &&
|
|
29
|
+
!record.serverFile &&
|
|
30
|
+
record.type === 'script') {
|
|
31
|
+
mainFile = file;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// No action required if no browser main entrypoint
|
|
36
|
+
if (!mainFile) {
|
|
37
|
+
return original;
|
|
38
|
+
}
|
|
39
|
+
const chunks = {};
|
|
40
|
+
const maps = {};
|
|
41
|
+
for (const originalFile of original.outputFiles) {
|
|
42
|
+
if (originalFile.type !== bundler_context_1.BuildOutputFileType.Browser) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (originalFile.path.endsWith('.js')) {
|
|
46
|
+
chunks[originalFile.path] = originalFile;
|
|
47
|
+
}
|
|
48
|
+
else if (originalFile.path.endsWith('.js.map')) {
|
|
49
|
+
// Create mapping of JS file to sourcemap content
|
|
50
|
+
maps[originalFile.path.slice(0, -4)] = originalFile;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const usedChunks = new Set();
|
|
54
|
+
let bundle;
|
|
55
|
+
let optimizedOutput;
|
|
56
|
+
try {
|
|
57
|
+
bundle = await (0, rollup_1.rollup)({
|
|
58
|
+
input: mainFile,
|
|
59
|
+
plugins: [
|
|
60
|
+
{
|
|
61
|
+
name: 'angular-bundle',
|
|
62
|
+
resolveId(source) {
|
|
63
|
+
// Remove leading `./` if present
|
|
64
|
+
const file = source[0] === '.' && source[1] === '/' ? source.slice(2) : source;
|
|
65
|
+
if (chunks[file]) {
|
|
66
|
+
return file;
|
|
67
|
+
}
|
|
68
|
+
// All other identifiers are considered external to maintain behavior
|
|
69
|
+
return { id: source, external: true };
|
|
70
|
+
},
|
|
71
|
+
load(id) {
|
|
72
|
+
(0, node_assert_1.default)(chunks[id], `Angular chunk content should always be present in chunk optimizer [${id}].`);
|
|
73
|
+
usedChunks.add(id);
|
|
74
|
+
const result = {
|
|
75
|
+
code: chunks[id].text,
|
|
76
|
+
map: maps[id]?.text,
|
|
77
|
+
};
|
|
78
|
+
return result;
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
const result = await bundle.generate({
|
|
84
|
+
compact: true,
|
|
85
|
+
sourcemap,
|
|
86
|
+
chunkFileNames(chunkInfo) {
|
|
87
|
+
// Do not add hash to file name if already present
|
|
88
|
+
return /-[a-zA-Z0-9]{8}$/.test(chunkInfo.name) ? '[name].js' : '[name]-[hash].js';
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
optimizedOutput = result.output;
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
(0, error_1.assertIsError)(e);
|
|
95
|
+
return {
|
|
96
|
+
errors: [
|
|
97
|
+
// Most of these fields are not actually needed for printing the error
|
|
98
|
+
{
|
|
99
|
+
id: '',
|
|
100
|
+
text: 'Chunk optimization failed',
|
|
101
|
+
detail: undefined,
|
|
102
|
+
pluginName: '',
|
|
103
|
+
location: null,
|
|
104
|
+
notes: [
|
|
105
|
+
{
|
|
106
|
+
text: e.message,
|
|
107
|
+
location: null,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
warnings: original.warnings,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
await bundle?.close();
|
|
117
|
+
}
|
|
118
|
+
// Remove used chunks and associated sourcemaps from the original result
|
|
119
|
+
original.outputFiles = original.outputFiles.filter((file) => !usedChunks.has(file.path) &&
|
|
120
|
+
!(file.path.endsWith('.map') && usedChunks.has(file.path.slice(0, -4))));
|
|
121
|
+
// Add new optimized chunks
|
|
122
|
+
const importsPerFile = {};
|
|
123
|
+
for (const optimizedFile of optimizedOutput) {
|
|
124
|
+
if (optimizedFile.type !== 'chunk') {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
importsPerFile[optimizedFile.fileName] = optimizedFile.imports;
|
|
128
|
+
original.outputFiles.push((0, utils_1.createOutputFile)(optimizedFile.fileName, optimizedFile.code, bundler_context_1.BuildOutputFileType.Browser));
|
|
129
|
+
if (optimizedFile.map && optimizedFile.sourcemapFileName) {
|
|
130
|
+
original.outputFiles.push((0, utils_1.createOutputFile)(optimizedFile.sourcemapFileName, optimizedFile.map.toString(), bundler_context_1.BuildOutputFileType.Browser));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Update initial files to reflect optimized chunks
|
|
134
|
+
const entriesToAnalyze = [];
|
|
135
|
+
for (const usedFile of usedChunks) {
|
|
136
|
+
// Leave the main file since its information did not change
|
|
137
|
+
if (usedFile === mainFile) {
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
139
|
+
entriesToAnalyze.push([mainFile, original.initialFiles.get(mainFile)]);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
// Remove all other used chunks
|
|
143
|
+
original.initialFiles.delete(usedFile);
|
|
144
|
+
}
|
|
145
|
+
// Analyze for transitive initial files
|
|
146
|
+
let currentEntry;
|
|
147
|
+
while ((currentEntry = entriesToAnalyze.pop())) {
|
|
148
|
+
const [entryPath, entryRecord] = currentEntry;
|
|
149
|
+
for (const importPath of importsPerFile[entryPath]) {
|
|
150
|
+
const existingRecord = original.initialFiles.get(importPath);
|
|
151
|
+
if (existingRecord) {
|
|
152
|
+
// Store the smallest value depth
|
|
153
|
+
if (existingRecord.depth > entryRecord.depth + 1) {
|
|
154
|
+
existingRecord.depth = entryRecord.depth + 1;
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const record = {
|
|
159
|
+
type: 'script',
|
|
160
|
+
entrypoint: false,
|
|
161
|
+
external: false,
|
|
162
|
+
serverFile: false,
|
|
163
|
+
depth: entryRecord.depth + 1,
|
|
164
|
+
};
|
|
165
|
+
entriesToAnalyze.push([importPath, record]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return original;
|
|
169
|
+
}
|
|
@@ -14,10 +14,13 @@ const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
|
14
14
|
const bundler_execution_result_1 = require("../../tools/esbuild/bundler-execution-result");
|
|
15
15
|
const commonjs_checker_1 = require("../../tools/esbuild/commonjs-checker");
|
|
16
16
|
const license_extractor_1 = require("../../tools/esbuild/license-extractor");
|
|
17
|
+
const profiling_1 = require("../../tools/esbuild/profiling");
|
|
17
18
|
const utils_1 = require("../../tools/esbuild/utils");
|
|
18
19
|
const bundle_calculator_1 = require("../../utils/bundle-calculator");
|
|
20
|
+
const environment_options_1 = require("../../utils/environment-options");
|
|
19
21
|
const resolve_assets_1 = require("../../utils/resolve-assets");
|
|
20
22
|
const supported_browsers_1 = require("../../utils/supported-browsers");
|
|
23
|
+
const chunk_optimizer_1 = require("./chunk-optimizer");
|
|
21
24
|
const execute_post_bundle_1 = require("./execute-post-bundle");
|
|
22
25
|
const i18n_1 = require("./i18n");
|
|
23
26
|
const setup_bundling_1 = require("./setup-bundling");
|
|
@@ -37,7 +40,10 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
37
40
|
if (bundlerContexts === undefined) {
|
|
38
41
|
bundlerContexts = (0, setup_bundling_1.setupBundlerContexts)(options, browsers, codeBundleCache);
|
|
39
42
|
}
|
|
40
|
-
|
|
43
|
+
let bundlingResult = await bundler_context_1.BundlerContext.bundleAll(bundlerContexts, rebuildState?.fileChanges.all);
|
|
44
|
+
if (options.optimizationOptions.scripts && environment_options_1.shouldOptimizeChunks) {
|
|
45
|
+
bundlingResult = await (0, profiling_1.profileAsync)('OPTIMIZE_CHUNKS', () => (0, chunk_optimizer_1.optimizeChunks)(bundlingResult, options.sourcemapOptions.scripts ? !options.sourcemapOptions.hidden || 'hidden' : false));
|
|
46
|
+
}
|
|
41
47
|
const executionResult = new bundler_execution_result_1.ExecutionResult(bundlerContexts, codeBundleCache);
|
|
42
48
|
executionResult.addWarnings(bundlingResult.warnings);
|
|
43
49
|
// Return if the bundling has errors
|
|
@@ -63,7 +69,7 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
63
69
|
// Analyze files for bundle budget failures if present
|
|
64
70
|
let budgetFailures;
|
|
65
71
|
if (options.budgets) {
|
|
66
|
-
const compatStats = (0, budget_stats_1.generateBudgetStats)(metafile, initialFiles);
|
|
72
|
+
const compatStats = (0, budget_stats_1.generateBudgetStats)(metafile, outputFiles, initialFiles);
|
|
67
73
|
budgetFailures = [...(0, bundle_calculator_1.checkBudgets)(options.budgets, compatStats, true)];
|
|
68
74
|
for (const { message, severity } of budgetFailures) {
|
|
69
75
|
if (severity === 'error') {
|
|
@@ -122,7 +128,7 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
122
128
|
executionResult.addOutputFile('stats.json', JSON.stringify(metafile, null, 2), bundler_context_1.BuildOutputFileType.Root);
|
|
123
129
|
}
|
|
124
130
|
if (!jsonLogs) {
|
|
125
|
-
executionResult.addLog((0, utils_1.logBuildStats)(metafile, initialFiles, budgetFailures, colors, changedFiles, estimatedTransferSizes, !!ssrOptions, verbose));
|
|
131
|
+
executionResult.addLog((0, utils_1.logBuildStats)(metafile, outputFiles, initialFiles, budgetFailures, colors, changedFiles, estimatedTransferSizes, !!ssrOptions, verbose));
|
|
126
132
|
}
|
|
127
133
|
return executionResult;
|
|
128
134
|
}
|
|
@@ -48,10 +48,10 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
|
|
|
48
48
|
const { csrContent, ssrContent, errors, warnings } = await (0, index_html_generator_1.generateIndexHtml)(initialFiles, outputFiles, options, locale);
|
|
49
49
|
allErrors.push(...errors);
|
|
50
50
|
allWarnings.push(...warnings);
|
|
51
|
-
additionalHtmlOutputFiles.set(indexHtmlOptions.output, (0, utils_1.
|
|
51
|
+
additionalHtmlOutputFiles.set(indexHtmlOptions.output, (0, utils_1.createOutputFile)(indexHtmlOptions.output, csrContent, bundler_context_1.BuildOutputFileType.Browser));
|
|
52
52
|
if (ssrContent) {
|
|
53
53
|
const serverIndexHtmlFilename = 'index.server.html';
|
|
54
|
-
additionalHtmlOutputFiles.set(serverIndexHtmlFilename, (0, utils_1.
|
|
54
|
+
additionalHtmlOutputFiles.set(serverIndexHtmlFilename, (0, utils_1.createOutputFile)(serverIndexHtmlFilename, ssrContent, bundler_context_1.BuildOutputFileType.Server));
|
|
55
55
|
ssrIndexContent = ssrContent;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -64,7 +64,7 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
|
|
|
64
64
|
allWarnings.push(...warnings);
|
|
65
65
|
prerenderedRoutes.push(...Array.from(generatedRoutes));
|
|
66
66
|
for (const [path, content] of Object.entries(output)) {
|
|
67
|
-
additionalHtmlOutputFiles.set(path, (0, utils_1.
|
|
67
|
+
additionalHtmlOutputFiles.set(path, (0, utils_1.createOutputFile)(path, content, bundler_context_1.BuildOutputFileType.Browser));
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
additionalOutputFiles.push(...additionalHtmlOutputFiles.values());
|
|
@@ -75,7 +75,7 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
|
|
|
75
75
|
const serviceWorkerResult = await (0, service_worker_1.augmentAppWithServiceWorkerEsbuild)(workspaceRoot, serviceWorker, options.baseHref || '/', options.indexHtmlOptions?.output,
|
|
76
76
|
// Ensure additional files recently added are used
|
|
77
77
|
[...outputFiles, ...additionalOutputFiles], assetFiles);
|
|
78
|
-
additionalOutputFiles.push((0, utils_1.
|
|
78
|
+
additionalOutputFiles.push((0, utils_1.createOutputFile)('ngsw.json', serviceWorkerResult.manifest, bundler_context_1.BuildOutputFileType.Browser));
|
|
79
79
|
additionalAssets.push(...serviceWorkerResult.assetFiles);
|
|
80
80
|
}
|
|
81
81
|
catch (error) {
|
|
@@ -136,7 +136,9 @@ class AotCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
136
136
|
const { affectedFiles, angularCompiler, compilerHost, typeScriptProgram, webWorkerTransform } = this.#state;
|
|
137
137
|
const compilerOptions = typeScriptProgram.getCompilerOptions();
|
|
138
138
|
const buildInfoFilename = compilerOptions.tsBuildInfoFile ?? '.tsbuildinfo';
|
|
139
|
-
const useTypeScriptTranspilation = !compilerOptions.isolatedModules ||
|
|
139
|
+
const useTypeScriptTranspilation = !compilerOptions.isolatedModules ||
|
|
140
|
+
!!compilerOptions.sourceMap ||
|
|
141
|
+
!!compilerOptions.inlineSourceMap;
|
|
140
142
|
const emittedFiles = new Map();
|
|
141
143
|
const writeFileCallback = (filename, contents, _a, _b, sourceFiles) => {
|
|
142
144
|
if (!sourceFiles?.length && filename.endsWith(buildInfoFilename)) {
|
|
@@ -24,6 +24,7 @@ export declare function initialize(request: InitRequest): Promise<{
|
|
|
24
24
|
allowJs: boolean | undefined;
|
|
25
25
|
isolatedModules: boolean | undefined;
|
|
26
26
|
sourceMap: boolean | undefined;
|
|
27
|
+
inlineSourceMap: boolean | undefined;
|
|
27
28
|
};
|
|
28
29
|
}>;
|
|
29
30
|
export declare function diagnose(modes: DiagnosticModes): Promise<{
|
|
@@ -70,11 +70,12 @@ async function initialize(request) {
|
|
|
70
70
|
});
|
|
71
71
|
return {
|
|
72
72
|
referencedFiles,
|
|
73
|
-
// TODO: Expand? `allowJs`, `isolatedModules`, `sourceMap` are the only fields needed currently.
|
|
73
|
+
// TODO: Expand? `allowJs`, `isolatedModules`, `sourceMap`, `inlineSourceMap` are the only fields needed currently.
|
|
74
74
|
compilerOptions: {
|
|
75
75
|
allowJs: compilerOptions.allowJs,
|
|
76
76
|
isolatedModules: compilerOptions.isolatedModules,
|
|
77
77
|
sourceMap: compilerOptions.sourceMap,
|
|
78
|
+
inlineSourceMap: compilerOptions.inlineSourceMap,
|
|
78
79
|
},
|
|
79
80
|
};
|
|
80
81
|
}
|
|
@@ -206,7 +206,8 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
206
206
|
// Typescript printing support for sourcemaps is not yet integrated.
|
|
207
207
|
useTypeScriptTranspilation =
|
|
208
208
|
!initializationResult.compilerOptions.isolatedModules ||
|
|
209
|
-
!!initializationResult.compilerOptions.sourceMap
|
|
209
|
+
!!initializationResult.compilerOptions.sourceMap ||
|
|
210
|
+
!!initializationResult.compilerOptions.inlineSourceMap;
|
|
210
211
|
referencedFiles = initializationResult.referencedFiles;
|
|
211
212
|
}
|
|
212
213
|
catch (error) {
|
|
@@ -425,6 +426,7 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
|
|
|
425
426
|
noEmitOnError: false,
|
|
426
427
|
inlineSources: !!pluginOptions.sourcemap,
|
|
427
428
|
inlineSourceMap: !!pluginOptions.sourcemap,
|
|
429
|
+
sourceMap: undefined,
|
|
428
430
|
mapRoot: undefined,
|
|
429
431
|
sourceRoot: undefined,
|
|
430
432
|
preserveSymlinks,
|
|
@@ -27,9 +27,11 @@ const rxjs_esm_resolution_plugin_1 = require("./rxjs-esm-resolution-plugin");
|
|
|
27
27
|
const sourcemap_ignorelist_plugin_1 = require("./sourcemap-ignorelist-plugin");
|
|
28
28
|
const utils_1 = require("./utils");
|
|
29
29
|
const virtual_module_plugin_1 = require("./virtual-module-plugin");
|
|
30
|
+
const wasm_plugin_1 = require("./wasm-plugin");
|
|
30
31
|
function createBrowserCodeBundleOptions(options, target, sourceFileCache) {
|
|
31
32
|
const { entryPoints, outputNames, polyfills } = options;
|
|
32
33
|
const { pluginOptions, styleOptions } = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, target, sourceFileCache);
|
|
34
|
+
const zoneless = (0, utils_1.isZonelessApp)(polyfills);
|
|
33
35
|
const buildOptions = {
|
|
34
36
|
...getEsBuildCommonOptions(options),
|
|
35
37
|
platform: 'browser',
|
|
@@ -41,8 +43,9 @@ function createBrowserCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
41
43
|
entryNames: outputNames.bundles,
|
|
42
44
|
entryPoints,
|
|
43
45
|
target,
|
|
44
|
-
supported: (0, utils_1.getFeatureSupport)(target,
|
|
46
|
+
supported: (0, utils_1.getFeatureSupport)(target, zoneless),
|
|
45
47
|
plugins: [
|
|
48
|
+
(0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: sourceFileCache?.loadResultCache }),
|
|
46
49
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
47
50
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
48
51
|
// JS/TS options
|
|
@@ -124,6 +127,7 @@ function createServerCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
124
127
|
if (ssrEntryPoint) {
|
|
125
128
|
entryPoints['server'] = ssrEntryPoint;
|
|
126
129
|
}
|
|
130
|
+
const zoneless = (0, utils_1.isZonelessApp)(polyfills);
|
|
127
131
|
const buildOptions = {
|
|
128
132
|
...getEsBuildCommonOptions(options),
|
|
129
133
|
platform: 'node',
|
|
@@ -140,8 +144,9 @@ function createServerCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
140
144
|
js: `import './polyfills.server.mjs';`,
|
|
141
145
|
},
|
|
142
146
|
entryPoints,
|
|
143
|
-
supported: (0, utils_1.getFeatureSupport)(target,
|
|
147
|
+
supported: (0, utils_1.getFeatureSupport)(target, zoneless),
|
|
144
148
|
plugins: [
|
|
149
|
+
(0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: sourceFileCache?.loadResultCache }),
|
|
145
150
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
146
151
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
147
152
|
// JS/TS options
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Metafile } from 'esbuild';
|
|
9
9
|
import type { BudgetStats } from '../../utils/bundle-calculator';
|
|
10
|
-
import type
|
|
10
|
+
import { type BuildOutputFile, type InitialFileRecord } from './bundler-context';
|
|
11
11
|
/**
|
|
12
12
|
* Generates a bundle budget calculator compatible stats object that provides
|
|
13
13
|
* the necessary information for the Webpack-based bundle budget code to
|
|
@@ -16,4 +16,4 @@ import type { InitialFileRecord } from './bundler-context';
|
|
|
16
16
|
* @param initialFiles The records of all initial files of a build.
|
|
17
17
|
* @returns A bundle budget compatible stats object.
|
|
18
18
|
*/
|
|
19
|
-
export declare function generateBudgetStats(metafile: Metafile, initialFiles: Map<string, InitialFileRecord>): BudgetStats;
|
|
19
|
+
export declare function generateBudgetStats(metafile: Metafile, outputFiles: BuildOutputFile[], initialFiles: Map<string, InitialFileRecord>): BudgetStats;
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.generateBudgetStats = generateBudgetStats;
|
|
11
|
-
const
|
|
11
|
+
const bundler_context_1 = require("./bundler-context");
|
|
12
|
+
const utils_1 = require("./utils");
|
|
12
13
|
/**
|
|
13
14
|
* Generates a bundle budget calculator compatible stats object that provides
|
|
14
15
|
* the necessary information for the Webpack-based bundle budget code to
|
|
@@ -17,39 +18,43 @@ const node_path_1 = require("node:path");
|
|
|
17
18
|
* @param initialFiles The records of all initial files of a build.
|
|
18
19
|
* @returns A bundle budget compatible stats object.
|
|
19
20
|
*/
|
|
20
|
-
function generateBudgetStats(metafile, initialFiles) {
|
|
21
|
+
function generateBudgetStats(metafile, outputFiles, initialFiles) {
|
|
21
22
|
const stats = {
|
|
22
23
|
chunks: [],
|
|
23
24
|
assets: [],
|
|
24
25
|
};
|
|
25
|
-
for (const
|
|
26
|
+
for (const { path: file, size, type } of outputFiles) {
|
|
26
27
|
if (!file.endsWith('.js') && !file.endsWith('.css')) {
|
|
27
28
|
continue;
|
|
28
29
|
}
|
|
29
30
|
// Exclude server bundles
|
|
30
|
-
|
|
31
|
-
if (entry['ng-platform-server']) {
|
|
31
|
+
if (type === bundler_context_1.BuildOutputFileType.Server) {
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
34
34
|
const initialRecord = initialFiles.get(file);
|
|
35
|
-
|
|
36
|
-
if (name === undefined && entry.entryPoint) {
|
|
37
|
-
// For non-initial lazy modules, convert the entry point file into a Webpack compatible name
|
|
38
|
-
name = (0, node_path_1.basename)(entry.entryPoint)
|
|
39
|
-
.replace(/\.[cm]?[jt]s$/, '')
|
|
40
|
-
.replace(/[\\/.]/g, '-');
|
|
41
|
-
}
|
|
35
|
+
const name = initialRecord?.name ?? (0, utils_1.getChunkNameFromMetafile)(metafile, file);
|
|
42
36
|
stats.chunks.push({
|
|
43
37
|
files: [file],
|
|
44
38
|
initial: !!initialRecord,
|
|
45
39
|
names: name ? [name] : undefined,
|
|
46
40
|
});
|
|
41
|
+
stats.assets.push({
|
|
42
|
+
name: file,
|
|
43
|
+
size,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Add component styles from metafile
|
|
47
|
+
// TODO: Provide this information directly from the AOT compiler
|
|
48
|
+
for (const entry of Object.values(metafile.outputs)) {
|
|
47
49
|
// 'ng-component' is set by the angular plugin's component stylesheet bundler
|
|
48
50
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
51
|
const componentStyle = entry['ng-component'];
|
|
52
|
+
if (!componentStyle) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
50
55
|
stats.assets.push({
|
|
51
|
-
// Component styles use the input file
|
|
52
|
-
name:
|
|
56
|
+
// Component styles use the input file
|
|
57
|
+
name: Object.keys(entry.inputs)[0],
|
|
53
58
|
size: entry.bytes,
|
|
54
59
|
componentStyle,
|
|
55
60
|
});
|
|
@@ -38,6 +38,7 @@ export declare enum BuildOutputFileType {
|
|
|
38
38
|
}
|
|
39
39
|
export interface BuildOutputFile extends OutputFile {
|
|
40
40
|
type: BuildOutputFileType;
|
|
41
|
+
readonly size: number;
|
|
41
42
|
clone: () => BuildOutputFile;
|
|
42
43
|
}
|
|
43
44
|
export type BundlerOptionsFactory<T extends BuildOptions = BuildOptions> = (loadCache: LoadResultCache | undefined) => T;
|
|
@@ -39,7 +39,7 @@ export declare class ExecutionResult {
|
|
|
39
39
|
externalMetadata?: ExternalResultMetadata;
|
|
40
40
|
extraWatchFiles: string[];
|
|
41
41
|
constructor(rebuildContexts: BundlerContext[], codeBundleCache?: SourceFileCache | undefined);
|
|
42
|
-
addOutputFile(path: string, content: string, type: BuildOutputFileType): void;
|
|
42
|
+
addOutputFile(path: string, content: string | Uint8Array, type: BuildOutputFileType): void;
|
|
43
43
|
addAssets(assets: BuildOutputAsset[]): void;
|
|
44
44
|
addLog(value: string): void;
|
|
45
45
|
addError(error: PartialMessage | string): void;
|
|
@@ -29,7 +29,7 @@ class ExecutionResult {
|
|
|
29
29
|
this.codeBundleCache = codeBundleCache;
|
|
30
30
|
}
|
|
31
31
|
addOutputFile(path, content, type) {
|
|
32
|
-
this.outputFiles.push((0, utils_1.
|
|
32
|
+
this.outputFiles.push((0, utils_1.createOutputFile)(path, content, type));
|
|
33
33
|
}
|
|
34
34
|
addAssets(assets) {
|
|
35
35
|
this.assetFiles.push(...assets);
|
|
@@ -117,9 +117,9 @@ class I18nInliner {
|
|
|
117
117
|
...rawResults.flatMap(({ file, code, map, messages }) => {
|
|
118
118
|
const type = this.#fileToType.get(file);
|
|
119
119
|
(0, node_assert_1.default)(type !== undefined, 'localized file should always have a type' + file);
|
|
120
|
-
const resultFiles = [(0, utils_1.
|
|
120
|
+
const resultFiles = [(0, utils_1.createOutputFile)(file, code, type)];
|
|
121
121
|
if (map) {
|
|
122
|
-
resultFiles.push((0, utils_1.
|
|
122
|
+
resultFiles.push((0, utils_1.createOutputFile)(file + '.map', map, type));
|
|
123
123
|
}
|
|
124
124
|
for (const message of messages) {
|
|
125
125
|
if (message.type === 'error') {
|
|
@@ -60,7 +60,9 @@ async function transformWithBabel(filename, data, options) {
|
|
|
60
60
|
const shouldLink = !options.skipLinker && (await requiresLinking(filename, data));
|
|
61
61
|
const useInputSourcemap = options.sourcemap &&
|
|
62
62
|
(!!options.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename));
|
|
63
|
-
|
|
63
|
+
// @ts-expect-error Import attribute syntax plugin does not currently have type definitions
|
|
64
|
+
const { default: importAttributePlugin } = await Promise.resolve().then(() => __importStar(require('@babel/plugin-syntax-import-attributes')));
|
|
65
|
+
const plugins = [importAttributePlugin];
|
|
64
66
|
// Lazy load the linker plugin only when linking is required
|
|
65
67
|
if (shouldLink) {
|
|
66
68
|
const linkerPlugin = await createLinkerPlugin(options);
|
|
@@ -11,7 +11,8 @@ import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from '../.
|
|
|
11
11
|
import { BudgetCalculatorResult } from '../../utils/bundle-calculator';
|
|
12
12
|
import { BuildOutputFile, BuildOutputFileType, InitialFileRecord } from './bundler-context';
|
|
13
13
|
import { BuildOutputAsset, ExecutionResult } from './bundler-execution-result';
|
|
14
|
-
export declare function logBuildStats(metafile: Metafile, initial: Map<string, InitialFileRecord>, budgetFailures: BudgetCalculatorResult[] | undefined, colors: boolean, changedFiles?: Set<string>, estimatedTransferSizes?: Map<string, number>, ssrOutputEnabled?: boolean, verbose?: boolean): string;
|
|
14
|
+
export declare function logBuildStats(metafile: Metafile, outputFiles: BuildOutputFile[], initial: Map<string, InitialFileRecord>, budgetFailures: BudgetCalculatorResult[] | undefined, colors: boolean, changedFiles?: Set<string>, estimatedTransferSizes?: Map<string, number>, ssrOutputEnabled?: boolean, verbose?: boolean): string;
|
|
15
|
+
export declare function getChunkNameFromMetafile(metafile: Metafile, file: string): string | undefined;
|
|
15
16
|
export declare function calculateEstimatedTransferSizes(outputFiles: OutputFile[]): Promise<Map<string, number>>;
|
|
16
17
|
export declare function withSpinner<T>(text: string, action: () => T | Promise<T>): Promise<T>;
|
|
17
18
|
export declare function withNoProgress<T>(text: string, action: () => T | Promise<T>): Promise<T>;
|
|
@@ -25,8 +26,7 @@ export declare function withNoProgress<T>(text: string, action: () => T | Promis
|
|
|
25
26
|
export declare function getFeatureSupport(target: string[], nativeAsyncAwait: boolean): BuildOptions['supported'];
|
|
26
27
|
export declare function writeResultFiles(outputFiles: BuildOutputFile[], assetFiles: BuildOutputAsset[] | undefined, { base, browser, server }: NormalizedOutputOptions): Promise<void>;
|
|
27
28
|
export declare function emitFilesToDisk<T = BuildOutputAsset | BuildOutputFile>(files: T[], writeFileCallback: (file: T) => Promise<void>): Promise<void>;
|
|
28
|
-
export declare function
|
|
29
|
-
export declare function createOutputFileFromData(path: string, data: Uint8Array, type: BuildOutputFileType): BuildOutputFile;
|
|
29
|
+
export declare function createOutputFile(path: string, data: string | Uint8Array, type: BuildOutputFileType): BuildOutputFile;
|
|
30
30
|
export declare function convertOutputFile(file: OutputFile, type: BuildOutputFileType): BuildOutputFile;
|
|
31
31
|
/**
|
|
32
32
|
* Transform browserlists result to esbuild target.
|
|
@@ -47,3 +47,4 @@ export declare function logMessages(logger: BuilderContext['logger'], executionR
|
|
|
47
47
|
* @returns true, when the application is considered as zoneless.
|
|
48
48
|
*/
|
|
49
49
|
export declare function isZonelessApp(polyfills: string[] | undefined): boolean;
|
|
50
|
+
export declare function getEntryPointName(entryPoint: string): string;
|