@angular-devkit/build-angular 15.0.0-next.4 → 15.0.0-next.6
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 +20 -17
- package/src/builders/app-shell/index.js +39 -40
- package/src/builders/app-shell/render-worker.d.ts +36 -0
- package/src/builders/app-shell/render-worker.js +82 -0
- package/src/builders/browser/index.d.ts +2 -0
- package/src/builders/browser/index.js +38 -19
- package/src/builders/browser/schema.json +2 -2
- package/src/builders/browser-esbuild/compiler-plugin.d.ts +1 -0
- package/src/builders/browser-esbuild/compiler-plugin.js +127 -53
- package/src/builders/browser-esbuild/index.js +3 -2
- package/src/builders/browser-esbuild/profiling.d.ts +11 -0
- package/src/builders/browser-esbuild/profiling.js +64 -0
- package/src/builders/browser-esbuild/sass-plugin.js +11 -5
- package/src/builders/browser-esbuild/schema.json +2 -2
- package/src/builders/dev-server/index.d.ts +2 -0
- package/src/builders/dev-server/index.js +10 -7
- package/src/builders/karma/find-tests-plugin.js +1 -0
- package/src/builders/karma/index.d.ts +1 -1
- package/src/builders/karma/index.js +4 -5
- package/src/builders/server/schema.json +1 -1
- package/src/sass/sass-service.d.ts +12 -1
- package/src/sass/sass-service.js +19 -11
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +3 -1
- package/src/webpack/configs/common.js +29 -5
- package/src/webpack/configs/index.d.ts +0 -1
- package/src/webpack/configs/index.js +0 -1
- package/src/webpack/configs/styles.js +49 -25
- package/src/webpack/plugins/occurrences-plugin.d.ts +18 -0
- package/src/webpack/plugins/occurrences-plugin.js +79 -0
- package/src/webpack/utils/stats.d.ts +13 -8
- package/src/webpack/utils/stats.js +57 -6
- package/src/webpack/configs/analytics.d.ts +0 -11
- package/src/webpack/configs/analytics.js +0 -27
- package/src/webpack/plugins/analytics.d.ts +0 -66
- package/src/webpack/plugins/analytics.js +0 -236
package/src/sass/sass-service.js
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.SassWorkerImplementation = void 0;
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
11
|
+
const node_path_1 = require("node:path");
|
|
12
|
+
const node_url_1 = require("node:url");
|
|
13
|
+
const node_worker_threads_1 = require("node:worker_threads");
|
|
14
14
|
const environment_options_1 = require("../utils/environment-options");
|
|
15
15
|
/**
|
|
16
16
|
* The maximum number of Workers that will be created to execute render requests.
|
|
@@ -27,7 +27,7 @@ class SassWorkerImplementation {
|
|
|
27
27
|
this.workers = [];
|
|
28
28
|
this.availableWorkers = [];
|
|
29
29
|
this.requests = new Map();
|
|
30
|
-
this.workerPath = (0,
|
|
30
|
+
this.workerPath = (0, node_path_1.join)(__dirname, './worker.js');
|
|
31
31
|
this.idCounter = 1;
|
|
32
32
|
this.nextWorkerIndex = 0;
|
|
33
33
|
}
|
|
@@ -76,7 +76,7 @@ class SassWorkerImplementation {
|
|
|
76
76
|
if (error) {
|
|
77
77
|
const url = error === null || error === void 0 ? void 0 : error.span.url;
|
|
78
78
|
if (url) {
|
|
79
|
-
error.span.url = (0,
|
|
79
|
+
error.span.url = (0, node_url_1.pathToFileURL)(url);
|
|
80
80
|
}
|
|
81
81
|
reject(error);
|
|
82
82
|
return;
|
|
@@ -96,7 +96,7 @@ class SassWorkerImplementation {
|
|
|
96
96
|
options: {
|
|
97
97
|
...serializableOptions,
|
|
98
98
|
// URL is not serializable so to convert to string here and back to URL in the worker.
|
|
99
|
-
url: url ? (0,
|
|
99
|
+
url: url ? (0, node_url_1.fileURLToPath)(url) : undefined,
|
|
100
100
|
},
|
|
101
101
|
});
|
|
102
102
|
});
|
|
@@ -115,9 +115,9 @@ class SassWorkerImplementation {
|
|
|
115
115
|
this.requests.clear();
|
|
116
116
|
}
|
|
117
117
|
createWorker() {
|
|
118
|
-
const { port1: mainImporterPort, port2: workerImporterPort } = new
|
|
118
|
+
const { port1: mainImporterPort, port2: workerImporterPort } = new node_worker_threads_1.MessageChannel();
|
|
119
119
|
const importerSignal = new Int32Array(new SharedArrayBuffer(4));
|
|
120
|
-
const worker = new
|
|
120
|
+
const worker = new node_worker_threads_1.Worker(this.workerPath, {
|
|
121
121
|
workerData: { workerImporterPort, importerSignal },
|
|
122
122
|
transferList: [workerImporterPort],
|
|
123
123
|
});
|
|
@@ -132,7 +132,7 @@ class SassWorkerImplementation {
|
|
|
132
132
|
request.callback(undefined, {
|
|
133
133
|
...response.result,
|
|
134
134
|
// URL is not serializable so in the worker we convert to string and here back to URL.
|
|
135
|
-
loadedUrls: response.result.loadedUrls.map((p) => (0,
|
|
135
|
+
loadedUrls: response.result.loadedUrls.map((p) => (0, node_url_1.pathToFileURL)(p)),
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
else {
|
|
@@ -147,8 +147,16 @@ class SassWorkerImplementation {
|
|
|
147
147
|
Atomics.notify(importerSignal, 0);
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
-
this.processImporters(request.importers, url,
|
|
150
|
+
this.processImporters(request.importers, url, {
|
|
151
|
+
...options,
|
|
152
|
+
previousResolvedModules: request.previousResolvedModules,
|
|
153
|
+
})
|
|
151
154
|
.then((result) => {
|
|
155
|
+
var _a;
|
|
156
|
+
if (result) {
|
|
157
|
+
(_a = request.previousResolvedModules) !== null && _a !== void 0 ? _a : (request.previousResolvedModules = new Set());
|
|
158
|
+
request.previousResolvedModules.add((0, node_path_1.dirname)(result));
|
|
159
|
+
}
|
|
152
160
|
mainImporterPort.postMessage(result);
|
|
153
161
|
})
|
|
154
162
|
.catch((error) => {
|
|
@@ -171,7 +179,7 @@ class SassWorkerImplementation {
|
|
|
171
179
|
// File importer (Can be sync or aync).
|
|
172
180
|
const result = await importer.findFileUrl(url, options);
|
|
173
181
|
if (result) {
|
|
174
|
-
return (0,
|
|
182
|
+
return (0, node_url_1.fileURLToPath)(result);
|
|
175
183
|
}
|
|
176
184
|
}
|
|
177
185
|
return null;
|
|
@@ -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.useLegacySass = exports.maxWorkers = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
10
|
+
exports.debugPerformance = exports.useLegacySass = 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';
|
|
@@ -77,3 +77,5 @@ exports.useLegacySass = (() => {
|
|
|
77
77
|
console.warn(color_1.colors.yellow(`Warning: 'NG_BUILD_LEGACY_SASS' environment variable support will be removed in version 16.`));
|
|
78
78
|
return isEnabled(legacySassVariable);
|
|
79
79
|
})();
|
|
80
|
+
const debugPerfVariable = process.env['NG_BUILD_DEBUG_PERF'];
|
|
81
|
+
exports.debugPerformance = isPresent(debugPerfVariable) && isEnabled(debugPerfVariable);
|
|
@@ -44,6 +44,7 @@ const load_esm_1 = require("../../utils/load-esm");
|
|
|
44
44
|
const plugins_1 = require("../plugins");
|
|
45
45
|
const devtools_ignore_plugin_1 = require("../plugins/devtools-ignore-plugin");
|
|
46
46
|
const named_chunks_plugin_1 = require("../plugins/named-chunks-plugin");
|
|
47
|
+
const occurrences_plugin_1 = require("../plugins/occurrences-plugin");
|
|
47
48
|
const progress_plugin_1 = require("../plugins/progress-plugin");
|
|
48
49
|
const transfer_size_plugin_1 = require("../plugins/transfer-size-plugin");
|
|
49
50
|
const typescript_1 = require("../plugins/typescript");
|
|
@@ -52,7 +53,7 @@ const helpers_1 = require("../utils/helpers");
|
|
|
52
53
|
const VENDORS_TEST = /[\\/]node_modules[\\/]/;
|
|
53
54
|
// eslint-disable-next-line max-lines-per-function
|
|
54
55
|
async function getCommonConfig(wco) {
|
|
55
|
-
var _a, _b;
|
|
56
|
+
var _a, _b, _c;
|
|
56
57
|
const { root, projectRoot, buildOptions, tsConfig, projectName, sourceRoot, tsConfigPath } = wco;
|
|
57
58
|
const { cache, codeCoverage, crossOrigin = 'none', platform = 'browser', aot = true, codeCoverageExclude = [], main, polyfills, sourceMap: { styles: stylesSourceMap, scripts: scriptsSourceMap, vendor: vendorSourceMap, hidden: hiddenSourceMap, }, optimization: { styles: stylesOptimization, scripts: scriptsOptimization }, commonChunk, vendorChunk, subresourceIntegrity, verbose, poll, webWorkerTsConfig, externalDependencies = [], allowedCommonJsDependencies, } = buildOptions;
|
|
58
59
|
const isPlatformServer = buildOptions.platform === 'server';
|
|
@@ -68,13 +69,28 @@ async function getCommonConfig(wco) {
|
|
|
68
69
|
if (buildOptions.progress) {
|
|
69
70
|
extraPlugins.push(new progress_plugin_1.ProgressPlugin(platform));
|
|
70
71
|
}
|
|
72
|
+
const localizePackageInitEntryPoint = '@angular/localize/init';
|
|
73
|
+
const hasLocalizeType = (_a = tsConfig.options.types) === null || _a === void 0 ? void 0 : _a.some((t) => t === '@angular/localize' || t === localizePackageInitEntryPoint);
|
|
74
|
+
if (hasLocalizeType) {
|
|
75
|
+
entryPoints['main'] = [localizePackageInitEntryPoint];
|
|
76
|
+
}
|
|
71
77
|
if (buildOptions.main) {
|
|
72
78
|
const mainPath = path.resolve(root, buildOptions.main);
|
|
73
|
-
entryPoints['main']
|
|
79
|
+
if (Array.isArray(entryPoints['main'])) {
|
|
80
|
+
entryPoints['main'].push(mainPath);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
entryPoints['main'] = [mainPath];
|
|
84
|
+
}
|
|
74
85
|
}
|
|
75
86
|
if (isPlatformServer) {
|
|
76
87
|
// Fixes Critical dependency: the request of a dependency is an expression
|
|
77
88
|
extraPlugins.push(new webpack_2.ContextReplacementPlugin(/@?hapi|express[\\/]/));
|
|
89
|
+
if (Array.isArray(entryPoints['main'])) {
|
|
90
|
+
// This import must come before any imports (direct or transitive) that rely on DOM built-ins being
|
|
91
|
+
// available, such as `@angular/elements`.
|
|
92
|
+
entryPoints['main'].unshift('@angular/platform-server/init');
|
|
93
|
+
}
|
|
78
94
|
}
|
|
79
95
|
if (polyfills === null || polyfills === void 0 ? void 0 : polyfills.length) {
|
|
80
96
|
// `zone.js/testing` is a **special** polyfill because when not imported in the main it fails with the below errors:
|
|
@@ -253,9 +269,9 @@ async function getCommonConfig(wco) {
|
|
|
253
269
|
output: {
|
|
254
270
|
uniqueName: projectName,
|
|
255
271
|
hashFunction: 'xxhash64',
|
|
256
|
-
clean: (
|
|
272
|
+
clean: (_b = buildOptions.deleteOutputPath) !== null && _b !== void 0 ? _b : true,
|
|
257
273
|
path: path.resolve(root, buildOptions.outputPath),
|
|
258
|
-
publicPath: (
|
|
274
|
+
publicPath: (_c = buildOptions.deployUrl) !== null && _c !== void 0 ? _c : '',
|
|
259
275
|
filename: `[name]${hashFormat.chunk}.js`,
|
|
260
276
|
chunkFilename: `[name]${hashFormat.chunk}.js`,
|
|
261
277
|
libraryTarget: isPlatformServer ? 'commonjs' : undefined,
|
|
@@ -385,7 +401,15 @@ async function getCommonConfig(wco) {
|
|
|
385
401
|
},
|
|
386
402
|
},
|
|
387
403
|
},
|
|
388
|
-
plugins: [
|
|
404
|
+
plugins: [
|
|
405
|
+
new named_chunks_plugin_1.NamedChunksPlugin(),
|
|
406
|
+
new occurrences_plugin_1.OccurrencesPlugin({
|
|
407
|
+
aot,
|
|
408
|
+
scriptsOptimization,
|
|
409
|
+
}),
|
|
410
|
+
new plugins_1.DedupeModuleResolvePlugin({ verbose }),
|
|
411
|
+
...extraPlugins,
|
|
412
|
+
],
|
|
389
413
|
node: false,
|
|
390
414
|
};
|
|
391
415
|
}
|
|
@@ -21,7 +21,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
__exportStar(require("./analytics"), exports);
|
|
25
24
|
__exportStar(require("./common"), exports);
|
|
26
25
|
__exportStar(require("./dev-server"), exports);
|
|
27
26
|
__exportStar(require("./styles"), exports);
|
|
@@ -34,10 +34,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
34
34
|
};
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.getStylesConfig = void 0;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
37
|
const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
|
|
39
|
-
const
|
|
40
|
-
const
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
const node_url_1 = require("node:url");
|
|
41
41
|
const sass_service_1 = require("../../sass/sass-service");
|
|
42
42
|
const sass_service_legacy_1 = require("../../sass/sass-service-legacy");
|
|
43
43
|
const environment_options_1 = require("../../utils/environment-options");
|
|
@@ -48,7 +48,7 @@ const helpers_1 = require("../utils/helpers");
|
|
|
48
48
|
// eslint-disable-next-line max-lines-per-function
|
|
49
49
|
function getStylesConfig(wco) {
|
|
50
50
|
var _a, _b, _c;
|
|
51
|
-
const { root,
|
|
51
|
+
const { root, buildOptions } = wco;
|
|
52
52
|
const extraPlugins = [];
|
|
53
53
|
extraPlugins.push(new plugins_1.AnyComponentStyleBudgetChecker(buildOptions.budgets));
|
|
54
54
|
const cssSourceMap = buildOptions.sourceMap.styles;
|
|
@@ -101,10 +101,8 @@ function getStylesConfig(wco) {
|
|
|
101
101
|
extraPostcssPlugins.push(require(tailwindPackagePath)({ config: tailwindConfigPath }));
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
const postcssImports = require('postcss-import');
|
|
105
104
|
const autoprefixer = require('autoprefixer');
|
|
106
105
|
const postcssOptionsCreator = (inlineSourcemaps, extracted) => {
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
106
|
const optionGenerator = (loader) => ({
|
|
109
107
|
map: inlineSourcemaps
|
|
110
108
|
? {
|
|
@@ -113,20 +111,6 @@ function getStylesConfig(wco) {
|
|
|
113
111
|
}
|
|
114
112
|
: undefined,
|
|
115
113
|
plugins: [
|
|
116
|
-
postcssImports({
|
|
117
|
-
load: (filename) => {
|
|
118
|
-
return new Promise((resolve, reject) => {
|
|
119
|
-
loader.fs.readFile(filename, (err, data) => {
|
|
120
|
-
if (err) {
|
|
121
|
-
reject(err);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
const content = data.toString();
|
|
125
|
-
resolve(content);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
},
|
|
129
|
-
}),
|
|
130
114
|
(0, plugins_1.PostcssCliResources)({
|
|
131
115
|
baseHref: buildOptions.baseHref,
|
|
132
116
|
deployUrl: buildOptions.deployUrl,
|
|
@@ -165,6 +149,16 @@ function getStylesConfig(wco) {
|
|
|
165
149
|
const postCss = require('postcss');
|
|
166
150
|
const postCssLoaderPath = require.resolve('postcss-loader');
|
|
167
151
|
const componentStyleLoaders = [
|
|
152
|
+
{
|
|
153
|
+
loader: require.resolve('css-loader'),
|
|
154
|
+
options: {
|
|
155
|
+
url: false,
|
|
156
|
+
sourceMap: componentsSourceMap,
|
|
157
|
+
importLoaders: 1,
|
|
158
|
+
exportType: 'string',
|
|
159
|
+
esModule: false,
|
|
160
|
+
},
|
|
161
|
+
},
|
|
168
162
|
{
|
|
169
163
|
loader: postCssLoaderPath,
|
|
170
164
|
options: {
|
|
@@ -182,6 +176,7 @@ function getStylesConfig(wco) {
|
|
|
182
176
|
options: {
|
|
183
177
|
url: false,
|
|
184
178
|
sourceMap: !!cssSourceMap,
|
|
179
|
+
importLoaders: 1,
|
|
185
180
|
},
|
|
186
181
|
},
|
|
187
182
|
{
|
|
@@ -261,7 +256,6 @@ function getStylesConfig(wco) {
|
|
|
261
256
|
// Component styles are all styles except defined global styles
|
|
262
257
|
{
|
|
263
258
|
use: componentStyleLoaders,
|
|
264
|
-
type: 'asset/source',
|
|
265
259
|
resourceQuery: /\?ngResource/,
|
|
266
260
|
},
|
|
267
261
|
],
|
|
@@ -370,11 +364,41 @@ function getSassResolutionImporter(loaderContext, root, preserveSymlinks) {
|
|
|
370
364
|
mainFiles: ['_index', 'index', '...'],
|
|
371
365
|
});
|
|
372
366
|
return {
|
|
373
|
-
findFileUrl: (url, { fromImport }) => {
|
|
367
|
+
findFileUrl: async (url, { fromImport, previousResolvedModules }) => {
|
|
368
|
+
if (url.charAt(0) === '.') {
|
|
369
|
+
// Let Sass handle relative imports.
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
374
372
|
const resolve = fromImport ? resolveImport : resolveModule;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
373
|
+
// Try to resolve from root of workspace
|
|
374
|
+
let result = await tryResolve(resolve, root, url);
|
|
375
|
+
// Try to resolve from previously resolved modules.
|
|
376
|
+
if (!result && previousResolvedModules) {
|
|
377
|
+
for (const path of previousResolvedModules) {
|
|
378
|
+
result = await tryResolve(resolve, path, url);
|
|
379
|
+
if (result) {
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return result ? (0, node_url_1.pathToFileURL)(result) : null;
|
|
378
385
|
},
|
|
379
386
|
};
|
|
380
387
|
}
|
|
388
|
+
async function tryResolve(resolve, root, url) {
|
|
389
|
+
try {
|
|
390
|
+
return await resolve(root, url);
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Try to resolve a partial file
|
|
394
|
+
// @use '@material/button/button' as mdc-button;
|
|
395
|
+
// `@material/button/button` -> `@material/button/_button`
|
|
396
|
+
const lastSlashIndex = url.lastIndexOf('/');
|
|
397
|
+
const underscoreIndex = lastSlashIndex + 1;
|
|
398
|
+
if (underscoreIndex > 0 && url.charAt(underscoreIndex) !== '_') {
|
|
399
|
+
const partialFileUrl = `${url.slice(0, underscoreIndex)}_${url.slice(underscoreIndex)}`;
|
|
400
|
+
return resolve(root, partialFileUrl).catch(() => undefined);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return undefined;
|
|
404
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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 interface OccurrencesPluginOptions {
|
|
10
|
+
aot?: boolean;
|
|
11
|
+
scriptsOptimization?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class OccurrencesPlugin {
|
|
14
|
+
private options;
|
|
15
|
+
constructor(options: OccurrencesPluginOptions);
|
|
16
|
+
apply(compiler: Compiler): void;
|
|
17
|
+
private countOccurrences;
|
|
18
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
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.OccurrencesPlugin = void 0;
|
|
11
|
+
const PLUGIN_NAME = 'angular-occurrences-plugin';
|
|
12
|
+
class OccurrencesPlugin {
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
apply(compiler) {
|
|
17
|
+
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
18
|
+
compilation.hooks.processAssets.tapPromise({
|
|
19
|
+
name: PLUGIN_NAME,
|
|
20
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
|
|
21
|
+
}, async (compilationAssets) => {
|
|
22
|
+
for (const assetName of Object.keys(compilationAssets)) {
|
|
23
|
+
if (!assetName.endsWith('.js')) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const scriptAsset = compilation.getAsset(assetName);
|
|
27
|
+
if (!scriptAsset || scriptAsset.source.size() <= 0) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const src = scriptAsset.source.source().toString('utf-8');
|
|
31
|
+
let ngComponentCount = 0;
|
|
32
|
+
if (!this.options.aot) {
|
|
33
|
+
// Count the number of `Component({` strings (case sensitive), which happens in __decorate().
|
|
34
|
+
ngComponentCount += this.countOccurrences(src, 'Component({');
|
|
35
|
+
}
|
|
36
|
+
if (this.options.scriptsOptimization) {
|
|
37
|
+
// for ascii_only true
|
|
38
|
+
ngComponentCount += this.countOccurrences(src, '.\\u0275cmp', false);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// For Ivy we just count ɵcmp.src
|
|
42
|
+
ngComponentCount += this.countOccurrences(src, '.ɵcmp', true);
|
|
43
|
+
}
|
|
44
|
+
compilation.updateAsset(assetName, (s) => s, (assetInfo) => ({
|
|
45
|
+
...assetInfo,
|
|
46
|
+
ngComponentCount,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
countOccurrences(source, match, wordBreak = false) {
|
|
53
|
+
let count = 0;
|
|
54
|
+
// We condition here so branch prediction happens out of the loop, not in it.
|
|
55
|
+
if (wordBreak) {
|
|
56
|
+
const re = /\w/;
|
|
57
|
+
for (let pos = source.lastIndexOf(match); pos >= 0; pos = source.lastIndexOf(match, pos)) {
|
|
58
|
+
if (!(re.test(source[pos - 1] || '') || re.test(source[pos + match.length] || ''))) {
|
|
59
|
+
count++; // 1 match, AH! AH! AH! 2 matches, AH! AH! AH!
|
|
60
|
+
}
|
|
61
|
+
pos -= match.length;
|
|
62
|
+
if (pos < 0) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
for (let pos = source.lastIndexOf(match); pos >= 0; pos = source.lastIndexOf(match, pos)) {
|
|
69
|
+
count++; // 1 match, AH! AH! AH! 2 matches, AH! AH! AH!
|
|
70
|
+
pos -= match.length;
|
|
71
|
+
if (pos < 0) {
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return count;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.OccurrencesPlugin = OccurrencesPlugin;
|
|
@@ -22,17 +22,22 @@ export interface BundleStats {
|
|
|
22
22
|
initial: boolean;
|
|
23
23
|
stats: BundleStatsData;
|
|
24
24
|
}
|
|
25
|
-
export declare function generateBundleStats(info: {
|
|
26
|
-
rawSize?: number;
|
|
27
|
-
estimatedTransferSize?: number;
|
|
28
|
-
files?: string[];
|
|
29
|
-
names?: string[];
|
|
30
|
-
initial?: boolean;
|
|
31
|
-
rendered?: boolean;
|
|
32
|
-
}): BundleStats;
|
|
33
25
|
export declare function statsWarningsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
|
|
34
26
|
export declare function statsErrorsToString(json: StatsCompilation, statsConfig: WebpackStatsOptions): string;
|
|
35
27
|
export declare function statsHasErrors(json: StatsCompilation): boolean;
|
|
36
28
|
export declare function statsHasWarnings(json: StatsCompilation): boolean;
|
|
37
29
|
export declare function createWebpackLoggingCallback(options: BrowserBuilderOptions, logger: logging.LoggerApi): WebpackLoggingCallback;
|
|
30
|
+
export interface BuildEventStats {
|
|
31
|
+
aot: boolean;
|
|
32
|
+
optimization: boolean;
|
|
33
|
+
allChunksCount: number;
|
|
34
|
+
lazyChunksCount: number;
|
|
35
|
+
initialChunksCount: number;
|
|
36
|
+
changedChunksCount?: number;
|
|
37
|
+
durationInMs: number;
|
|
38
|
+
cssSizeInBytes: number;
|
|
39
|
+
jsSizeInBytes: number;
|
|
40
|
+
ngComponentCount: number;
|
|
41
|
+
}
|
|
42
|
+
export declare function generateBuildEventStats(webpackStats: StatsCompilation, browserBuilderOptions: BrowserBuilderOptions): BuildEventStats;
|
|
38
43
|
export declare function webpackStatsLogger(logger: logging.LoggerApi, json: StatsCompilation, config: Configuration, budgetFailures?: BudgetCalculatorResult[]): void;
|
|
@@ -33,10 +33,12 @@ 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.createWebpackLoggingCallback = exports.statsHasWarnings = exports.statsHasErrors = exports.statsErrorsToString = exports.statsWarningsToString = exports.
|
|
36
|
+
exports.webpackStatsLogger = exports.generateBuildEventStats = exports.createWebpackLoggingCallback = exports.statsHasWarnings = exports.statsHasErrors = exports.statsErrorsToString = exports.statsWarningsToString = exports.formatSize = void 0;
|
|
37
37
|
const core_1 = require("@angular-devkit/core");
|
|
38
|
+
const assert_1 = __importDefault(require("assert"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const text_table_1 = __importDefault(require("text-table"));
|
|
41
|
+
const utils_1 = require("../../utils");
|
|
40
42
|
const color_1 = require("../../utils/color");
|
|
41
43
|
const async_chunks_1 = require("./async-chunks");
|
|
42
44
|
const helpers_1 = require("./helpers");
|
|
@@ -52,6 +54,11 @@ function formatSize(size) {
|
|
|
52
54
|
return `${roundedSize.toFixed(fractionDigits)} ${abbreviations[index]}`;
|
|
53
55
|
}
|
|
54
56
|
exports.formatSize = formatSize;
|
|
57
|
+
function getBuildDuration(webpackStats) {
|
|
58
|
+
(0, assert_1.default)(webpackStats.builtAt, 'buildAt cannot be undefined');
|
|
59
|
+
(0, assert_1.default)(webpackStats.time, 'time cannot be undefined');
|
|
60
|
+
return Date.now() - webpackStats.builtAt + webpackStats.time;
|
|
61
|
+
}
|
|
55
62
|
function generateBundleStats(info) {
|
|
56
63
|
var _a, _b, _c;
|
|
57
64
|
const rawSize = typeof info.rawSize === 'number' ? info.rawSize : '-';
|
|
@@ -64,7 +71,6 @@ function generateBundleStats(info) {
|
|
|
64
71
|
stats: [files, names, rawSize, estimatedTransferSize],
|
|
65
72
|
};
|
|
66
73
|
}
|
|
67
|
-
exports.generateBundleStats = generateBundleStats;
|
|
68
74
|
function generateBuildStatsTable(data, colors, showTotalSize, showEstimatedTransferSize, budgetFailures) {
|
|
69
75
|
const g = (x) => (colors ? color_1.colors.greenBright(x) : x);
|
|
70
76
|
const c = (x) => (colors ? color_1.colors.cyanBright(x) : x);
|
|
@@ -238,10 +244,7 @@ statsConfig, budgetFailures) {
|
|
|
238
244
|
// In some cases we do things outside of webpack context
|
|
239
245
|
// Such us index generation, service worker augmentation etc...
|
|
240
246
|
// This will correct the time and include these.
|
|
241
|
-
|
|
242
|
-
if (json.builtAt !== undefined && json.time !== undefined) {
|
|
243
|
-
time = Date.now() - json.builtAt + json.time;
|
|
244
|
-
}
|
|
247
|
+
const time = getBuildDuration(json);
|
|
245
248
|
if (unchangedChunkNumber > 0) {
|
|
246
249
|
return ('\n' +
|
|
247
250
|
rs(core_1.tags.stripIndents `
|
|
@@ -370,6 +373,54 @@ function createWebpackLoggingCallback(options, logger) {
|
|
|
370
373
|
};
|
|
371
374
|
}
|
|
372
375
|
exports.createWebpackLoggingCallback = createWebpackLoggingCallback;
|
|
376
|
+
function generateBuildEventStats(webpackStats, browserBuilderOptions) {
|
|
377
|
+
var _a, _b;
|
|
378
|
+
const { chunks = [], assets = [] } = webpackStats;
|
|
379
|
+
let jsSizeInBytes = 0;
|
|
380
|
+
let cssSizeInBytes = 0;
|
|
381
|
+
let initialChunksCount = 0;
|
|
382
|
+
let ngComponentCount = 0;
|
|
383
|
+
let changedChunksCount = 0;
|
|
384
|
+
const allChunksCount = chunks.length;
|
|
385
|
+
const isFirstRun = !runsCache.has(webpackStats.outputPath || '');
|
|
386
|
+
const chunkFiles = new Set();
|
|
387
|
+
for (const chunk of chunks) {
|
|
388
|
+
if (!isFirstRun && chunk.rendered) {
|
|
389
|
+
changedChunksCount++;
|
|
390
|
+
}
|
|
391
|
+
if (chunk.initial) {
|
|
392
|
+
initialChunksCount++;
|
|
393
|
+
}
|
|
394
|
+
for (const file of (_a = chunk.files) !== null && _a !== void 0 ? _a : []) {
|
|
395
|
+
chunkFiles.add(file);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
for (const asset of assets) {
|
|
399
|
+
if (asset.name.endsWith('.map') || !chunkFiles.has(asset.name)) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
if (asset.name.endsWith('.js')) {
|
|
403
|
+
jsSizeInBytes += asset.size;
|
|
404
|
+
ngComponentCount += (_b = asset.info.ngComponentCount) !== null && _b !== void 0 ? _b : 0;
|
|
405
|
+
}
|
|
406
|
+
else if (asset.name.endsWith('.css')) {
|
|
407
|
+
cssSizeInBytes += asset.size;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
optimization: !!(0, utils_1.normalizeOptimization)(browserBuilderOptions.optimization).scripts,
|
|
412
|
+
aot: browserBuilderOptions.aot !== false,
|
|
413
|
+
allChunksCount,
|
|
414
|
+
lazyChunksCount: allChunksCount - initialChunksCount,
|
|
415
|
+
initialChunksCount,
|
|
416
|
+
changedChunksCount,
|
|
417
|
+
durationInMs: getBuildDuration(webpackStats),
|
|
418
|
+
cssSizeInBytes,
|
|
419
|
+
jsSizeInBytes,
|
|
420
|
+
ngComponentCount,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
exports.generateBuildEventStats = generateBuildEventStats;
|
|
373
424
|
function webpackStatsLogger(logger, json, config, budgetFailures) {
|
|
374
425
|
logger.info(statsToString(json, config.stats, budgetFailures));
|
|
375
426
|
if (typeof config.stats !== 'object') {
|
|
@@ -1,11 +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
|
-
import { BuilderContext } from '@angular-devkit/architect';
|
|
9
|
-
import { Configuration } from 'webpack';
|
|
10
|
-
import { WebpackConfigOptions } from '../../utils/build-options';
|
|
11
|
-
export declare function getAnalyticsConfig(wco: WebpackConfigOptions, context: BuilderContext): Configuration;
|
|
@@ -1,27 +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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.getAnalyticsConfig = void 0;
|
|
11
|
-
const analytics_1 = require("../plugins/analytics");
|
|
12
|
-
function getAnalyticsConfig(wco, context) {
|
|
13
|
-
if (!context.analytics) {
|
|
14
|
-
return {};
|
|
15
|
-
}
|
|
16
|
-
// If there's analytics, add our plugin. Otherwise no need to slow down the build.
|
|
17
|
-
let category = 'build';
|
|
18
|
-
if (context.builder) {
|
|
19
|
-
// We already vetted that this is a "safe" package, otherwise the analytics would be noop.
|
|
20
|
-
category = context.builder.builderName.split(':')[1] || context.builder.builderName || 'build';
|
|
21
|
-
}
|
|
22
|
-
// The category is the builder name if it's an angular builder.
|
|
23
|
-
return {
|
|
24
|
-
plugins: [new analytics_1.NgBuildAnalyticsPlugin(wco.projectRoot, context.analytics, category)],
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
exports.getAnalyticsConfig = getAnalyticsConfig;
|