@angular-devkit/build-angular 17.2.0-next.0 → 17.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 +24 -25
- package/src/builders/application/build-action.d.ts +1 -0
- package/src/builders/application/build-action.js +18 -18
- package/src/builders/application/execute-build.js +8 -15
- package/src/builders/application/index.js +20 -3
- package/src/builders/application/options.d.ts +13 -2
- package/src/builders/application/options.js +16 -3
- package/src/builders/application/schema.d.ts +13 -0
- package/src/builders/application/schema.json +12 -0
- package/src/builders/application/setup-bundling.js +2 -2
- package/src/builders/browser/index.js +3 -2
- package/src/builders/dev-server/builder.js +13 -2
- package/src/builders/dev-server/options.d.ts +1 -0
- package/src/builders/dev-server/options.js +3 -1
- package/src/builders/dev-server/schema.d.ts +19 -0
- package/src/builders/dev-server/schema.json +18 -0
- package/src/builders/dev-server/vite-server.js +6 -6
- package/src/builders/extract-i18n/application-extraction.js +3 -1
- package/src/builders/server/index.js +3 -2
- package/src/tools/babel/plugins/elide-angular-metadata.d.ts +1 -1
- package/src/tools/babel/plugins/elide-angular-metadata.js +38 -30
- package/src/tools/babel/plugins/pure-toplevel-functions.d.ts +1 -1
- package/src/tools/babel/plugins/pure-toplevel-functions.js +3 -4
- package/src/tools/esbuild/angular/compiler-plugin.js +1 -1
- package/src/tools/esbuild/application-code-bundle.js +7 -4
- package/src/tools/esbuild/budget-stats.js +5 -0
- package/src/tools/esbuild/bundler-context.d.ts +1 -0
- package/src/tools/esbuild/bundler-context.js +19 -5
- package/src/tools/esbuild/bundler-execution-result.d.ts +2 -0
- package/src/tools/esbuild/bundler-execution-result.js +6 -0
- package/src/tools/esbuild/compiler-plugin-options.js +2 -1
- package/src/tools/esbuild/external-packages-plugin.d.ts +3 -1
- package/src/tools/esbuild/external-packages-plugin.js +9 -5
- package/src/tools/esbuild/global-scripts.js +3 -4
- package/src/tools/esbuild/global-styles.js +2 -1
- package/src/tools/esbuild/index-html-generator.js +4 -2
- package/src/tools/esbuild/stylesheets/bundle-options.d.ts +2 -0
- package/src/tools/esbuild/stylesheets/bundle-options.js +1 -0
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +7 -0
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js +24 -8
- package/src/tools/esbuild/utils.d.ts +5 -8
- package/src/tools/esbuild/utils.js +64 -31
- package/src/tools/vite/angular-memory-plugin.js +13 -0
- package/src/tools/webpack/utils/stats.d.ts +1 -0
- package/src/tools/webpack/utils/stats.js +101 -49
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +3 -1
- package/src/utils/load-proxy-config.js +3 -3
- package/src/utils/postcss-configuration.d.ts +11 -0
- package/src/utils/postcss-configuration.js +77 -0
|
@@ -10,23 +10,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.getSupportedNodeTargets = exports.transformSupportedBrowsersToTargets = exports.convertOutputFile = exports.createOutputFileFromData = exports.createOutputFileFromText = exports.emitFilesToDisk = exports.writeResultFiles = exports.getFeatureSupport = exports.
|
|
13
|
+
exports.logMessages = exports.getSupportedNodeTargets = exports.transformSupportedBrowsersToTargets = exports.convertOutputFile = exports.createOutputFileFromData = exports.createOutputFileFromText = exports.emitFilesToDisk = exports.writeResultFiles = exports.getFeatureSupport = exports.withNoProgress = exports.withSpinner = exports.calculateEstimatedTransferSizes = exports.logBuildStats = void 0;
|
|
14
14
|
const esbuild_1 = require("esbuild");
|
|
15
15
|
const node_crypto_1 = require("node:crypto");
|
|
16
16
|
const node_fs_1 = require("node:fs");
|
|
17
17
|
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
18
|
-
const node_path_1 =
|
|
18
|
+
const node_path_1 = require("node:path");
|
|
19
|
+
const node_url_1 = require("node:url");
|
|
19
20
|
const node_zlib_1 = require("node:zlib");
|
|
20
21
|
const semver_1 = require("semver");
|
|
21
22
|
const spinner_1 = require("../../utils/spinner");
|
|
22
23
|
const stats_1 = require("../webpack/utils/stats");
|
|
23
24
|
const bundler_context_1 = require("./bundler-context");
|
|
24
|
-
function logBuildStats(
|
|
25
|
-
const
|
|
25
|
+
function logBuildStats(metafile, initial, budgetFailures, colors, changedFiles, estimatedTransferSizes, ssrOutputEnabled, verbose) {
|
|
26
|
+
const browserStats = [];
|
|
27
|
+
const serverStats = [];
|
|
26
28
|
let unchangedCount = 0;
|
|
27
29
|
for (const [file, output] of Object.entries(metafile.outputs)) {
|
|
28
30
|
// Only display JavaScript and CSS files
|
|
29
|
-
if (
|
|
31
|
+
if (!/\.(?:css|m?js)$/.test(file)) {
|
|
30
32
|
continue;
|
|
31
33
|
}
|
|
32
34
|
// Skip internal component resources
|
|
@@ -39,28 +41,40 @@ function logBuildStats(logger, metafile, initial, budgetFailures, changedFiles,
|
|
|
39
41
|
++unchangedCount;
|
|
40
42
|
continue;
|
|
41
43
|
}
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
const isPlatformServer = output['ng-platform-server'];
|
|
46
|
+
if (isPlatformServer && !ssrOutputEnabled) {
|
|
47
|
+
// Only log server build stats when SSR is enabled.
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
42
50
|
let name = initial.get(file)?.name;
|
|
43
51
|
if (name === undefined && output.entryPoint) {
|
|
44
|
-
name = node_path_1.
|
|
45
|
-
.basename(output.entryPoint)
|
|
52
|
+
name = (0, node_path_1.basename)(output.entryPoint)
|
|
46
53
|
.replace(/\.[cm]?[jt]s$/, '')
|
|
47
54
|
.replace(/[\\/.]/g, '-');
|
|
48
55
|
}
|
|
49
|
-
|
|
56
|
+
const stat = {
|
|
50
57
|
initial: initial.has(file),
|
|
51
58
|
stats: [file, name ?? '-', output.bytes, estimatedTransferSizes?.get(file) ?? '-'],
|
|
52
|
-
}
|
|
59
|
+
};
|
|
60
|
+
if (isPlatformServer) {
|
|
61
|
+
serverStats.push(stat);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
browserStats.push(stat);
|
|
65
|
+
}
|
|
53
66
|
}
|
|
54
|
-
if (
|
|
55
|
-
const tableText = (0, stats_1.
|
|
56
|
-
|
|
67
|
+
if (browserStats.length > 0 || serverStats.length > 0) {
|
|
68
|
+
const tableText = (0, stats_1.generateEsbuildBuildStatsTable)([browserStats, serverStats], colors, unchangedCount === 0, !!estimatedTransferSizes, budgetFailures, verbose);
|
|
69
|
+
return tableText + '\n';
|
|
57
70
|
}
|
|
58
71
|
else if (changedFiles !== undefined) {
|
|
59
|
-
|
|
72
|
+
return '\nNo output file changes.\n';
|
|
60
73
|
}
|
|
61
74
|
if (unchangedCount > 0) {
|
|
62
|
-
|
|
75
|
+
return `Unchanged output files: ${unchangedCount}`;
|
|
63
76
|
}
|
|
77
|
+
return '';
|
|
64
78
|
}
|
|
65
79
|
exports.logBuildStats = logBuildStats;
|
|
66
80
|
async function calculateEstimatedTransferSizes(outputFiles) {
|
|
@@ -117,17 +131,6 @@ async function withNoProgress(text, action) {
|
|
|
117
131
|
return action();
|
|
118
132
|
}
|
|
119
133
|
exports.withNoProgress = withNoProgress;
|
|
120
|
-
async function logMessages(logger, { errors, warnings }) {
|
|
121
|
-
if (warnings?.length) {
|
|
122
|
-
const warningMessages = await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color: true });
|
|
123
|
-
logger.warn(warningMessages.join('\n'));
|
|
124
|
-
}
|
|
125
|
-
if (errors?.length) {
|
|
126
|
-
const errorMessages = await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color: true });
|
|
127
|
-
logger.error(errorMessages.join('\n'));
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
exports.logMessages = logMessages;
|
|
131
134
|
/**
|
|
132
135
|
* Generates a syntax feature object map for Angular applications based on a list of targets.
|
|
133
136
|
* A full set of feature names can be found here: https://esbuild.github.io/api/#supported
|
|
@@ -179,9 +182,9 @@ exports.getFeatureSupport = getFeatureSupport;
|
|
|
179
182
|
async function writeResultFiles(outputFiles, assetFiles, { base, browser, media, server }) {
|
|
180
183
|
const directoryExists = new Set();
|
|
181
184
|
const ensureDirectoryExists = async (destPath) => {
|
|
182
|
-
const basePath = node_path_1.
|
|
185
|
+
const basePath = (0, node_path_1.dirname)(destPath);
|
|
183
186
|
if (!directoryExists.has(basePath)) {
|
|
184
|
-
await promises_1.default.mkdir(node_path_1.
|
|
187
|
+
await promises_1.default.mkdir((0, node_path_1.join)(base, basePath), { recursive: true });
|
|
185
188
|
directoryExists.add(basePath);
|
|
186
189
|
}
|
|
187
190
|
};
|
|
@@ -202,19 +205,19 @@ async function writeResultFiles(outputFiles, assetFiles, { base, browser, media,
|
|
|
202
205
|
default:
|
|
203
206
|
throw new Error(`Unhandled write for file "${file.path}" with type "${bundler_context_1.BuildOutputFileType[file.type]}".`);
|
|
204
207
|
}
|
|
205
|
-
const destPath = node_path_1.
|
|
208
|
+
const destPath = (0, node_path_1.join)(outputDir, file.path);
|
|
206
209
|
// Ensure output subdirectories exist
|
|
207
210
|
await ensureDirectoryExists(destPath);
|
|
208
211
|
// Write file contents
|
|
209
|
-
await promises_1.default.writeFile(node_path_1.
|
|
212
|
+
await promises_1.default.writeFile((0, node_path_1.join)(base, destPath), file.contents);
|
|
210
213
|
});
|
|
211
214
|
if (assetFiles?.length) {
|
|
212
215
|
await emitFilesToDisk(assetFiles, async ({ source, destination }) => {
|
|
213
|
-
const destPath = node_path_1.
|
|
216
|
+
const destPath = (0, node_path_1.join)(browser, destination);
|
|
214
217
|
// Ensure output subdirectories exist
|
|
215
218
|
await ensureDirectoryExists(destPath);
|
|
216
219
|
// Copy file contents
|
|
217
|
-
await promises_1.default.copyFile(source, node_path_1.
|
|
220
|
+
await promises_1.default.copyFile(source, (0, node_path_1.join)(base, destPath), node_fs_1.constants.COPYFILE_FICLONE);
|
|
218
221
|
});
|
|
219
222
|
}
|
|
220
223
|
}
|
|
@@ -341,3 +344,33 @@ function getSupportedNodeTargets() {
|
|
|
341
344
|
return SUPPORTED_NODE_VERSIONS.split('||').map((v) => 'node' + (0, semver_1.coerce)(v)?.version);
|
|
342
345
|
}
|
|
343
346
|
exports.getSupportedNodeTargets = getSupportedNodeTargets;
|
|
347
|
+
async function logMessages(logger, executionResult, options) {
|
|
348
|
+
const { outputOptions: { base, server, browser }, ssrOptions, jsonLogs, colors: color, } = options;
|
|
349
|
+
const { warnings, errors, prerenderedRoutes } = executionResult;
|
|
350
|
+
const warningMessages = warnings.length
|
|
351
|
+
? await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color })
|
|
352
|
+
: [];
|
|
353
|
+
const errorMessages = errors.length ? await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color }) : [];
|
|
354
|
+
if (jsonLogs) {
|
|
355
|
+
// JSON format output
|
|
356
|
+
const manifest = {
|
|
357
|
+
errors: errorMessages,
|
|
358
|
+
warnings: warningMessages,
|
|
359
|
+
outputPaths: {
|
|
360
|
+
root: (0, node_url_1.pathToFileURL)(base),
|
|
361
|
+
browser: (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, browser)),
|
|
362
|
+
server: ssrOptions ? (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, server)) : undefined,
|
|
363
|
+
},
|
|
364
|
+
prerenderedRoutes,
|
|
365
|
+
};
|
|
366
|
+
logger.info(JSON.stringify(manifest, undefined, 2));
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (warningMessages.length) {
|
|
370
|
+
logger.warn(warningMessages.join('\n'));
|
|
371
|
+
}
|
|
372
|
+
if (errorMessages.length) {
|
|
373
|
+
logger.error(errorMessages.join('\n'));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
exports.logMessages = logMessages;
|
|
@@ -99,6 +99,19 @@ function createAngularMemoryPlugin(options) {
|
|
|
99
99
|
next();
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
|
+
// HTML fallbacking
|
|
103
|
+
// This matches what happens in the vite html fallback middleware.
|
|
104
|
+
// ref: https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L9
|
|
105
|
+
const htmlAssetSourcePath = pathname[pathname.length - 1] === '/'
|
|
106
|
+
? // Trailing slash check for `index.html`.
|
|
107
|
+
assets.get(pathname + 'index.html')
|
|
108
|
+
: // Non-trailing slash check for fallback `.html`
|
|
109
|
+
assets.get(pathname + '.html');
|
|
110
|
+
if (htmlAssetSourcePath) {
|
|
111
|
+
req.url = `${server.config.base}@fs/${encodeURI(htmlAssetSourcePath)}`;
|
|
112
|
+
next();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
102
115
|
// Resource files are handled directly.
|
|
103
116
|
// Global stylesheets (CSS files) are currently considered resources to workaround
|
|
104
117
|
// dev server sourcemap issues with stylesheets.
|
|
@@ -22,6 +22,7 @@ export interface BundleStats {
|
|
|
22
22
|
initial: boolean;
|
|
23
23
|
stats: BundleStatsData;
|
|
24
24
|
}
|
|
25
|
+
export declare function generateEsbuildBuildStatsTable([browserStats, serverStats]: [browserStats: BundleStats[], serverStats: BundleStats[]], colors: boolean, showTotalSize: boolean, showEstimatedTransferSize: boolean, budgetFailures?: BudgetCalculatorResult[], verbose?: boolean): string;
|
|
25
26
|
export declare function generateBuildStatsTable(data: BundleStats[], colors: boolean, showTotalSize: boolean, showEstimatedTransferSize: boolean, budgetFailures?: BudgetCalculatorResult[]): string;
|
|
26
27
|
export declare function statsWarningsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
|
|
27
28
|
export declare function statsErrorsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
|
|
@@ -33,11 +33,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
33
33
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34
34
|
};
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.webpackStatsLogger = exports.generateBuildEventStats = exports.createWebpackLoggingCallback = exports.statsHasWarnings = exports.statsHasErrors = exports.statsErrorsToString = exports.statsWarningsToString = exports.generateBuildStatsTable = exports.formatSize = void 0;
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const text_table_1 = __importDefault(require("text-table"));
|
|
36
|
+
exports.webpackStatsLogger = exports.generateBuildEventStats = exports.createWebpackLoggingCallback = exports.statsHasWarnings = exports.statsHasErrors = exports.statsErrorsToString = exports.statsWarningsToString = exports.generateBuildStatsTable = exports.generateEsbuildBuildStatsTable = exports.formatSize = void 0;
|
|
37
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
41
39
|
const utils_1 = require("../../../utils");
|
|
42
40
|
const color_1 = require("../../../utils/color");
|
|
43
41
|
const async_chunks_1 = require("./async-chunks");
|
|
@@ -55,8 +53,8 @@ function formatSize(size) {
|
|
|
55
53
|
}
|
|
56
54
|
exports.formatSize = formatSize;
|
|
57
55
|
function getBuildDuration(webpackStats) {
|
|
58
|
-
(0,
|
|
59
|
-
(0,
|
|
56
|
+
(0, node_assert_1.default)(webpackStats.builtAt, 'buildAt cannot be undefined');
|
|
57
|
+
(0, node_assert_1.default)(webpackStats.time, 'time cannot be undefined');
|
|
60
58
|
return Date.now() - webpackStats.builtAt + webpackStats.time;
|
|
61
59
|
}
|
|
62
60
|
function generateBundleStats(info) {
|
|
@@ -73,9 +71,31 @@ function generateBundleStats(info) {
|
|
|
73
71
|
stats: [files, names, rawSize, estimatedTransferSize],
|
|
74
72
|
};
|
|
75
73
|
}
|
|
74
|
+
function generateEsbuildBuildStatsTable([browserStats, serverStats], colors, showTotalSize, showEstimatedTransferSize, budgetFailures, verbose) {
|
|
75
|
+
const bundleInfo = generateBuildStatsData(browserStats, colors, showTotalSize, showEstimatedTransferSize, budgetFailures, verbose);
|
|
76
|
+
if (serverStats.length) {
|
|
77
|
+
const m = (x) => (colors ? color_1.colors.magenta(x) : x);
|
|
78
|
+
if (browserStats.length) {
|
|
79
|
+
bundleInfo.unshift([m('Browser bundles')]);
|
|
80
|
+
// Add seperators between browser and server logs
|
|
81
|
+
bundleInfo.push([], []);
|
|
82
|
+
}
|
|
83
|
+
bundleInfo.push([m('Server bundles')], ...generateBuildStatsData(serverStats, colors, false, false, undefined, verbose));
|
|
84
|
+
}
|
|
85
|
+
return generateTableText(bundleInfo, colors);
|
|
86
|
+
}
|
|
87
|
+
exports.generateEsbuildBuildStatsTable = generateEsbuildBuildStatsTable;
|
|
76
88
|
function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures) {
|
|
77
|
-
const
|
|
78
|
-
|
|
89
|
+
const bundleInfo = generateBuildStatsData(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures, true);
|
|
90
|
+
return generateTableText(bundleInfo, colors);
|
|
91
|
+
}
|
|
92
|
+
exports.generateBuildStatsTable = generateBuildStatsTable;
|
|
93
|
+
function generateBuildStatsData(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures, verbose) {
|
|
94
|
+
if (data.length === 0) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const g = (x) => (colors ? color_1.colors.green(x) : x);
|
|
98
|
+
const c = (x) => (colors ? color_1.colors.cyan(x) : x);
|
|
79
99
|
const r = (x) => (colors ? color_1.colors.redBright(x) : x);
|
|
80
100
|
const y = (x) => (colors ? color_1.colors.yellowBright(x) : x);
|
|
81
101
|
const bold = (x) => (colors ? color_1.colors.bold(x) : x);
|
|
@@ -94,7 +114,9 @@ function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTrans
|
|
|
94
114
|
const changedEntryChunksStats = [];
|
|
95
115
|
const changedLazyChunksStats = [];
|
|
96
116
|
let initialTotalRawSize = 0;
|
|
117
|
+
let changedLazyChunksCount = 0;
|
|
97
118
|
let initialTotalEstimatedTransferSize;
|
|
119
|
+
const maxLazyChunksWithoutBudgetFailures = 15;
|
|
98
120
|
const budgets = new Map();
|
|
99
121
|
if (budgetFailures) {
|
|
100
122
|
for (const { label, severity } of budgetFailures) {
|
|
@@ -117,12 +139,21 @@ function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTrans
|
|
|
117
139
|
});
|
|
118
140
|
for (const { initial, stats } of data) {
|
|
119
141
|
const [files, names, rawSize, estimatedTransferSize] = stats;
|
|
142
|
+
if (!initial &&
|
|
143
|
+
!verbose &&
|
|
144
|
+
changedLazyChunksStats.length >= maxLazyChunksWithoutBudgetFailures &&
|
|
145
|
+
!budgets.has(names) &&
|
|
146
|
+
!budgets.has(files)) {
|
|
147
|
+
// Limit the number of lazy chunks displayed in the stats table when there is no budget failure and not in verbose mode.
|
|
148
|
+
changedLazyChunksCount++;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
120
151
|
const getRawSizeColor = getSizeColor(names, files);
|
|
121
152
|
let data;
|
|
122
153
|
if (showEstimatedTransferSize) {
|
|
123
154
|
data = [
|
|
124
155
|
g(files),
|
|
125
|
-
names,
|
|
156
|
+
dim(names),
|
|
126
157
|
getRawSizeColor(typeof rawSize === 'number' ? formatSize(rawSize) : rawSize),
|
|
127
158
|
c(typeof estimatedTransferSize === 'number'
|
|
128
159
|
? formatSize(estimatedTransferSize)
|
|
@@ -132,7 +163,7 @@ function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTrans
|
|
|
132
163
|
else {
|
|
133
164
|
data = [
|
|
134
165
|
g(files),
|
|
135
|
-
names,
|
|
166
|
+
dim(names),
|
|
136
167
|
getRawSizeColor(typeof rawSize === 'number' ? formatSize(rawSize) : rawSize),
|
|
137
168
|
'',
|
|
138
169
|
];
|
|
@@ -151,24 +182,22 @@ function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTrans
|
|
|
151
182
|
}
|
|
152
183
|
else {
|
|
153
184
|
changedLazyChunksStats.push(data);
|
|
185
|
+
changedLazyChunksCount++;
|
|
154
186
|
}
|
|
155
187
|
}
|
|
156
188
|
const bundleInfo = [];
|
|
157
|
-
const baseTitles = ['Names', 'Raw
|
|
158
|
-
const tableAlign = ['l', 'l', 'r'];
|
|
189
|
+
const baseTitles = ['Names', 'Raw size'];
|
|
159
190
|
if (showEstimatedTransferSize) {
|
|
160
|
-
baseTitles.push('Estimated
|
|
161
|
-
tableAlign.push('r');
|
|
191
|
+
baseTitles.push('Estimated transfer size');
|
|
162
192
|
}
|
|
163
193
|
// Entry chunks
|
|
164
194
|
if (changedEntryChunksStats.length) {
|
|
165
|
-
bundleInfo.push(['Initial
|
|
195
|
+
bundleInfo.push(['Initial chunk files', ...baseTitles].map(bold), ...changedEntryChunksStats);
|
|
166
196
|
if (showTotalSize) {
|
|
167
|
-
bundleInfo.push([]);
|
|
168
197
|
const initialSizeTotalColor = getSizeColor('bundle initial', undefined, (x) => x);
|
|
169
198
|
const totalSizeElements = [
|
|
170
199
|
' ',
|
|
171
|
-
'Initial
|
|
200
|
+
'Initial total',
|
|
172
201
|
initialSizeTotalColor(formatSize(initialTotalRawSize)),
|
|
173
202
|
];
|
|
174
203
|
if (showEstimatedTransferSize) {
|
|
@@ -176,7 +205,7 @@ function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTrans
|
|
|
176
205
|
? formatSize(initialTotalEstimatedTransferSize)
|
|
177
206
|
: '-');
|
|
178
207
|
}
|
|
179
|
-
bundleInfo.push(totalSizeElements.map(bold));
|
|
208
|
+
bundleInfo.push([], totalSizeElements.map(bold));
|
|
180
209
|
}
|
|
181
210
|
}
|
|
182
211
|
// Seperator
|
|
@@ -185,18 +214,54 @@ function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTrans
|
|
|
185
214
|
}
|
|
186
215
|
// Lazy chunks
|
|
187
216
|
if (changedLazyChunksStats.length) {
|
|
188
|
-
bundleInfo.push(['Lazy
|
|
217
|
+
bundleInfo.push(['Lazy chunk files', ...baseTitles].map(bold), ...changedLazyChunksStats);
|
|
218
|
+
if (changedLazyChunksCount > changedLazyChunksStats.length) {
|
|
219
|
+
bundleInfo.push([
|
|
220
|
+
dim(`...and ${changedLazyChunksCount - changedLazyChunksStats.length} more lazy chunks files. ` +
|
|
221
|
+
'Use "--verbose" to show all the files.'),
|
|
222
|
+
]);
|
|
223
|
+
}
|
|
189
224
|
}
|
|
190
|
-
return
|
|
191
|
-
hsep: dim(' | '),
|
|
192
|
-
stringLength: (s) => (0, color_1.removeColor)(s).length,
|
|
193
|
-
align: tableAlign,
|
|
194
|
-
});
|
|
225
|
+
return bundleInfo;
|
|
195
226
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
227
|
+
function generateTableText(bundleInfo, colors) {
|
|
228
|
+
const skipText = (value) => value.includes('...and ');
|
|
229
|
+
const longest = [];
|
|
230
|
+
for (const item of bundleInfo) {
|
|
231
|
+
for (let i = 0; i < item.length; i++) {
|
|
232
|
+
if (item[i] === undefined) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const currentItem = item[i].toString();
|
|
236
|
+
if (skipText(currentItem)) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const currentLongest = (longest[i] ??= 0);
|
|
240
|
+
const currentItemLength = (0, color_1.removeColor)(currentItem).length;
|
|
241
|
+
if (currentLongest < currentItemLength) {
|
|
242
|
+
longest[i] = currentItemLength;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const seperator = colors ? color_1.colors.dim(' | ') : ' | ';
|
|
247
|
+
const outputTable = [];
|
|
248
|
+
for (const item of bundleInfo) {
|
|
249
|
+
for (let i = 0; i < longest.length; i++) {
|
|
250
|
+
if (item[i] === undefined) {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
const currentItem = item[i].toString();
|
|
254
|
+
if (skipText(currentItem)) {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
const currentItemLength = (0, color_1.removeColor)(currentItem).length;
|
|
258
|
+
const stringPad = ' '.repeat(longest[i] - currentItemLength);
|
|
259
|
+
// Values in columns at index 2 and 3 (Raw and Estimated sizes) are always right aligned.
|
|
260
|
+
item[i] = i >= 2 ? stringPad + currentItem : currentItem + stringPad;
|
|
261
|
+
}
|
|
262
|
+
outputTable.push(item.join(seperator));
|
|
263
|
+
}
|
|
264
|
+
return outputTable.join('\n');
|
|
200
265
|
}
|
|
201
266
|
// We use this cache because we can have multiple builders running in the same process,
|
|
202
267
|
// where each builder has different output path.
|
|
@@ -210,6 +275,7 @@ statsConfig, budgetFailures) {
|
|
|
210
275
|
}
|
|
211
276
|
const colors = statsConfig.colors;
|
|
212
277
|
const rs = (x) => (colors ? color_1.colors.reset(x) : x);
|
|
278
|
+
const w = (x) => (colors ? color_1.colors.bold.white(x) : x);
|
|
213
279
|
const changedChunksStats = [];
|
|
214
280
|
let unchangedChunkNumber = 0;
|
|
215
281
|
let hasEstimatedTransferSizes = false;
|
|
@@ -247,24 +313,9 @@ statsConfig, budgetFailures) {
|
|
|
247
313
|
// Such us index generation, service worker augmentation etc...
|
|
248
314
|
// This will correct the time and include these.
|
|
249
315
|
const time = getBuildDuration(json);
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
${statsTable}
|
|
254
|
-
|
|
255
|
-
${unchangedChunkNumber} unchanged chunks
|
|
256
|
-
|
|
257
|
-
${generateBuildStats(json.hash || '', time, colors)}
|
|
258
|
-
`));
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
return ('\n' +
|
|
262
|
-
rs(core_1.tags.stripIndents `
|
|
263
|
-
${statsTable}
|
|
264
|
-
|
|
265
|
-
${generateBuildStats(json.hash || '', time, colors)}
|
|
266
|
-
`));
|
|
267
|
-
}
|
|
316
|
+
return rs(`\n${statsTable}\n\n` +
|
|
317
|
+
(unchangedChunkNumber > 0 ? `${unchangedChunkNumber} unchanged chunks\n\n` : '') +
|
|
318
|
+
`Build at: ${w(new Date().toISOString())} - Hash: ${w(json.hash || '')} - Time: ${w('' + time)}ms`);
|
|
268
319
|
}
|
|
269
320
|
function statsWarningsToString(json, statsConfig) {
|
|
270
321
|
const colors = statsConfig.colors;
|
|
@@ -368,8 +419,9 @@ function createWebpackLoggingCallback(options, logger) {
|
|
|
368
419
|
...(0, helpers_1.normalizeExtraEntryPoints)(scripts, 'scripts'),
|
|
369
420
|
];
|
|
370
421
|
return (stats, config) => {
|
|
371
|
-
if (verbose) {
|
|
372
|
-
|
|
422
|
+
if (verbose && config.stats !== false) {
|
|
423
|
+
const statsOptions = config.stats === true ? undefined : config.stats;
|
|
424
|
+
logger.info(stats.toString(statsOptions));
|
|
373
425
|
}
|
|
374
426
|
const rawStats = stats.toJson((0, helpers_1.getStatsOptions)(false));
|
|
375
427
|
const webpackStats = {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.useTypeChecking = exports.shouldWatchRoot = exports.debugPerformance = exports.useLegacySass = exports.useParallelTs = exports.maxWorkers = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
10
|
+
exports.useJSONBuildLogs = exports.useTypeChecking = exports.shouldWatchRoot = exports.debugPerformance = exports.useLegacySass = exports.useParallelTs = exports.maxWorkers = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
11
11
|
const color_1 = require("./color");
|
|
12
12
|
function isDisabled(variable) {
|
|
13
13
|
return variable === '0' || variable.toLowerCase() === 'false';
|
|
@@ -85,3 +85,5 @@ const watchRootVariable = process.env['NG_BUILD_WATCH_ROOT'];
|
|
|
85
85
|
exports.shouldWatchRoot = isPresent(watchRootVariable) && isEnabled(watchRootVariable);
|
|
86
86
|
const typeCheckingVariable = process.env['NG_BUILD_TYPE_CHECK'];
|
|
87
87
|
exports.useTypeChecking = !isPresent(typeCheckingVariable) || !isDisabled(typeCheckingVariable);
|
|
88
|
+
const buildLogsJsonVariable = process.env['NG_BUILD_LOGS_JSON'];
|
|
89
|
+
exports.useJSONBuildLogs = isPresent(buildLogsJsonVariable) && isEnabled(buildLogsJsonVariable);
|
|
@@ -135,9 +135,9 @@ function normalizeProxyConfiguration(proxy) {
|
|
|
135
135
|
}
|
|
136
136
|
// TODO: Consider upstreaming glob support
|
|
137
137
|
for (const key of Object.keys(normalizedProxy)) {
|
|
138
|
-
if ((0, fast_glob_1.isDynamicPattern)(key)) {
|
|
139
|
-
const
|
|
140
|
-
normalizedProxy[
|
|
138
|
+
if (key[0] !== '^' && (0, fast_glob_1.isDynamicPattern)(key)) {
|
|
139
|
+
const pattern = (0, picomatch_1.makeRe)(key).source;
|
|
140
|
+
normalizedProxy[pattern] = normalizedProxy[key];
|
|
141
141
|
delete normalizedProxy[key];
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
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.io/license
|
|
7
|
+
*/
|
|
8
|
+
export interface PostcssConfiguration {
|
|
9
|
+
plugins: [name: string, options?: object][];
|
|
10
|
+
}
|
|
11
|
+
export declare function loadPostcssConfiguration(workspaceRoot: string, projectRoot: string): Promise<PostcssConfiguration | undefined>;
|
|
@@ -0,0 +1,77 @@
|
|
|
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.io/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.loadPostcssConfiguration = void 0;
|
|
11
|
+
const promises_1 = require("node:fs/promises");
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
const postcssConfigurationFiles = ['postcss.config.json', '.postcssrc.json'];
|
|
14
|
+
async function generateSearchDirectories(roots) {
|
|
15
|
+
return await Promise.all(roots.map((root) => (0, promises_1.readdir)(root, { withFileTypes: true }).then((entries) => ({
|
|
16
|
+
root,
|
|
17
|
+
files: new Set(entries.filter((entry) => entry.isFile()).map((entry) => entry.name)),
|
|
18
|
+
}))));
|
|
19
|
+
}
|
|
20
|
+
function findFile(searchDirectories, potentialFiles) {
|
|
21
|
+
for (const { root, files } of searchDirectories) {
|
|
22
|
+
for (const potential of potentialFiles) {
|
|
23
|
+
if (files.has(potential)) {
|
|
24
|
+
return (0, node_path_1.join)(root, potential);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
async function readPostcssConfiguration(configurationFile) {
|
|
31
|
+
const data = await (0, promises_1.readFile)(configurationFile, 'utf-8');
|
|
32
|
+
const config = JSON.parse(data);
|
|
33
|
+
return config;
|
|
34
|
+
}
|
|
35
|
+
async function loadPostcssConfiguration(workspaceRoot, projectRoot) {
|
|
36
|
+
// A configuration file can exist in the project or workspace root
|
|
37
|
+
const searchDirectories = await generateSearchDirectories([projectRoot, workspaceRoot]);
|
|
38
|
+
const configPath = findFile(searchDirectories, postcssConfigurationFiles);
|
|
39
|
+
if (!configPath) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const raw = await readPostcssConfiguration(configPath);
|
|
43
|
+
// If no plugins are defined, consider it equivalent to no configuration
|
|
44
|
+
if (!raw.plugins || typeof raw.plugins !== 'object') {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
// Normalize plugin array form
|
|
48
|
+
if (Array.isArray(raw.plugins)) {
|
|
49
|
+
if (raw.plugins.length < 1) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
const config = { plugins: [] };
|
|
53
|
+
for (const element of raw.plugins) {
|
|
54
|
+
if (typeof element === 'string') {
|
|
55
|
+
config.plugins.push([element]);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
config.plugins.push(element);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return config;
|
|
62
|
+
}
|
|
63
|
+
// Normalize plugin object map form
|
|
64
|
+
const entries = Object.entries(raw.plugins);
|
|
65
|
+
if (entries.length < 1) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const config = { plugins: [] };
|
|
69
|
+
for (const [name, options] of entries) {
|
|
70
|
+
if (!options || typeof options !== 'object') {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
config.plugins.push([name, options]);
|
|
74
|
+
}
|
|
75
|
+
return config;
|
|
76
|
+
}
|
|
77
|
+
exports.loadPostcssConfiguration = loadPostcssConfiguration;
|