Skip to content

Commit 839d0cb

Browse files
clydinangular-robot[bot]
authored andcommittedJan 3, 2023
feat(@angular-devkit/build-angular): implement stats-json option for esbuild builder
When using the experimental esbuild-based browser application builder, the `--stats-json` option can now be used to create an esbuild metafile named `stats.json` in the output directory of the application. The metafile contents will contain information about the application JavaScript, global stylesheets, and the component stylesheets used by the Angular compiler. While the `--stats-json` option controls the output of the file onto the filesystem, the metafile data is internally always created to support the future integration of the bundle budget and console build stat output capabilities. The metafile format follows the structure of the esbuild metafile format. Information regarding the file format can be found here: https://esbuild.github.io/api/#metafile
1 parent 31f60f8 commit 839d0cb

File tree

5 files changed

+32
-2
lines changed

5 files changed

+32
-2
lines changed
 

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/compiler-plugin.ts

+16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import type {
10+
Metafile,
1011
OnStartResult,
1112
OutputFile,
1213
PartialMessage,
@@ -237,6 +238,8 @@ export function createCompilerPlugin(
237238
// The stylesheet resources from component stylesheets that will be added to the build results output files
238239
let stylesheetResourceFiles: OutputFile[];
239240

241+
let stylesheetMetafiles: Metafile[];
242+
240243
let compilation: AngularCompilation | undefined;
241244

242245
build.onStart(async () => {
@@ -252,6 +255,7 @@ export function createCompilerPlugin(
252255

253256
// Reset stylesheet resource output files
254257
stylesheetResourceFiles = [];
258+
stylesheetMetafiles = [];
255259

256260
// Create Angular compiler host options
257261
const hostOptions: AngularHostOptions = {
@@ -276,6 +280,9 @@ export function createCompilerPlugin(
276280
(result.errors ??= []).push(...errors);
277281
(result.warnings ??= []).push(...warnings);
278282
stylesheetResourceFiles.push(...resourceFiles);
283+
if (stylesheetResult.metafile) {
284+
stylesheetMetafiles.push(stylesheetResult.metafile);
285+
}
279286

280287
return contents;
281288
},
@@ -403,10 +410,19 @@ export function createCompilerPlugin(
403410
);
404411

405412
build.onEnd((result) => {
413+
// Add any component stylesheet resource files to the output files
406414
if (stylesheetResourceFiles.length) {
407415
result.outputFiles?.push(...stylesheetResourceFiles);
408416
}
409417

418+
// Combine component stylesheet metafiles with main metafile
419+
if (result.metafile && stylesheetMetafiles.length) {
420+
for (const metafile of stylesheetMetafiles) {
421+
result.metafile.inputs = { ...result.metafile.inputs, ...metafile.inputs };
422+
result.metafile.outputs = { ...result.metafile.outputs, ...metafile.outputs };
423+
}
424+
}
425+
410426
logCumulativeDurations();
411427
});
412428
},

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/experimental-warnings.ts

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const UNSUPPORTED_OPTIONS: Array<keyof BrowserBuilderOptions> = [
1515
'extractLicenses',
1616
'progress',
1717
'scripts',
18-
'statsJson',
1918

2019
// * i18n support
2120
'localize',

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
10-
import type { BuildInvalidate, BuildOptions, OutputFile } from 'esbuild';
10+
import type { BuildInvalidate, BuildOptions, Metafile, OutputFile } from 'esbuild';
1111
import assert from 'node:assert';
1212
import * as fs from 'node:fs/promises';
1313
import * as path from 'node:path';
@@ -141,6 +141,12 @@ async function execute(
141141
const initialFiles: FileInfo[] = [...codeResults.initialFiles, ...styleResults.initialFiles];
142142
const outputFiles: OutputFile[] = [...codeResults.outputFiles, ...styleResults.outputFiles];
143143

144+
// Combine metafiles used for the stats option as well as bundle budgets and console output
145+
const metafile = {
146+
inputs: { ...codeResults.metafile?.inputs, ...styleResults.metafile?.inputs },
147+
outputs: { ...codeResults.metafile?.outputs, ...styleResults.metafile?.outputs },
148+
};
149+
144150
// Generate index HTML file
145151
if (indexHtmlOptions) {
146152
// Create an index HTML generator that reads from the in-memory output files
@@ -191,6 +197,10 @@ async function execute(
191197
await Promise.all(
192198
outputFiles.map((file) => fs.writeFile(path.join(outputPath, file.path), file.contents)),
193199
);
200+
// Write metafile if stats option is enabled
201+
if (options.stats) {
202+
await fs.writeFile(path.join(outputPath, 'stats.json'), JSON.stringify(metafile, null, 2));
203+
}
194204

195205
// Augment the application with service worker support
196206
// TODO: This should eventually operate on the in-memory files prior to writing the output files
@@ -258,6 +268,7 @@ function createCodeBundleOptions(
258268
mainFields: ['es2020', 'browser', 'module', 'main'],
259269
conditions: ['es2020', 'es2015', 'module'],
260270
resolveExtensions: ['.ts', '.tsx', '.mjs', '.js'],
271+
metafile: true,
261272
logLevel: options.verbose ? 'debug' : 'silent',
262273
minify: optimizationOptions.scripts,
263274
pure: ['forwardRef'],

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/options.ts

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export async function normalizeOptions(
139139
inlineStyleLanguage = 'css',
140140
poll,
141141
preserveSymlinks,
142+
statsJson,
142143
stylePreprocessorOptions,
143144
subresourceIntegrity,
144145
verbose,
@@ -153,6 +154,7 @@ export async function normalizeOptions(
153154
crossOrigin,
154155
externalDependencies,
155156
inlineStyleLanguage,
157+
stats: !!statsJson,
156158
poll,
157159
// If not explicitly set, default to the Node.js process argument
158160
preserveSymlinks: preserveSymlinks ?? process.execArgv.includes('--preserve-symlinks'),

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/stylesheets.ts

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function createStylesheetBundleOptions(
3434
assetNames: options.outputNames?.media,
3535
logLevel: 'silent',
3636
minify: options.optimization,
37+
metafile: true,
3738
sourcemap: options.sourcemap,
3839
outdir: options.workspaceRoot,
3940
write: false,
@@ -140,5 +141,6 @@ export async function bundleComponentStylesheet(
140141
map,
141142
path: outputPath,
142143
resourceFiles,
144+
metafile: result.outputFiles && result.metafile,
143145
};
144146
}

0 commit comments

Comments
 (0)
Please sign in to comment.