@angular-devkit/build-angular 13.1.0-next.0 → 13.1.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 +35 -35
- package/src/babel/presets/application.d.ts +5 -2
- package/src/babel/presets/application.js +7 -14
- package/src/babel/webpack-loader.js +23 -14
- package/src/builders/browser/index.js +7 -5
- package/src/builders/dev-server/index.js +31 -2
- package/src/builders/extract-i18n/ivy-extract-loader.js +4 -1
- package/src/utils/build-options.d.ts +1 -0
- package/src/utils/bundle-calculator.d.ts +6 -7
- package/src/utils/bundle-calculator.js +3 -1
- package/src/utils/environment-options.d.ts +0 -1
- package/src/utils/environment-options.js +1 -4
- package/src/utils/i18n-options.d.ts +16 -10
- package/src/utils/i18n-options.js +46 -37
- package/src/utils/index-file/augment-index-html.d.ts +5 -1
- package/src/utils/index-file/augment-index-html.js +38 -5
- package/src/utils/index.d.ts +0 -1
- package/src/utils/index.js +0 -1
- package/src/utils/normalize-builder-schema.js +2 -0
- package/src/utils/read-tsconfig.js +1 -4
- package/src/utils/supported-browsers.d.ts +8 -0
- package/src/utils/supported-browsers.js +26 -0
- package/src/webpack/configs/common.js +27 -23
- package/src/webpack/configs/dev-server.js +78 -25
- package/src/webpack/configs/styles.js +23 -14
- package/src/webpack/plugins/hmr/hmr-accept.js +4 -1
- package/src/webpack/plugins/named-chunks-plugin.d.ts +17 -0
- package/src/webpack/plugins/named-chunks-plugin.js +49 -0
- package/src/webpack/plugins/transfer-size-plugin.d.ts +12 -0
- package/src/webpack/plugins/transfer-size-plugin.js +47 -0
- package/src/webpack/utils/helpers.d.ts +3 -1
- package/src/webpack/utils/helpers.js +18 -3
- package/src/webpack/utils/stats.d.ts +10 -3
- package/src/webpack/utils/stats.js +111 -33
- package/src/utils/build-browser-features.d.ts +0 -16
- package/src/utils/build-browser-features.js +0 -54
|
@@ -30,7 +30,6 @@ exports.getStylesConfig = void 0;
|
|
|
30
30
|
const fs = __importStar(require("fs"));
|
|
31
31
|
const path = __importStar(require("path"));
|
|
32
32
|
const sass_service_1 = require("../../sass/sass-service");
|
|
33
|
-
const build_browser_features_1 = require("../../utils/build-browser-features");
|
|
34
33
|
const plugins_1 = require("../plugins");
|
|
35
34
|
const css_optimizer_plugin_1 = require("../plugins/css-optimizer-plugin");
|
|
36
35
|
const helpers_1 = require("../utils/helpers");
|
|
@@ -92,14 +91,16 @@ function getStylesConfig(wco) {
|
|
|
92
91
|
wco.logger.warn('Stylus usage is deprecated and will be removed in a future major version. ' +
|
|
93
92
|
'To opt-out of the deprecated behaviour, please migrate to another stylesheet language.');
|
|
94
93
|
}
|
|
95
|
-
const sassImplementation =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
compiler
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
const sassImplementation = getSassImplementation();
|
|
95
|
+
if (sassImplementation instanceof sass_service_1.SassWorkerImplementation) {
|
|
96
|
+
extraPlugins.push({
|
|
97
|
+
apply(compiler) {
|
|
98
|
+
compiler.hooks.shutdown.tap('sass-worker', () => {
|
|
99
|
+
sassImplementation === null || sassImplementation === void 0 ? void 0 : sassImplementation.close();
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
103
104
|
const assetNameTemplate = (0, helpers_1.assetNameTemplateFactory)(hashFormat);
|
|
104
105
|
const extraPostcssPlugins = [];
|
|
105
106
|
// Attempt to setup Tailwind CSS
|
|
@@ -134,9 +135,8 @@ function getStylesConfig(wco) {
|
|
|
134
135
|
extraPostcssPlugins.push(require(tailwindPackagePath)({ config: tailwindConfigPath }));
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
|
-
const { supportedBrowsers } = new build_browser_features_1.BuildBrowserFeatures(wco.projectRoot);
|
|
138
138
|
const postcssPresetEnvPlugin = postcssPresetEnv({
|
|
139
|
-
browsers: supportedBrowsers,
|
|
139
|
+
browsers: buildOptions.supportedBrowsers,
|
|
140
140
|
autoprefixer: true,
|
|
141
141
|
stage: 3,
|
|
142
142
|
});
|
|
@@ -342,14 +342,14 @@ function getStylesConfig(wco) {
|
|
|
342
342
|
oneOf: [
|
|
343
343
|
// Component styles are all styles except defined global styles
|
|
344
344
|
{
|
|
345
|
-
exclude: globalStylePaths,
|
|
346
345
|
use: componentStyleLoaders,
|
|
346
|
+
resourceQuery: /\?ngResource/,
|
|
347
347
|
type: 'asset/source',
|
|
348
348
|
},
|
|
349
349
|
// Global styles are only defined global styles
|
|
350
350
|
{
|
|
351
|
-
include: globalStylePaths,
|
|
352
351
|
use: globalStyleLoaders,
|
|
352
|
+
resourceQuery: { not: [/\?ngResource/] },
|
|
353
353
|
},
|
|
354
354
|
],
|
|
355
355
|
},
|
|
@@ -361,7 +361,7 @@ function getStylesConfig(wco) {
|
|
|
361
361
|
minimizer: buildOptions.optimization.styles.minify
|
|
362
362
|
? [
|
|
363
363
|
new css_optimizer_plugin_1.CssOptimizerPlugin({
|
|
364
|
-
supportedBrowsers,
|
|
364
|
+
supportedBrowsers: buildOptions.supportedBrowsers,
|
|
365
365
|
}),
|
|
366
366
|
]
|
|
367
367
|
: undefined,
|
|
@@ -370,3 +370,12 @@ function getStylesConfig(wco) {
|
|
|
370
370
|
};
|
|
371
371
|
}
|
|
372
372
|
exports.getStylesConfig = getStylesConfig;
|
|
373
|
+
function getSassImplementation() {
|
|
374
|
+
const { webcontainer } = process.versions;
|
|
375
|
+
// When `webcontainer` is a truthy it means that we are running in a StackBlitz webcontainer.
|
|
376
|
+
// `SassWorkerImplementation` uses `receiveMessageOnPort` Node.js `worker_thread` API to ensure sync behavior which is ~2x faster.
|
|
377
|
+
// However, it is non trivial to support this in a webcontainer and while slower we choose to use `dart-sass`
|
|
378
|
+
// which in Webpack uses the slower async path.
|
|
379
|
+
// We should periodically check with StackBlitz folks (Mark Whitfeld / Dominic Elm) to determine if this workaround is still needed.
|
|
380
|
+
return webcontainer ? require('sass') : new sass_service_1.SassWorkerImplementation();
|
|
381
|
+
}
|
|
@@ -140,7 +140,6 @@ function restoreFormValues(oldInputs, oldOptions) {
|
|
|
140
140
|
case 'date':
|
|
141
141
|
case 'datetime-local':
|
|
142
142
|
case 'email':
|
|
143
|
-
case 'file':
|
|
144
143
|
case 'hidden':
|
|
145
144
|
case 'month':
|
|
146
145
|
case 'number':
|
|
@@ -155,6 +154,10 @@ function restoreFormValues(oldInputs, oldOptions) {
|
|
|
155
154
|
case 'week':
|
|
156
155
|
newElement.value = oldElement.value;
|
|
157
156
|
break;
|
|
157
|
+
case 'file':
|
|
158
|
+
// Ignored due: Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement':
|
|
159
|
+
// This input element accepts a filename, which may only be programmatically set to the empty string.
|
|
160
|
+
break;
|
|
158
161
|
default:
|
|
159
162
|
console.warn('[NG HMR] Unknown input type ' + oldElement.type + '.');
|
|
160
163
|
continue;
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
import { Compiler } from 'webpack';
|
|
9
|
+
/**
|
|
10
|
+
* Webpack will not populate the chunk `name` property unless `webpackChunkName` magic comment is used.
|
|
11
|
+
* This however will also effect the filename which is not desired when using `deterministic` chunkIds.
|
|
12
|
+
* This plugin will populate the chunk `name` which is mainly used so that users can set bundle budgets on lazy chunks.
|
|
13
|
+
*/
|
|
14
|
+
export declare class NamedChunksPlugin {
|
|
15
|
+
apply(compiler: Compiler): void;
|
|
16
|
+
private generateName;
|
|
17
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
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.NamedChunksPlugin = void 0;
|
|
11
|
+
const webpack_1 = require("webpack");
|
|
12
|
+
// `ImportDependency` is not part of Webpack's depenencies typings.
|
|
13
|
+
const ImportDependency = require('webpack/lib/dependencies/ImportDependency');
|
|
14
|
+
const PLUGIN_NAME = 'named-chunks-plugin';
|
|
15
|
+
/**
|
|
16
|
+
* Webpack will not populate the chunk `name` property unless `webpackChunkName` magic comment is used.
|
|
17
|
+
* This however will also effect the filename which is not desired when using `deterministic` chunkIds.
|
|
18
|
+
* This plugin will populate the chunk `name` which is mainly used so that users can set bundle budgets on lazy chunks.
|
|
19
|
+
*/
|
|
20
|
+
class NamedChunksPlugin {
|
|
21
|
+
apply(compiler) {
|
|
22
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
23
|
+
compilation.hooks.chunkAsset.tap(PLUGIN_NAME, (chunk) => {
|
|
24
|
+
if (chunk.name) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const name = this.generateName(chunk);
|
|
28
|
+
if (name) {
|
|
29
|
+
chunk.name = name;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
generateName(chunk) {
|
|
35
|
+
for (const group of chunk.groupsIterable) {
|
|
36
|
+
const [block] = group.getBlocks();
|
|
37
|
+
if (!(block instanceof webpack_1.AsyncDependenciesBlock)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
for (const dependency of block.dependencies) {
|
|
41
|
+
if (dependency instanceof ImportDependency) {
|
|
42
|
+
return webpack_1.Template.toPath(dependency.request);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.NamedChunksPlugin = NamedChunksPlugin;
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
import { Compiler } from 'webpack';
|
|
9
|
+
export declare class TransferSizePlugin {
|
|
10
|
+
constructor();
|
|
11
|
+
apply(compiler: Compiler): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
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.TransferSizePlugin = void 0;
|
|
11
|
+
const util_1 = require("util");
|
|
12
|
+
const zlib_1 = require("zlib");
|
|
13
|
+
const brotliCompressAsync = (0, util_1.promisify)(zlib_1.brotliCompress);
|
|
14
|
+
const PLUGIN_NAME = 'angular-transfer-size-estimator';
|
|
15
|
+
class TransferSizePlugin {
|
|
16
|
+
constructor() { }
|
|
17
|
+
apply(compiler) {
|
|
18
|
+
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
19
|
+
compilation.hooks.processAssets.tapPromise({
|
|
20
|
+
name: PLUGIN_NAME,
|
|
21
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
|
|
22
|
+
}, async (compilationAssets) => {
|
|
23
|
+
const actions = [];
|
|
24
|
+
for (const assetName of Object.keys(compilationAssets)) {
|
|
25
|
+
if (!assetName.endsWith('.js') && !assetName.endsWith('.css')) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const scriptAsset = compilation.getAsset(assetName);
|
|
29
|
+
if (!scriptAsset || scriptAsset.source.size() <= 0) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
actions.push(brotliCompressAsync(scriptAsset.source.source())
|
|
33
|
+
.then((result) => {
|
|
34
|
+
compilation.updateAsset(assetName, (s) => s, {
|
|
35
|
+
estimatedTransferSize: result.length,
|
|
36
|
+
});
|
|
37
|
+
})
|
|
38
|
+
.catch((error) => {
|
|
39
|
+
compilation.warnings.push(new compilation.compiler.webpack.WebpackError(`Unable to calculate estimated transfer size for '${assetName}'. Reason: ${error.message}`));
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
await Promise.all(actions);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.TransferSizePlugin = TransferSizePlugin;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import type { ObjectPattern } from 'copy-webpack-plugin';
|
|
9
|
+
import { ScriptTarget } from 'typescript';
|
|
9
10
|
import type { Configuration, WebpackOptionsNormalized } from 'webpack';
|
|
10
11
|
import { AssetPatternClass, ExtraEntryPoint, ExtraEntryPointClass } from '../../builders/browser/schema';
|
|
11
12
|
import { WebpackConfigOptions } from '../../utils/build-options';
|
|
@@ -20,7 +21,7 @@ export declare type NormalizedEntryPoint = Required<ExtraEntryPointClass>;
|
|
|
20
21
|
export declare function normalizeExtraEntryPoints(extraEntryPoints: ExtraEntryPoint[], defaultBundleName: string): NormalizedEntryPoint[];
|
|
21
22
|
export declare function assetNameTemplateFactory(hashFormat: HashFormat): (resourcePath: string) => string;
|
|
22
23
|
export declare function getInstrumentationExcludedPaths(sourceRoot: string, excludedPaths: string[]): Set<string>;
|
|
23
|
-
export declare function getCacheSettings(wco: WebpackConfigOptions,
|
|
24
|
+
export declare function getCacheSettings(wco: WebpackConfigOptions, angularVersion: string): WebpackOptionsNormalized['cache'];
|
|
24
25
|
export declare function globalScriptsByBundleName(root: string, scripts: ExtraEntryPoint[]): {
|
|
25
26
|
bundleName: string;
|
|
26
27
|
inject: boolean;
|
|
@@ -30,4 +31,5 @@ export declare function assetPatterns(root: string, assets: AssetPatternClass[])
|
|
|
30
31
|
export declare function externalizePackages(context: string, request: string | undefined, callback: (error?: Error, result?: string) => void): void;
|
|
31
32
|
declare type WebpackStatsOptions = Exclude<Configuration['stats'], string | boolean>;
|
|
32
33
|
export declare function getStatsOptions(verbose?: boolean): WebpackStatsOptions;
|
|
34
|
+
export declare function getMainFieldsAndConditionNames(target: ScriptTarget, platformServer: boolean): Pick<WebpackOptionsNormalized['resolve'], 'mainFields' | 'conditionNames'>;
|
|
33
35
|
export {};
|
|
@@ -29,11 +29,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
29
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
exports.getStatsOptions = exports.externalizePackages = exports.assetPatterns = exports.globalScriptsByBundleName = exports.getCacheSettings = exports.getInstrumentationExcludedPaths = exports.assetNameTemplateFactory = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
|
|
32
|
+
exports.getMainFieldsAndConditionNames = exports.getStatsOptions = exports.externalizePackages = exports.assetPatterns = exports.globalScriptsByBundleName = exports.getCacheSettings = exports.getInstrumentationExcludedPaths = exports.assetNameTemplateFactory = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
|
|
33
33
|
const crypto_1 = require("crypto");
|
|
34
34
|
const fs_1 = require("fs");
|
|
35
35
|
const glob_1 = __importDefault(require("glob"));
|
|
36
36
|
const path = __importStar(require("path"));
|
|
37
|
+
const typescript_1 = require("typescript");
|
|
37
38
|
function getOutputHashFormat(option, length = 20) {
|
|
38
39
|
const hashFormats = {
|
|
39
40
|
none: { chunk: '', extract: '', file: '', script: '' },
|
|
@@ -109,7 +110,7 @@ function getInstrumentationExcludedPaths(sourceRoot, excludedPaths) {
|
|
|
109
110
|
return excluded;
|
|
110
111
|
}
|
|
111
112
|
exports.getInstrumentationExcludedPaths = getInstrumentationExcludedPaths;
|
|
112
|
-
function getCacheSettings(wco,
|
|
113
|
+
function getCacheSettings(wco, angularVersion) {
|
|
113
114
|
const { enabled, path: cacheDirectory } = wco.buildOptions.cache;
|
|
114
115
|
if (enabled) {
|
|
115
116
|
const packageVersion = require('../../../package.json').version;
|
|
@@ -131,7 +132,6 @@ function getCacheSettings(wco, supportedBrowsers, angularVersion) {
|
|
|
131
132
|
// https://github.com/angular/angular-cli/blob/736a5f89deaca85f487b78aec9ff66d4118ceb6a/packages/angular_devkit/build_angular/src/utils/i18n-options.ts#L264-L265
|
|
132
133
|
outputPath: undefined,
|
|
133
134
|
}))
|
|
134
|
-
.update(supportedBrowsers.join(''))
|
|
135
135
|
.digest('hex'),
|
|
136
136
|
};
|
|
137
137
|
}
|
|
@@ -266,3 +266,18 @@ function getStatsOptions(verbose = false) {
|
|
|
266
266
|
: webpackOutputOptions;
|
|
267
267
|
}
|
|
268
268
|
exports.getStatsOptions = getStatsOptions;
|
|
269
|
+
function getMainFieldsAndConditionNames(target, platformServer) {
|
|
270
|
+
const mainFields = platformServer
|
|
271
|
+
? ['es2015', 'module', 'main']
|
|
272
|
+
: ['es2015', 'browser', 'module', 'main'];
|
|
273
|
+
const conditionNames = ['es2015', '...'];
|
|
274
|
+
if (target >= typescript_1.ScriptTarget.ES2020) {
|
|
275
|
+
mainFields.unshift('es2020');
|
|
276
|
+
conditionNames.unshift('es2020');
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
mainFields,
|
|
280
|
+
conditionNames,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
exports.getMainFieldsAndConditionNames = getMainFieldsAndConditionNames;
|
|
@@ -9,14 +9,21 @@ import { WebpackLoggingCallback } from '@angular-devkit/build-webpack';
|
|
|
9
9
|
import { logging } from '@angular-devkit/core';
|
|
10
10
|
import { Configuration, StatsCompilation } from 'webpack';
|
|
11
11
|
import { Schema as BrowserBuilderOptions } from '../../builders/browser/schema';
|
|
12
|
+
import { BudgetCalculatorResult } from '../../utils/bundle-calculator';
|
|
12
13
|
export declare function formatSize(size: number): string;
|
|
13
|
-
export declare type BundleStatsData = [
|
|
14
|
+
export declare type BundleStatsData = [
|
|
15
|
+
files: string,
|
|
16
|
+
names: string,
|
|
17
|
+
rawSize: number | string,
|
|
18
|
+
estimatedTransferSize: number | string
|
|
19
|
+
];
|
|
14
20
|
export interface BundleStats {
|
|
15
21
|
initial: boolean;
|
|
16
22
|
stats: BundleStatsData;
|
|
17
23
|
}
|
|
18
24
|
export declare function generateBundleStats(info: {
|
|
19
|
-
|
|
25
|
+
rawSize?: number;
|
|
26
|
+
estimatedTransferSize?: number;
|
|
20
27
|
files?: string[];
|
|
21
28
|
names?: string[];
|
|
22
29
|
initial?: boolean;
|
|
@@ -27,4 +34,4 @@ export declare function statsErrorsToString(json: StatsCompilation, statsConfig:
|
|
|
27
34
|
export declare function statsHasErrors(json: StatsCompilation): boolean;
|
|
28
35
|
export declare function statsHasWarnings(json: StatsCompilation): boolean;
|
|
29
36
|
export declare function createWebpackLoggingCallback(options: BrowserBuilderOptions, logger: logging.LoggerApi): WebpackLoggingCallback;
|
|
30
|
-
export declare function webpackStatsLogger(logger: logging.LoggerApi, json: StatsCompilation, config: Configuration,
|
|
37
|
+
export declare function webpackStatsLogger(logger: logging.LoggerApi, json: StatsCompilation, config: Configuration, budgetFailures?: BudgetCalculatorResult[]): void;
|
|
@@ -50,35 +50,81 @@ function formatSize(size) {
|
|
|
50
50
|
exports.formatSize = formatSize;
|
|
51
51
|
function generateBundleStats(info) {
|
|
52
52
|
var _a, _b, _c;
|
|
53
|
-
const
|
|
53
|
+
const rawSize = typeof info.rawSize === 'number' ? info.rawSize : '-';
|
|
54
|
+
const estimatedTransferSize = typeof info.estimatedTransferSize === 'number' ? info.estimatedTransferSize : '-';
|
|
54
55
|
const files = (_b = (_a = info.files) === null || _a === void 0 ? void 0 : _a.filter((f) => !f.endsWith('.map')).map((f) => path.basename(f)).join(', ')) !== null && _b !== void 0 ? _b : '';
|
|
55
56
|
const names = ((_c = info.names) === null || _c === void 0 ? void 0 : _c.length) ? info.names.join(', ') : '-';
|
|
56
57
|
const initial = !!info.initial;
|
|
57
58
|
return {
|
|
58
59
|
initial,
|
|
59
|
-
stats: [files, names,
|
|
60
|
+
stats: [files, names, rawSize, estimatedTransferSize],
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
exports.generateBundleStats = generateBundleStats;
|
|
63
|
-
function generateBuildStatsTable(data, colors, showTotalSize) {
|
|
64
|
+
function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures) {
|
|
64
65
|
const g = (x) => (colors ? color_1.colors.greenBright(x) : x);
|
|
65
66
|
const c = (x) => (colors ? color_1.colors.cyanBright(x) : x);
|
|
67
|
+
const r = (x) => (colors ? color_1.colors.redBright(x) : x);
|
|
68
|
+
const y = (x) => (colors ? color_1.colors.yellowBright(x) : x);
|
|
66
69
|
const bold = (x) => (colors ? color_1.colors.bold(x) : x);
|
|
67
70
|
const dim = (x) => (colors ? color_1.colors.dim(x) : x);
|
|
71
|
+
const getSizeColor = (name, file, defaultColor = c) => {
|
|
72
|
+
const severity = budgets.get(name) || (file && budgets.get(file));
|
|
73
|
+
switch (severity) {
|
|
74
|
+
case 'warning':
|
|
75
|
+
return y;
|
|
76
|
+
case 'error':
|
|
77
|
+
return r;
|
|
78
|
+
default:
|
|
79
|
+
return defaultColor;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
68
82
|
const changedEntryChunksStats = [];
|
|
69
83
|
const changedLazyChunksStats = [];
|
|
70
|
-
let
|
|
84
|
+
let initialTotalRawSize = 0;
|
|
85
|
+
let initialTotalEstimatedTransferSize;
|
|
86
|
+
const budgets = new Map();
|
|
87
|
+
if (budgetFailures) {
|
|
88
|
+
for (const { label, severity } of budgetFailures) {
|
|
89
|
+
// In some cases a file can have multiple budget failures.
|
|
90
|
+
// Favor error.
|
|
91
|
+
if (label && (!budgets.has(label) || budgets.get(label) === 'warning')) {
|
|
92
|
+
budgets.set(label, severity);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
71
96
|
for (const { initial, stats } of data) {
|
|
72
|
-
const [files, names,
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
97
|
+
const [files, names, rawSize, estimatedTransferSize] = stats;
|
|
98
|
+
const getRawSizeColor = getSizeColor(names, files);
|
|
99
|
+
let data;
|
|
100
|
+
if (showEstimatedTransferSize) {
|
|
101
|
+
data = [
|
|
102
|
+
g(files),
|
|
103
|
+
names,
|
|
104
|
+
getRawSizeColor(typeof rawSize === 'number' ? formatSize(rawSize) : rawSize),
|
|
105
|
+
c(typeof estimatedTransferSize === 'number'
|
|
106
|
+
? formatSize(estimatedTransferSize)
|
|
107
|
+
: estimatedTransferSize),
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
data = [
|
|
112
|
+
g(files),
|
|
113
|
+
names,
|
|
114
|
+
getRawSizeColor(typeof rawSize === 'number' ? formatSize(rawSize) : rawSize),
|
|
115
|
+
'',
|
|
116
|
+
];
|
|
117
|
+
}
|
|
78
118
|
if (initial) {
|
|
79
119
|
changedEntryChunksStats.push(data);
|
|
80
|
-
if (typeof
|
|
81
|
-
|
|
120
|
+
if (typeof rawSize === 'number') {
|
|
121
|
+
initialTotalRawSize += rawSize;
|
|
122
|
+
}
|
|
123
|
+
if (showEstimatedTransferSize && typeof estimatedTransferSize === 'number') {
|
|
124
|
+
if (initialTotalEstimatedTransferSize === undefined) {
|
|
125
|
+
initialTotalEstimatedTransferSize = 0;
|
|
126
|
+
}
|
|
127
|
+
initialTotalEstimatedTransferSize += estimatedTransferSize;
|
|
82
128
|
}
|
|
83
129
|
}
|
|
84
130
|
else {
|
|
@@ -86,12 +132,29 @@ function generateBuildStatsTable(data, colors, showTotalSize) {
|
|
|
86
132
|
}
|
|
87
133
|
}
|
|
88
134
|
const bundleInfo = [];
|
|
135
|
+
const baseTitles = ['Names', 'Raw Size'];
|
|
136
|
+
const tableAlign = ['l', 'l', 'r'];
|
|
137
|
+
if (showEstimatedTransferSize) {
|
|
138
|
+
baseTitles.push('Estimated Transfer Size');
|
|
139
|
+
tableAlign.push('r');
|
|
140
|
+
}
|
|
89
141
|
// Entry chunks
|
|
90
142
|
if (changedEntryChunksStats.length) {
|
|
91
|
-
bundleInfo.push(['Initial Chunk Files',
|
|
143
|
+
bundleInfo.push(['Initial Chunk Files', ...baseTitles].map(bold), ...changedEntryChunksStats);
|
|
92
144
|
if (showTotalSize) {
|
|
93
145
|
bundleInfo.push([]);
|
|
94
|
-
|
|
146
|
+
const initialSizeTotalColor = getSizeColor('bundle initial', undefined, (x) => x);
|
|
147
|
+
const totalSizeElements = [
|
|
148
|
+
' ',
|
|
149
|
+
'Initial Total',
|
|
150
|
+
initialSizeTotalColor(formatSize(initialTotalRawSize)),
|
|
151
|
+
];
|
|
152
|
+
if (showEstimatedTransferSize) {
|
|
153
|
+
totalSizeElements.push(typeof initialTotalEstimatedTransferSize === 'number'
|
|
154
|
+
? formatSize(initialTotalEstimatedTransferSize)
|
|
155
|
+
: '-');
|
|
156
|
+
}
|
|
157
|
+
bundleInfo.push(totalSizeElements.map(bold));
|
|
95
158
|
}
|
|
96
159
|
}
|
|
97
160
|
// Seperator
|
|
@@ -100,12 +163,12 @@ function generateBuildStatsTable(data, colors, showTotalSize) {
|
|
|
100
163
|
}
|
|
101
164
|
// Lazy chunks
|
|
102
165
|
if (changedLazyChunksStats.length) {
|
|
103
|
-
bundleInfo.push(['Lazy Chunk Files',
|
|
166
|
+
bundleInfo.push(['Lazy Chunk Files', ...baseTitles].map(bold), ...changedLazyChunksStats);
|
|
104
167
|
}
|
|
105
168
|
return (0, text_table_1.default)(bundleInfo, {
|
|
106
169
|
hsep: dim(' | '),
|
|
107
170
|
stringLength: (s) => (0, color_1.removeColor)(s).length,
|
|
108
|
-
align:
|
|
171
|
+
align: tableAlign,
|
|
109
172
|
});
|
|
110
173
|
}
|
|
111
174
|
function generateBuildStats(hash, time, colors) {
|
|
@@ -118,30 +181,45 @@ function generateBuildStats(hash, time, colors) {
|
|
|
118
181
|
const runsCache = new Set();
|
|
119
182
|
function statsToString(json,
|
|
120
183
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
121
|
-
statsConfig,
|
|
184
|
+
statsConfig, budgetFailures) {
|
|
122
185
|
var _a, _b;
|
|
123
186
|
if (!((_a = json.chunks) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
124
187
|
return '';
|
|
125
188
|
}
|
|
126
189
|
const colors = statsConfig.colors;
|
|
127
190
|
const rs = (x) => (colors ? color_1.colors.reset(x) : x);
|
|
128
|
-
const changedChunksStats =
|
|
191
|
+
const changedChunksStats = [];
|
|
129
192
|
let unchangedChunkNumber = 0;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
193
|
+
let hasEstimatedTransferSizes = false;
|
|
194
|
+
const isFirstRun = !runsCache.has(json.outputPath || '');
|
|
195
|
+
for (const chunk of json.chunks) {
|
|
196
|
+
// During first build we want to display unchanged chunks
|
|
197
|
+
// but unchanged cached chunks are always marked as not rendered.
|
|
198
|
+
if (!isFirstRun && !chunk.rendered) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const assets = (_b = json.assets) === null || _b === void 0 ? void 0 : _b.filter((asset) => { var _a; return (_a = chunk.files) === null || _a === void 0 ? void 0 : _a.includes(asset.name); });
|
|
202
|
+
let rawSize = 0;
|
|
203
|
+
let estimatedTransferSize;
|
|
204
|
+
if (assets) {
|
|
205
|
+
for (const asset of assets) {
|
|
206
|
+
if (asset.name.endsWith('.map')) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
rawSize += asset.size;
|
|
210
|
+
if (typeof asset.info.estimatedTransferSize === 'number') {
|
|
211
|
+
if (estimatedTransferSize === undefined) {
|
|
212
|
+
estimatedTransferSize = 0;
|
|
213
|
+
hasEstimatedTransferSizes = true;
|
|
214
|
+
}
|
|
215
|
+
estimatedTransferSize += asset.info.estimatedTransferSize;
|
|
216
|
+
}
|
|
137
217
|
}
|
|
138
|
-
const assets = (_b = json.assets) === null || _b === void 0 ? void 0 : _b.filter((asset) => { var _a; return (_a = chunk.files) === null || _a === void 0 ? void 0 : _a.includes(asset.name); });
|
|
139
|
-
const summedSize = assets === null || assets === void 0 ? void 0 : assets.filter((asset) => !asset.name.endsWith('.map')).reduce((total, asset) => total + asset.size, 0);
|
|
140
|
-
changedChunksStats.push(generateBundleStats({ ...chunk, size: summedSize }));
|
|
141
218
|
}
|
|
142
|
-
|
|
143
|
-
runsCache.add(json.outputPath || '');
|
|
219
|
+
changedChunksStats.push(generateBundleStats({ ...chunk, rawSize, estimatedTransferSize }));
|
|
144
220
|
}
|
|
221
|
+
unchangedChunkNumber = json.chunks.length - changedChunksStats.length;
|
|
222
|
+
runsCache.add(json.outputPath || '');
|
|
145
223
|
// Sort chunks by size in descending order
|
|
146
224
|
changedChunksStats.sort((a, b) => {
|
|
147
225
|
if (a.stats[2] > b.stats[2]) {
|
|
@@ -152,7 +230,7 @@ statsConfig, bundleState) {
|
|
|
152
230
|
}
|
|
153
231
|
return 0;
|
|
154
232
|
});
|
|
155
|
-
const statsTable = generateBuildStatsTable(changedChunksStats, colors, unchangedChunkNumber === 0);
|
|
233
|
+
const statsTable = generateBuildStatsTable(changedChunksStats, colors, unchangedChunkNumber === 0, hasEstimatedTransferSizes, budgetFailures);
|
|
156
234
|
// In some cases we do things outside of webpack context
|
|
157
235
|
// Such us index generation, service worker augmentation etc...
|
|
158
236
|
// This will correct the time and include these.
|
|
@@ -274,8 +352,8 @@ function createWebpackLoggingCallback(options, logger) {
|
|
|
274
352
|
};
|
|
275
353
|
}
|
|
276
354
|
exports.createWebpackLoggingCallback = createWebpackLoggingCallback;
|
|
277
|
-
function webpackStatsLogger(logger, json, config,
|
|
278
|
-
logger.info(statsToString(json, config.stats,
|
|
355
|
+
function webpackStatsLogger(logger, json, config, budgetFailures) {
|
|
356
|
+
logger.info(statsToString(json, config.stats, budgetFailures));
|
|
279
357
|
if (statsHasWarnings(json)) {
|
|
280
358
|
logger.warn(statsWarningsToString(json, config.stats));
|
|
281
359
|
}
|
|
@@ -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.io/license
|
|
7
|
-
*/
|
|
8
|
-
export declare class BuildBrowserFeatures {
|
|
9
|
-
private projectRoot;
|
|
10
|
-
readonly supportedBrowsers: string[];
|
|
11
|
-
constructor(projectRoot: string);
|
|
12
|
-
/**
|
|
13
|
-
* True, when a browser feature is supported partially or fully.
|
|
14
|
-
*/
|
|
15
|
-
isFeatureSupported(featureId: string): boolean;
|
|
16
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
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
|
-
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.BuildBrowserFeatures = void 0;
|
|
14
|
-
const browserslist_1 = __importDefault(require("browserslist"));
|
|
15
|
-
const caniuse_lite_1 = require("caniuse-lite");
|
|
16
|
-
class BuildBrowserFeatures {
|
|
17
|
-
constructor(projectRoot) {
|
|
18
|
-
// By default, browserslist defaults are too inclusive
|
|
19
|
-
// https://github.com/browserslist/browserslist/blob/83764ea81ffaa39111c204b02c371afa44a4ff07/index.js#L516-L522
|
|
20
|
-
this.projectRoot = projectRoot;
|
|
21
|
-
// We change the default query to browsers that Angular support.
|
|
22
|
-
// https://angular.io/guide/browser-support
|
|
23
|
-
browserslist_1.default.defaults = [
|
|
24
|
-
'last 1 Chrome version',
|
|
25
|
-
'last 1 Firefox version',
|
|
26
|
-
'last 2 Edge major versions',
|
|
27
|
-
'last 2 Safari major versions',
|
|
28
|
-
'last 2 iOS major versions',
|
|
29
|
-
'Firefox ESR',
|
|
30
|
-
];
|
|
31
|
-
this.supportedBrowsers = (0, browserslist_1.default)(undefined, { path: this.projectRoot });
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* True, when a browser feature is supported partially or fully.
|
|
35
|
-
*/
|
|
36
|
-
isFeatureSupported(featureId) {
|
|
37
|
-
// y: feature is fully available
|
|
38
|
-
// n: feature is unavailable
|
|
39
|
-
// a: feature is partially supported
|
|
40
|
-
// x: feature is prefixed
|
|
41
|
-
const criteria = ['y', 'a'];
|
|
42
|
-
const data = (0, caniuse_lite_1.feature)(caniuse_lite_1.features[featureId]);
|
|
43
|
-
return !this.supportedBrowsers.some((browser) => {
|
|
44
|
-
const [agentId, version] = browser.split(' ');
|
|
45
|
-
const browserData = data.stats[agentId];
|
|
46
|
-
const featureStatus = (browserData && browserData[version]);
|
|
47
|
-
// We are only interested in the first character
|
|
48
|
-
// Ex: when 'a #4 #5', we only need to check for 'a'
|
|
49
|
-
// as for such cases we should polyfill these features as needed
|
|
50
|
-
return !featureStatus || !criteria.includes(featureStatus.charAt(0));
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
exports.BuildBrowserFeatures = BuildBrowserFeatures;
|