@angular-devkit/build-angular 15.0.0-next.3 → 15.0.0-next.5
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 +19 -18
- 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 +10 -2
- package/src/builders/browser-esbuild/compiler-plugin.js +211 -115
- package/src/builders/browser-esbuild/esbuild.d.ts +4 -3
- package/src/builders/browser-esbuild/esbuild.js +12 -6
- package/src/builders/browser-esbuild/experimental-warnings.js +0 -3
- package/src/builders/browser-esbuild/index.d.ts +3 -3
- package/src/builders/browser-esbuild/index.js +145 -87
- package/src/builders/browser-esbuild/options.d.ts +26 -4
- package/src/builders/browser-esbuild/options.js +56 -5
- 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/browser-esbuild/watcher.d.ts +23 -0
- package/src/builders/browser-esbuild/watcher.js +93 -0
- 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 +50 -9
- package/src/builders/karma/schema.d.ts +1 -1
- package/src/builders/karma/schema.json +1 -1
- package/src/builders/server/schema.json +1 -1
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +3 -1
- package/src/utils/process-bundle.js +1 -1
- package/src/utils/service-worker.d.ts +3 -0
- package/src/utils/service-worker.js +29 -2
- package/src/webpack/configs/common.js +31 -7
- package/src/webpack/configs/index.d.ts +0 -1
- package/src/webpack/configs/index.js +0 -1
- package/src/webpack/configs/styles.d.ts +1 -7
- package/src/webpack/configs/styles.js +70 -60
- package/src/webpack/plugins/occurrences-plugin.d.ts +18 -0
- package/src/webpack/plugins/occurrences-plugin.js +79 -0
- package/src/webpack/plugins/scripts-webpack-plugin.js +24 -5
- package/src/webpack/plugins/styles-webpack-plugin.d.ts +19 -0
- package/src/webpack/plugins/styles-webpack-plugin.js +71 -0
- package/src/webpack/utils/helpers.d.ts +5 -1
- package/src/webpack/utils/helpers.js +24 -14
- 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
|
@@ -33,54 +33,18 @@ 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.getStylesConfig =
|
|
36
|
+
exports.getStylesConfig = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
|
+
const url_1 = require("url");
|
|
40
41
|
const sass_service_1 = require("../../sass/sass-service");
|
|
41
42
|
const sass_service_legacy_1 = require("../../sass/sass-service-legacy");
|
|
42
43
|
const environment_options_1 = require("../../utils/environment-options");
|
|
43
44
|
const plugins_1 = require("../plugins");
|
|
44
45
|
const css_optimizer_plugin_1 = require("../plugins/css-optimizer-plugin");
|
|
46
|
+
const styles_webpack_plugin_1 = require("../plugins/styles-webpack-plugin");
|
|
45
47
|
const helpers_1 = require("../utils/helpers");
|
|
46
|
-
function resolveGlobalStyles(styleEntrypoints, root, preserveSymlinks, skipResolution = false) {
|
|
47
|
-
const entryPoints = {};
|
|
48
|
-
const noInjectNames = [];
|
|
49
|
-
const paths = [];
|
|
50
|
-
if (styleEntrypoints.length === 0) {
|
|
51
|
-
return { entryPoints, noInjectNames, paths };
|
|
52
|
-
}
|
|
53
|
-
for (const style of (0, helpers_1.normalizeExtraEntryPoints)(styleEntrypoints, 'styles')) {
|
|
54
|
-
let stylesheetPath = style.input;
|
|
55
|
-
if (!skipResolution) {
|
|
56
|
-
stylesheetPath = path.resolve(root, stylesheetPath);
|
|
57
|
-
if (!fs.existsSync(stylesheetPath)) {
|
|
58
|
-
try {
|
|
59
|
-
stylesheetPath = require.resolve(style.input, { paths: [root] });
|
|
60
|
-
}
|
|
61
|
-
catch { }
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (!preserveSymlinks) {
|
|
65
|
-
stylesheetPath = fs.realpathSync(stylesheetPath);
|
|
66
|
-
}
|
|
67
|
-
// Add style entry points.
|
|
68
|
-
if (entryPoints[style.bundleName]) {
|
|
69
|
-
entryPoints[style.bundleName].push(stylesheetPath);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
entryPoints[style.bundleName] = [stylesheetPath];
|
|
73
|
-
}
|
|
74
|
-
// Add non injected styles to the list.
|
|
75
|
-
if (!style.inject) {
|
|
76
|
-
noInjectNames.push(style.bundleName);
|
|
77
|
-
}
|
|
78
|
-
// Add global css paths.
|
|
79
|
-
paths.push(stylesheetPath);
|
|
80
|
-
}
|
|
81
|
-
return { entryPoints, noInjectNames, paths };
|
|
82
|
-
}
|
|
83
|
-
exports.resolveGlobalStyles = resolveGlobalStyles;
|
|
84
48
|
// eslint-disable-next-line max-lines-per-function
|
|
85
49
|
function getStylesConfig(wco) {
|
|
86
50
|
var _a, _b, _c;
|
|
@@ -93,10 +57,17 @@ function getStylesConfig(wco) {
|
|
|
93
57
|
// use includePaths from appConfig
|
|
94
58
|
const includePaths = (_c = (_b = (_a = buildOptions.stylePreprocessorOptions) === null || _a === void 0 ? void 0 : _a.includePaths) === null || _b === void 0 ? void 0 : _b.map((p) => path.resolve(root, p))) !== null && _c !== void 0 ? _c : [];
|
|
95
59
|
// Process global styles.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
60
|
+
if (buildOptions.styles.length > 0) {
|
|
61
|
+
const { entryPoints, noInjectNames } = (0, helpers_1.normalizeGlobalStyles)(buildOptions.styles);
|
|
62
|
+
extraPlugins.push(new styles_webpack_plugin_1.StylesWebpackPlugin({
|
|
63
|
+
root,
|
|
64
|
+
entryPoints,
|
|
65
|
+
preserveSymlinks: buildOptions.preserveSymlinks,
|
|
66
|
+
}));
|
|
67
|
+
if (noInjectNames.length > 0) {
|
|
68
|
+
// Add plugin to remove hashes from lazy styles.
|
|
69
|
+
extraPlugins.push(new plugins_1.RemoveHashPlugin({ chunkNames: noInjectNames, hashFormat }));
|
|
70
|
+
}
|
|
100
71
|
}
|
|
101
72
|
const sassImplementation = environment_options_1.useLegacySass
|
|
102
73
|
? new sass_service_legacy_1.SassLegacyWorkerImplementation()
|
|
@@ -238,7 +209,7 @@ function getStylesConfig(wco) {
|
|
|
238
209
|
},
|
|
239
210
|
{
|
|
240
211
|
loader: require.resolve('sass-loader'),
|
|
241
|
-
options: getSassLoaderOptions(root,
|
|
212
|
+
options: getSassLoaderOptions(root, sassImplementation, includePaths, false, !buildOptions.verbose, !!buildOptions.preserveSymlinks),
|
|
242
213
|
},
|
|
243
214
|
],
|
|
244
215
|
},
|
|
@@ -253,7 +224,7 @@ function getStylesConfig(wco) {
|
|
|
253
224
|
},
|
|
254
225
|
{
|
|
255
226
|
loader: require.resolve('sass-loader'),
|
|
256
|
-
options: getSassLoaderOptions(root,
|
|
227
|
+
options: getSassLoaderOptions(root, sassImplementation, includePaths, true, !buildOptions.verbose, !!buildOptions.preserveSymlinks),
|
|
257
228
|
},
|
|
258
229
|
],
|
|
259
230
|
},
|
|
@@ -275,7 +246,6 @@ function getStylesConfig(wco) {
|
|
|
275
246
|
},
|
|
276
247
|
];
|
|
277
248
|
return {
|
|
278
|
-
entry: entryPoints,
|
|
279
249
|
module: {
|
|
280
250
|
rules: styleLanguages.map(({ extensions, use }) => ({
|
|
281
251
|
test: new RegExp(`\\.(?:${extensions.join('|')})$`, 'i'),
|
|
@@ -286,8 +256,7 @@ function getStylesConfig(wco) {
|
|
|
286
256
|
// Global styles are only defined global styles
|
|
287
257
|
{
|
|
288
258
|
use: globalStyleLoaders,
|
|
289
|
-
|
|
290
|
-
resourceQuery: { not: [/\?ngResource/] },
|
|
259
|
+
resourceQuery: /\?ngGlobalStyle/,
|
|
291
260
|
},
|
|
292
261
|
// Component styles are all styles except defined global styles
|
|
293
262
|
{
|
|
@@ -330,24 +299,18 @@ function getTailwindConfigPath({ projectRoot, root }) {
|
|
|
330
299
|
}
|
|
331
300
|
return undefined;
|
|
332
301
|
}
|
|
333
|
-
function getSassLoaderOptions(root,
|
|
302
|
+
function getSassLoaderOptions(root, implementation, includePaths, indentedSyntax, verbose, preserveSymlinks) {
|
|
334
303
|
return implementation instanceof sass_service_1.SassWorkerImplementation
|
|
335
304
|
? {
|
|
336
305
|
sourceMap: true,
|
|
337
306
|
api: 'modern',
|
|
338
307
|
implementation,
|
|
339
|
-
// Webpack importer is only implemented in the legacy API.
|
|
308
|
+
// Webpack importer is only implemented in the legacy API and we have our own custom Webpack importer.
|
|
340
309
|
// See: https://github.com/webpack-contrib/sass-loader/blob/997f3eb41d86dd00d5fa49c395a1aeb41573108c/src/utils.js#L642-L651
|
|
341
310
|
webpackImporter: false,
|
|
342
|
-
sassOptions: {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
// Needed to resolve node packages and retain the same behaviour of with the legacy API as sass-loader resolves
|
|
346
|
-
// scss also from the cwd and project root.
|
|
347
|
-
// See: https://github.com/webpack-contrib/sass-loader/blob/997f3eb41d86dd00d5fa49c395a1aeb41573108c/src/utils.js#L307
|
|
348
|
-
projectRoot,
|
|
349
|
-
path.join(root, 'node_modules'),
|
|
350
|
-
],
|
|
311
|
+
sassOptions: (loaderContext) => ({
|
|
312
|
+
importers: [getSassResolutionImporter(loaderContext, root, preserveSymlinks)],
|
|
313
|
+
loadPaths: includePaths,
|
|
351
314
|
// Use expanded as otherwise sass will remove comments that are needed for autoprefixer
|
|
352
315
|
// Ex: /* autoprefixer grid: autoplace */
|
|
353
316
|
// See: https://github.com/webpack-contrib/sass-loader/blob/45ad0be17264ceada5f0b4fb87e9357abe85c4ff/src/getSassOptions.js#L68-L70
|
|
@@ -356,7 +319,7 @@ function getSassLoaderOptions(root, projectRoot, implementation, includePaths, i
|
|
|
356
319
|
quietDeps: !verbose,
|
|
357
320
|
verbose,
|
|
358
321
|
syntax: indentedSyntax ? 'indented' : 'scss',
|
|
359
|
-
},
|
|
322
|
+
}),
|
|
360
323
|
}
|
|
361
324
|
: {
|
|
362
325
|
sourceMap: true,
|
|
@@ -385,3 +348,50 @@ function getSassLoaderOptions(root, projectRoot, implementation, includePaths, i
|
|
|
385
348
|
},
|
|
386
349
|
};
|
|
387
350
|
}
|
|
351
|
+
function getSassResolutionImporter(loaderContext, root, preserveSymlinks) {
|
|
352
|
+
const commonResolverOptions = {
|
|
353
|
+
conditionNames: ['sass', 'style'],
|
|
354
|
+
mainFields: ['sass', 'style', 'main', '...'],
|
|
355
|
+
extensions: ['.scss', '.sass', '.css'],
|
|
356
|
+
restrictions: [/\.((sa|sc|c)ss)$/i],
|
|
357
|
+
preferRelative: true,
|
|
358
|
+
symlinks: !preserveSymlinks,
|
|
359
|
+
};
|
|
360
|
+
// Sass also supports import-only files. If you name a file <name>.import.scss, it will only be loaded for imports, not for @uses.
|
|
361
|
+
// See: https://sass-lang.com/documentation/at-rules/import#import-only-files
|
|
362
|
+
const resolveImport = loaderContext.getResolve({
|
|
363
|
+
...commonResolverOptions,
|
|
364
|
+
dependencyType: 'sass-import',
|
|
365
|
+
mainFiles: ['_index.import', '_index', 'index.import', 'index', '...'],
|
|
366
|
+
});
|
|
367
|
+
const resolveModule = loaderContext.getResolve({
|
|
368
|
+
...commonResolverOptions,
|
|
369
|
+
dependencyType: 'sass-module',
|
|
370
|
+
mainFiles: ['_index', 'index', '...'],
|
|
371
|
+
});
|
|
372
|
+
return {
|
|
373
|
+
findFileUrl: async (url, { fromImport }) => {
|
|
374
|
+
if (url.charAt(0) === '.') {
|
|
375
|
+
// Let Sass handle relative imports.
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
let file;
|
|
379
|
+
const resolve = fromImport ? resolveImport : resolveModule;
|
|
380
|
+
try {
|
|
381
|
+
file = await resolve(root, url);
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
// Try to resolve a partial file
|
|
385
|
+
// @use '@material/button/button' as mdc-button;
|
|
386
|
+
// `@material/button/button` -> `@material/button/_button`
|
|
387
|
+
const lastSlashIndex = url.lastIndexOf('/');
|
|
388
|
+
const underscoreIndex = lastSlashIndex + 1;
|
|
389
|
+
if (underscoreIndex > 0 && url.charAt(underscoreIndex) !== '_') {
|
|
390
|
+
const partialFileUrl = `${url.slice(0, underscoreIndex)}_${url.slice(underscoreIndex)}`;
|
|
391
|
+
file = await resolve(root, partialFileUrl).catch(() => undefined);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return file ? (0, url_1.pathToFileURL)(file) : null;
|
|
395
|
+
},
|
|
396
|
+
};
|
|
397
|
+
}
|
|
@@ -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;
|
|
@@ -34,6 +34,8 @@ exports.ScriptsWebpackPlugin = void 0;
|
|
|
34
34
|
const loader_utils_1 = require("loader-utils");
|
|
35
35
|
const path = __importStar(require("path"));
|
|
36
36
|
const webpack_1 = require("webpack");
|
|
37
|
+
const error_1 = require("../../utils/error");
|
|
38
|
+
const webpack_diagnostics_1 = require("../../utils/webpack-diagnostics");
|
|
37
39
|
const Entrypoint = require('webpack/lib/Entrypoint');
|
|
38
40
|
/**
|
|
39
41
|
* The name of the plugin provided to Webpack when tapping Webpack compiler hooks.
|
|
@@ -81,18 +83,35 @@ class ScriptsWebpackPlugin {
|
|
|
81
83
|
chunk.addGroup(entrypoint);
|
|
82
84
|
compilation.entrypoints.set(this.options.name, entrypoint);
|
|
83
85
|
compilation.chunks.add(chunk);
|
|
84
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
86
|
compilation.assets[filename] = source;
|
|
86
87
|
compilation.hooks.chunkAsset.call(chunk, filename);
|
|
87
88
|
}
|
|
88
89
|
apply(compiler) {
|
|
89
|
-
if (
|
|
90
|
+
if (this.options.scripts.length === 0) {
|
|
90
91
|
return;
|
|
91
92
|
}
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
const resolver = compiler.resolverFactory.get('normal', {
|
|
94
|
+
preferRelative: true,
|
|
95
|
+
useSyncFileSystemCalls: true,
|
|
96
|
+
fileSystem: compiler.inputFileSystem,
|
|
97
|
+
});
|
|
95
98
|
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
99
|
+
const scripts = [];
|
|
100
|
+
for (const script of this.options.scripts) {
|
|
101
|
+
try {
|
|
102
|
+
const resolvedPath = resolver.resolveSync({}, this.options.basePath, script);
|
|
103
|
+
if (resolvedPath) {
|
|
104
|
+
scripts.push(resolvedPath);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
(0, webpack_diagnostics_1.addError)(compilation, `Cannot resolve '${script}'.`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
(0, error_1.assertIsError)(error);
|
|
112
|
+
(0, webpack_diagnostics_1.addError)(compilation, error.message);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
96
115
|
compilation.hooks.additionalAssets.tapPromise(PLUGIN_NAME, async () => {
|
|
97
116
|
if (await this.shouldSkip(compilation, scripts)) {
|
|
98
117
|
if (this._cachedOutput) {
|
|
@@ -0,0 +1,19 @@
|
|
|
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 type { Compiler } from 'webpack';
|
|
9
|
+
export interface StylesWebpackPluginOptions {
|
|
10
|
+
preserveSymlinks?: boolean;
|
|
11
|
+
root: string;
|
|
12
|
+
entryPoints: Record<string, string[]>;
|
|
13
|
+
}
|
|
14
|
+
export declare class StylesWebpackPlugin {
|
|
15
|
+
private readonly options;
|
|
16
|
+
private compilation;
|
|
17
|
+
constructor(options: StylesWebpackPluginOptions);
|
|
18
|
+
apply(compiler: Compiler): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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.StylesWebpackPlugin = void 0;
|
|
14
|
+
const assert_1 = __importDefault(require("assert"));
|
|
15
|
+
const error_1 = require("../../utils/error");
|
|
16
|
+
const webpack_diagnostics_1 = require("../../utils/webpack-diagnostics");
|
|
17
|
+
/**
|
|
18
|
+
* The name of the plugin provided to Webpack when tapping Webpack compiler hooks.
|
|
19
|
+
*/
|
|
20
|
+
const PLUGIN_NAME = 'styles-webpack-plugin';
|
|
21
|
+
class StylesWebpackPlugin {
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.options = options;
|
|
24
|
+
}
|
|
25
|
+
apply(compiler) {
|
|
26
|
+
const { entryPoints, preserveSymlinks, root } = this.options;
|
|
27
|
+
const webpackOptions = compiler.options;
|
|
28
|
+
const entry = typeof webpackOptions.entry === 'function' ? webpackOptions.entry() : webpackOptions.entry;
|
|
29
|
+
const resolver = compiler.resolverFactory.get('global-styles', {
|
|
30
|
+
conditionNames: ['sass', 'less', 'style'],
|
|
31
|
+
mainFields: ['sass', 'less', 'style', 'main', '...'],
|
|
32
|
+
extensions: ['.scss', '.sass', '.less', '.css'],
|
|
33
|
+
restrictions: [/\.((le|sa|sc|c)ss)$/i],
|
|
34
|
+
preferRelative: true,
|
|
35
|
+
useSyncFileSystemCalls: true,
|
|
36
|
+
symlinks: !preserveSymlinks,
|
|
37
|
+
fileSystem: compiler.inputFileSystem,
|
|
38
|
+
});
|
|
39
|
+
webpackOptions.entry = async () => {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
var _c;
|
|
42
|
+
const entrypoints = await entry;
|
|
43
|
+
for (const [bundleName, paths] of Object.entries(entryPoints)) {
|
|
44
|
+
(_a = entrypoints[bundleName]) !== null && _a !== void 0 ? _a : (entrypoints[bundleName] = {});
|
|
45
|
+
const entryImport = ((_b = (_c = entrypoints[bundleName]).import) !== null && _b !== void 0 ? _b : (_c.import = []));
|
|
46
|
+
for (const path of paths) {
|
|
47
|
+
try {
|
|
48
|
+
const resolvedPath = resolver.resolveSync({}, root, path);
|
|
49
|
+
if (resolvedPath) {
|
|
50
|
+
entryImport.push(`${resolvedPath}?ngGlobalStyle`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
(0, assert_1.default)(this.compilation, 'Compilation cannot be undefined.');
|
|
54
|
+
(0, webpack_diagnostics_1.addError)(this.compilation, `Cannot resolve '${path}'.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
(0, assert_1.default)(this.compilation, 'Compilation cannot be undefined.');
|
|
59
|
+
(0, error_1.assertIsError)(error);
|
|
60
|
+
(0, webpack_diagnostics_1.addError)(this.compilation, error.message);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return entrypoints;
|
|
65
|
+
};
|
|
66
|
+
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
67
|
+
this.compilation = compilation;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.StylesWebpackPlugin = StylesWebpackPlugin;
|
|
@@ -21,8 +21,12 @@ export declare type NormalizedEntryPoint = Required<Exclude<ScriptElement | Styl
|
|
|
21
21
|
export declare function normalizeExtraEntryPoints(extraEntryPoints: (ScriptElement | StyleElement)[], defaultBundleName: string): NormalizedEntryPoint[];
|
|
22
22
|
export declare function assetNameTemplateFactory(hashFormat: HashFormat): (resourcePath: string) => string;
|
|
23
23
|
export declare function getInstrumentationExcludedPaths(root: string, excludedPaths: string[]): Set<string>;
|
|
24
|
+
export declare function normalizeGlobalStyles(styleEntrypoints: StyleElement[]): {
|
|
25
|
+
entryPoints: Record<string, string[]>;
|
|
26
|
+
noInjectNames: string[];
|
|
27
|
+
};
|
|
24
28
|
export declare function getCacheSettings(wco: WebpackConfigOptions, angularVersion: string): WebpackOptionsNormalized['cache'];
|
|
25
|
-
export declare function globalScriptsByBundleName(
|
|
29
|
+
export declare function globalScriptsByBundleName(scripts: ScriptElement[]): {
|
|
26
30
|
bundleName: string;
|
|
27
31
|
inject: boolean;
|
|
28
32
|
paths: string[];
|
|
@@ -33,9 +33,8 @@ 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.getStatsOptions = exports.assetPatterns = exports.globalScriptsByBundleName = exports.getCacheSettings = exports.getInstrumentationExcludedPaths = exports.assetNameTemplateFactory = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
|
|
36
|
+
exports.getStatsOptions = exports.assetPatterns = exports.globalScriptsByBundleName = exports.getCacheSettings = exports.normalizeGlobalStyles = exports.getInstrumentationExcludedPaths = exports.assetNameTemplateFactory = exports.normalizeExtraEntryPoints = exports.getOutputHashFormat = void 0;
|
|
37
37
|
const crypto_1 = require("crypto");
|
|
38
|
-
const fs_1 = require("fs");
|
|
39
38
|
const glob_1 = __importDefault(require("glob"));
|
|
40
39
|
const path = __importStar(require("path"));
|
|
41
40
|
const schema_1 = require("../../builders/browser/schema");
|
|
@@ -130,6 +129,26 @@ function getInstrumentationExcludedPaths(root, excludedPaths) {
|
|
|
130
129
|
return excluded;
|
|
131
130
|
}
|
|
132
131
|
exports.getInstrumentationExcludedPaths = getInstrumentationExcludedPaths;
|
|
132
|
+
function normalizeGlobalStyles(styleEntrypoints) {
|
|
133
|
+
var _a;
|
|
134
|
+
var _b;
|
|
135
|
+
const entryPoints = {};
|
|
136
|
+
const noInjectNames = [];
|
|
137
|
+
if (styleEntrypoints.length === 0) {
|
|
138
|
+
return { entryPoints, noInjectNames };
|
|
139
|
+
}
|
|
140
|
+
for (const style of normalizeExtraEntryPoints(styleEntrypoints, 'styles')) {
|
|
141
|
+
// Add style entry points.
|
|
142
|
+
(_a = entryPoints[_b = style.bundleName]) !== null && _a !== void 0 ? _a : (entryPoints[_b] = []);
|
|
143
|
+
entryPoints[style.bundleName].push(style.input);
|
|
144
|
+
// Add non injected styles to the list.
|
|
145
|
+
if (!style.inject) {
|
|
146
|
+
noInjectNames.push(style.bundleName);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { entryPoints, noInjectNames };
|
|
150
|
+
}
|
|
151
|
+
exports.normalizeGlobalStyles = normalizeGlobalStyles;
|
|
133
152
|
function getCacheSettings(wco, angularVersion) {
|
|
134
153
|
const { enabled, path: cacheDirectory } = wco.buildOptions.cache;
|
|
135
154
|
if (enabled) {
|
|
@@ -164,31 +183,22 @@ function getCacheSettings(wco, angularVersion) {
|
|
|
164
183
|
return false;
|
|
165
184
|
}
|
|
166
185
|
exports.getCacheSettings = getCacheSettings;
|
|
167
|
-
function globalScriptsByBundleName(
|
|
186
|
+
function globalScriptsByBundleName(scripts) {
|
|
168
187
|
return normalizeExtraEntryPoints(scripts, 'scripts').reduce((prev, curr) => {
|
|
169
188
|
const { bundleName, inject, input } = curr;
|
|
170
|
-
let resolvedPath = path.resolve(root, input);
|
|
171
|
-
if (!(0, fs_1.existsSync)(resolvedPath)) {
|
|
172
|
-
try {
|
|
173
|
-
resolvedPath = require.resolve(input, { paths: [root] });
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
throw new Error(`Script file ${input} does not exist.`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
189
|
const existingEntry = prev.find((el) => el.bundleName === bundleName);
|
|
180
190
|
if (existingEntry) {
|
|
181
191
|
if (existingEntry.inject && !inject) {
|
|
182
192
|
// All entries have to be lazy for the bundle to be lazy.
|
|
183
193
|
throw new Error(`The ${bundleName} bundle is mixing injected and non-injected scripts.`);
|
|
184
194
|
}
|
|
185
|
-
existingEntry.paths.push(
|
|
195
|
+
existingEntry.paths.push(input);
|
|
186
196
|
}
|
|
187
197
|
else {
|
|
188
198
|
prev.push({
|
|
189
199
|
bundleName,
|
|
190
200
|
inject,
|
|
191
|
-
paths: [
|
|
201
|
+
paths: [input],
|
|
192
202
|
});
|
|
193
203
|
}
|
|
194
204
|
return prev;
|
|
@@ -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') {
|