@angular/build 18.0.0-next.3
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/LICENSE +21 -0
- package/README.md +5 -0
- package/builders.json +14 -0
- package/package.json +87 -0
- package/src/builders/application/build-action.d.ts +33 -0
- package/src/builders/application/build-action.js +183 -0
- package/src/builders/application/execute-build.d.ts +11 -0
- package/src/builders/application/execute-build.js +125 -0
- package/src/builders/application/execute-post-bundle.d.ts +25 -0
- package/src/builders/application/execute-post-bundle.js +93 -0
- package/src/builders/application/i18n.d.ts +29 -0
- package/src/builders/application/i18n.js +128 -0
- package/src/builders/application/index.d.ts +57 -0
- package/src/builders/application/index.js +121 -0
- package/src/builders/application/options.d.ts +149 -0
- package/src/builders/application/options.js +369 -0
- package/src/builders/application/schema.d.ts +512 -0
- package/src/builders/application/schema.js +58 -0
- package/src/builders/application/schema.json +635 -0
- package/src/builders/application/setup-bundling.d.ts +19 -0
- package/src/builders/application/setup-bundling.js +71 -0
- package/src/builders/dev-server/builder.d.ts +32 -0
- package/src/builders/dev-server/builder.js +70 -0
- package/src/builders/dev-server/index.d.ts +14 -0
- package/src/builders/dev-server/index.js +15 -0
- package/src/builders/dev-server/internal.d.ts +19 -0
- package/src/builders/dev-server/internal.js +29 -0
- package/src/builders/dev-server/options.d.ts +47 -0
- package/src/builders/dev-server/options.js +65 -0
- package/src/builders/dev-server/output.d.ts +16 -0
- package/src/builders/dev-server/output.js +9 -0
- package/src/builders/dev-server/schema.d.ts +118 -0
- package/src/builders/dev-server/schema.js +4 -0
- package/src/builders/dev-server/schema.json +131 -0
- package/src/builders/dev-server/vite-server.d.ts +31 -0
- package/src/builders/dev-server/vite-server.js +504 -0
- package/src/index.d.ts +11 -0
- package/src/index.js +16 -0
- package/src/private.d.ts +35 -0
- package/src/private.js +70 -0
- package/src/tools/babel/plugins/adjust-static-class-members.d.ts +26 -0
- package/src/tools/babel/plugins/adjust-static-class-members.js +351 -0
- package/src/tools/babel/plugins/adjust-typescript-enums.d.ts +22 -0
- package/src/tools/babel/plugins/adjust-typescript-enums.js +113 -0
- package/src/tools/babel/plugins/elide-angular-metadata.d.ts +22 -0
- package/src/tools/babel/plugins/elide-angular-metadata.js +110 -0
- package/src/tools/babel/plugins/index.d.ts +11 -0
- package/src/tools/babel/plugins/index.js +21 -0
- package/src/tools/babel/plugins/pure-toplevel-functions.d.ts +15 -0
- package/src/tools/babel/plugins/pure-toplevel-functions.js +90 -0
- package/src/tools/babel/typings.d.ts +21 -0
- package/src/tools/esbuild/angular/angular-host.d.ts +26 -0
- package/src/tools/esbuild/angular/angular-host.js +134 -0
- package/src/tools/esbuild/angular/compilation/angular-compilation.d.ts +42 -0
- package/src/tools/esbuild/angular/compilation/angular-compilation.js +94 -0
- package/src/tools/esbuild/angular/compilation/aot-compilation.d.ts +21 -0
- package/src/tools/esbuild/angular/compilation/aot-compilation.js +224 -0
- package/src/tools/esbuild/angular/compilation/factory.d.ts +16 -0
- package/src/tools/esbuild/angular/compilation/factory.js +56 -0
- package/src/tools/esbuild/angular/compilation/index.d.ts +10 -0
- package/src/tools/esbuild/angular/compilation/index.js +17 -0
- package/src/tools/esbuild/angular/compilation/jit-bootstrap-transformer.d.ts +10 -0
- package/src/tools/esbuild/angular/compilation/jit-bootstrap-transformer.js +182 -0
- package/src/tools/esbuild/angular/compilation/jit-compilation.d.ts +21 -0
- package/src/tools/esbuild/angular/compilation/jit-compilation.js +106 -0
- package/src/tools/esbuild/angular/compilation/noop-compilation.d.ts +20 -0
- package/src/tools/esbuild/angular/compilation/noop-compilation.js +26 -0
- package/src/tools/esbuild/angular/compilation/parallel-compilation.d.ts +42 -0
- package/src/tools/esbuild/angular/compilation/parallel-compilation.js +123 -0
- package/src/tools/esbuild/angular/compilation/parallel-worker.d.ts +33 -0
- package/src/tools/esbuild/angular/compilation/parallel-worker.js +90 -0
- package/src/tools/esbuild/angular/compilation-state.d.ts +15 -0
- package/src/tools/esbuild/angular/compilation-state.js +44 -0
- package/src/tools/esbuild/angular/compiler-plugin.d.ts +27 -0
- package/src/tools/esbuild/angular/compiler-plugin.js +441 -0
- package/src/tools/esbuild/angular/component-stylesheets.d.ts +44 -0
- package/src/tools/esbuild/angular/component-stylesheets.js +150 -0
- package/src/tools/esbuild/angular/diagnostics.d.ts +15 -0
- package/src/tools/esbuild/angular/diagnostics.js +69 -0
- package/src/tools/esbuild/angular/file-reference-tracker.d.ts +17 -0
- package/src/tools/esbuild/angular/file-reference-tracker.js +57 -0
- package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +23 -0
- package/src/tools/esbuild/angular/jit-plugin-callbacks.js +117 -0
- package/src/tools/esbuild/angular/jit-resource-transformer.d.ts +17 -0
- package/src/tools/esbuild/angular/jit-resource-transformer.js +186 -0
- package/src/tools/esbuild/angular/source-file-cache.d.ts +18 -0
- package/src/tools/esbuild/angular/source-file-cache.js +65 -0
- package/src/tools/esbuild/angular/uri.d.ts +54 -0
- package/src/tools/esbuild/angular/uri.js +74 -0
- package/src/tools/esbuild/angular/web-worker-transformer.d.ts +17 -0
- package/src/tools/esbuild/angular/web-worker-transformer.js +94 -0
- package/src/tools/esbuild/application-code-bundle.d.ts +20 -0
- package/src/tools/esbuild/application-code-bundle.js +368 -0
- package/src/tools/esbuild/budget-stats.d.ts +19 -0
- package/src/tools/esbuild/budget-stats.js +59 -0
- package/src/tools/esbuild/bundler-context.d.ts +75 -0
- package/src/tools/esbuild/bundler-context.js +366 -0
- package/src/tools/esbuild/bundler-execution-result.d.ts +71 -0
- package/src/tools/esbuild/bundler-execution-result.js +131 -0
- package/src/tools/esbuild/cache.d.ts +88 -0
- package/src/tools/esbuild/cache.js +92 -0
- package/src/tools/esbuild/commonjs-checker.d.ts +28 -0
- package/src/tools/esbuild/commonjs-checker.js +151 -0
- package/src/tools/esbuild/compiler-plugin-options.d.ts +16 -0
- package/src/tools/esbuild/compiler-plugin-options.js +49 -0
- package/src/tools/esbuild/external-packages-plugin.d.ts +18 -0
- package/src/tools/esbuild/external-packages-plugin.js +70 -0
- package/src/tools/esbuild/global-scripts.d.ts +16 -0
- package/src/tools/esbuild/global-scripts.js +142 -0
- package/src/tools/esbuild/global-styles.d.ts +10 -0
- package/src/tools/esbuild/global-styles.js +74 -0
- package/src/tools/esbuild/i18n-inliner-worker.d.ts +42 -0
- package/src/tools/esbuild/i18n-inliner-worker.js +136 -0
- package/src/tools/esbuild/i18n-inliner.d.ts +44 -0
- package/src/tools/esbuild/i18n-inliner.js +150 -0
- package/src/tools/esbuild/i18n-locale-plugin.d.ts +22 -0
- package/src/tools/esbuild/i18n-locale-plugin.js +120 -0
- package/src/tools/esbuild/index-html-generator.d.ts +15 -0
- package/src/tools/esbuild/index-html-generator.js +81 -0
- package/src/tools/esbuild/javascript-transformer-worker.d.ts +19 -0
- package/src/tools/esbuild/javascript-transformer-worker.js +154 -0
- package/src/tools/esbuild/javascript-transformer.d.ts +54 -0
- package/src/tools/esbuild/javascript-transformer.js +147 -0
- package/src/tools/esbuild/license-extractor.d.ts +25 -0
- package/src/tools/esbuild/license-extractor.js +158 -0
- package/src/tools/esbuild/load-result-cache.d.ts +21 -0
- package/src/tools/esbuild/load-result-cache.js +75 -0
- package/src/tools/esbuild/profiling.d.ts +11 -0
- package/src/tools/esbuild/profiling.js +78 -0
- package/src/tools/esbuild/rxjs-esm-resolution-plugin.d.ts +18 -0
- package/src/tools/esbuild/rxjs-esm-resolution-plugin.js +44 -0
- package/src/tools/esbuild/sourcemap-ignorelist-plugin.d.ts +17 -0
- package/src/tools/esbuild/sourcemap-ignorelist-plugin.js +73 -0
- package/src/tools/esbuild/stylesheets/bundle-options.d.ts +35 -0
- package/src/tools/esbuild/stylesheets/bundle-options.js +64 -0
- package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.d.ts +25 -0
- package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.js +57 -0
- package/src/tools/esbuild/stylesheets/css-language.d.ts +9 -0
- package/src/tools/esbuild/stylesheets/css-language.js +15 -0
- package/src/tools/esbuild/stylesheets/css-resource-plugin.d.ts +18 -0
- package/src/tools/esbuild/stylesheets/css-resource-plugin.js +114 -0
- package/src/tools/esbuild/stylesheets/less-language.d.ts +9 -0
- package/src/tools/esbuild/stylesheets/less-language.js +155 -0
- package/src/tools/esbuild/stylesheets/sass-language.d.ts +10 -0
- package/src/tools/esbuild/stylesheets/sass-language.js +185 -0
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +58 -0
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js +282 -0
- package/src/tools/esbuild/utils.d.ts +49 -0
- package/src/tools/esbuild/utils.js +392 -0
- package/src/tools/esbuild/virtual-module-plugin.d.ts +33 -0
- package/src/tools/esbuild/virtual-module-plugin.js +43 -0
- package/src/tools/esbuild/watcher.d.ts +25 -0
- package/src/tools/esbuild/watcher.js +118 -0
- package/src/tools/sass/lexer.d.ts +18 -0
- package/src/tools/sass/lexer.js +161 -0
- package/src/tools/sass/rebasing-importer.d.ts +101 -0
- package/src/tools/sass/rebasing-importer.js +334 -0
- package/src/tools/sass/sass-service.d.ts +72 -0
- package/src/tools/sass/sass-service.js +213 -0
- package/src/tools/sass/worker.d.ts +8 -0
- package/src/tools/sass/worker.js +192 -0
- package/src/tools/vite/angular-memory-plugin.d.ts +24 -0
- package/src/tools/vite/angular-memory-plugin.js +268 -0
- package/src/tools/vite/i18n-locale-plugin.d.ts +18 -0
- package/src/tools/vite/i18n-locale-plugin.js +55 -0
- package/src/utils/bundle-calculator.d.ts +44 -0
- package/src/utils/bundle-calculator.js +303 -0
- package/src/utils/check-port.d.ts +8 -0
- package/src/utils/check-port.js +58 -0
- package/src/utils/color.d.ts +10 -0
- package/src/utils/color.js +63 -0
- package/src/utils/delete-output-dir.d.ts +11 -0
- package/src/utils/delete-output-dir.js +46 -0
- package/src/utils/environment-options.d.ts +16 -0
- package/src/utils/environment-options.js +79 -0
- package/src/utils/error.d.ts +10 -0
- package/src/utils/error.js +21 -0
- package/src/utils/format-bytes.d.ts +8 -0
- package/src/utils/format-bytes.js +22 -0
- package/src/utils/i18n-options.d.ts +33 -0
- package/src/utils/i18n-options.js +161 -0
- package/src/utils/index-file/add-event-dispatch-contract.d.ts +8 -0
- package/src/utils/index-file/add-event-dispatch-contract.js +28 -0
- package/src/utils/index-file/augment-index-html.d.ts +40 -0
- package/src/utils/index-file/augment-index-html.js +239 -0
- package/src/utils/index-file/html-rewriting-stream.d.ts +11 -0
- package/src/utils/index-file/html-rewriting-stream.js +28 -0
- package/src/utils/index-file/index-html-generator.d.ts +57 -0
- package/src/utils/index-file/index-html-generator.js +135 -0
- package/src/utils/index-file/inline-critical-css.d.ts +24 -0
- package/src/utils/index-file/inline-critical-css.js +179 -0
- package/src/utils/index-file/inline-fonts.d.ts +23 -0
- package/src/utils/index-file/inline-fonts.js +267 -0
- package/src/utils/index-file/nonce.d.ts +12 -0
- package/src/utils/index-file/nonce.js +55 -0
- package/src/utils/index-file/style-nonce.d.ts +12 -0
- package/src/utils/index-file/style-nonce.js +55 -0
- package/src/utils/index.d.ts +11 -0
- package/src/utils/index.js +27 -0
- package/src/utils/load-esm.d.ts +20 -0
- package/src/utils/load-esm.js +31 -0
- package/src/utils/load-proxy-config.d.ts +8 -0
- package/src/utils/load-proxy-config.js +189 -0
- package/src/utils/load-translations.d.ts +16 -0
- package/src/utils/load-translations.js +84 -0
- package/src/utils/normalize-asset-patterns.d.ts +14 -0
- package/src/utils/normalize-asset-patterns.js +96 -0
- package/src/utils/normalize-cache.d.ts +16 -0
- package/src/utils/normalize-cache.js +44 -0
- package/src/utils/normalize-optimization.d.ts +13 -0
- package/src/utils/normalize-optimization.js +42 -0
- package/src/utils/normalize-source-maps.d.ts +9 -0
- package/src/utils/normalize-source-maps.js +23 -0
- package/src/utils/postcss-configuration.d.ts +17 -0
- package/src/utils/postcss-configuration.js +86 -0
- package/src/utils/purge-cache.d.ts +10 -0
- package/src/utils/purge-cache.js +40 -0
- package/src/utils/resolve-assets.d.ts +18 -0
- package/src/utils/resolve-assets.js +35 -0
- package/src/utils/routes-extractor/extractor.d.ts +15 -0
- package/src/utils/routes-extractor/extractor.js +97 -0
- package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.d.ts +18 -0
- package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.js +129 -0
- package/src/utils/server-rendering/esm-in-memory-loader/register-hooks.d.ts +8 -0
- package/src/utils/server-rendering/esm-in-memory-loader/register-hooks.js +13 -0
- package/src/utils/server-rendering/fetch-patch.d.ts +8 -0
- package/src/utils/server-rendering/fetch-patch.js +66 -0
- package/src/utils/server-rendering/load-esm-from-memory.d.ts +10 -0
- package/src/utils/server-rendering/load-esm-from-memory.js +26 -0
- package/src/utils/server-rendering/main-bundle-exports.d.ts +27 -0
- package/src/utils/server-rendering/main-bundle-exports.js +9 -0
- package/src/utils/server-rendering/prerender.d.ts +23 -0
- package/src/utils/server-rendering/prerender.js +192 -0
- package/src/utils/server-rendering/render-page.d.ts +26 -0
- package/src/utils/server-rendering/render-page.js +110 -0
- package/src/utils/server-rendering/render-worker.d.ts +22 -0
- package/src/utils/server-rendering/render-worker.js +30 -0
- package/src/utils/server-rendering/routes-extractor-worker.d.ts +21 -0
- package/src/utils/server-rendering/routes-extractor-worker.js +53 -0
- package/src/utils/service-worker.d.ts +25 -0
- package/src/utils/service-worker.js +211 -0
- package/src/utils/spinner.d.ts +20 -0
- package/src/utils/spinner.js +55 -0
- package/src/utils/stats-table.d.ts +20 -0
- package/src/utils/stats-table.js +205 -0
- package/src/utils/supported-browsers.d.ts +10 -0
- package/src/utils/supported-browsers.js +42 -0
- package/src/utils/tty.d.ts +8 -0
- package/src/utils/tty.js +23 -0
- package/src/utils/url.d.ts +8 -0
- package/src/utils/url.js +18 -0
- package/src/utils/version.d.ts +8 -0
- package/src/utils/version.js +59 -0
|
@@ -0,0 +1,268 @@
|
|
|
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.createAngularMemoryPlugin = void 0;
|
|
14
|
+
const remapping_1 = __importDefault(require("@ampproject/remapping"));
|
|
15
|
+
const mrmime_1 = require("mrmime");
|
|
16
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
17
|
+
const promises_1 = require("node:fs/promises");
|
|
18
|
+
const node_path_1 = require("node:path");
|
|
19
|
+
const render_page_1 = require("../../utils/server-rendering/render-page");
|
|
20
|
+
// eslint-disable-next-line max-lines-per-function
|
|
21
|
+
function createAngularMemoryPlugin(options) {
|
|
22
|
+
const { workspaceRoot, virtualProjectRoot, outputFiles, assets, external, ssr, extensionMiddleware, extraHeaders, indexHtmlTransformer, normalizePath, } = options;
|
|
23
|
+
return {
|
|
24
|
+
name: 'vite:angular-memory',
|
|
25
|
+
// Ensures plugin hooks run before built-in Vite hooks
|
|
26
|
+
enforce: 'pre',
|
|
27
|
+
async resolveId(source, importer) {
|
|
28
|
+
// Prevent vite from resolving an explicit external dependency (`externalDependencies` option)
|
|
29
|
+
if (external?.includes(source)) {
|
|
30
|
+
// This is still not ideal since Vite will still transform the import specifier to
|
|
31
|
+
// `/@id/${source}` but is currently closer to a raw external than a resolved file path.
|
|
32
|
+
return source;
|
|
33
|
+
}
|
|
34
|
+
if (importer && source[0] === '.' && importer.startsWith(virtualProjectRoot)) {
|
|
35
|
+
// Remove query if present
|
|
36
|
+
const [importerFile] = importer.split('?', 1);
|
|
37
|
+
source =
|
|
38
|
+
'/' + normalizePath((0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.relative)(virtualProjectRoot, importerFile)), source));
|
|
39
|
+
}
|
|
40
|
+
const [file] = source.split('?', 1);
|
|
41
|
+
if (outputFiles.has(file)) {
|
|
42
|
+
return (0, node_path_1.join)(virtualProjectRoot, source);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
async load(id) {
|
|
46
|
+
const [file] = id.split('?', 1);
|
|
47
|
+
const relativeFile = '/' + normalizePath((0, node_path_1.relative)(virtualProjectRoot, file));
|
|
48
|
+
const codeContents = outputFiles.get(relativeFile)?.contents;
|
|
49
|
+
if (codeContents === undefined) {
|
|
50
|
+
if (relativeFile.endsWith('/node_modules/vite/dist/client/client.mjs')) {
|
|
51
|
+
return {
|
|
52
|
+
code: await loadViteClientCode(file),
|
|
53
|
+
map: await (0, promises_1.readFile)(file + '.map', 'utf-8'),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const code = Buffer.from(codeContents).toString('utf-8');
|
|
59
|
+
const mapContents = outputFiles.get(relativeFile + '.map')?.contents;
|
|
60
|
+
return {
|
|
61
|
+
// Remove source map URL comments from the code if a sourcemap is present.
|
|
62
|
+
// Vite will inline and add an additional sourcemap URL for the sourcemap.
|
|
63
|
+
code: mapContents ? code.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, '') : code,
|
|
64
|
+
map: mapContents && Buffer.from(mapContents).toString('utf-8'),
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
// eslint-disable-next-line max-lines-per-function
|
|
68
|
+
configureServer(server) {
|
|
69
|
+
const originalssrTransform = server.ssrTransform;
|
|
70
|
+
server.ssrTransform = async (code, map, url, originalCode) => {
|
|
71
|
+
const result = await originalssrTransform(code, null, url, originalCode);
|
|
72
|
+
if (!result || !result.map || !map) {
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
const remappedMap = (0, remapping_1.default)([result.map, map], () => null);
|
|
76
|
+
// Set the sourcemap root to the workspace root. This is needed since we set a virtual path as root.
|
|
77
|
+
remappedMap.sourceRoot = normalizePath(workspaceRoot) + '/';
|
|
78
|
+
return {
|
|
79
|
+
...result,
|
|
80
|
+
map: remappedMap,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
// Assets and resources get handled first
|
|
84
|
+
server.middlewares.use(function angularAssetsMiddleware(req, res, next) {
|
|
85
|
+
if (req.url === undefined || res.writableEnded) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Parse the incoming request.
|
|
89
|
+
// The base of the URL is unused but required to parse the URL.
|
|
90
|
+
const pathname = pathnameWithoutBasePath(req.url, server.config.base);
|
|
91
|
+
const extension = (0, node_path_1.extname)(pathname);
|
|
92
|
+
// Rewrite all build assets to a vite raw fs URL
|
|
93
|
+
const assetSourcePath = assets.get(pathname);
|
|
94
|
+
if (assetSourcePath !== undefined) {
|
|
95
|
+
// Workaround to disable Vite transformer middleware.
|
|
96
|
+
// See: https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/middlewares/transform.ts#L201 and
|
|
97
|
+
// https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/transformRequest.ts#L204-L206
|
|
98
|
+
req.headers.accept = 'text/html';
|
|
99
|
+
// The encoding needs to match what happens in the vite static middleware.
|
|
100
|
+
// ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
|
|
101
|
+
req.url = `${server.config.base}@fs/${encodeURI(assetSourcePath)}`;
|
|
102
|
+
next();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// HTML fallbacking
|
|
106
|
+
// This matches what happens in the vite html fallback middleware.
|
|
107
|
+
// ref: https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L9
|
|
108
|
+
const htmlAssetSourcePath = pathname[pathname.length - 1] === '/'
|
|
109
|
+
? // Trailing slash check for `index.html`.
|
|
110
|
+
assets.get(pathname + 'index.html')
|
|
111
|
+
: // Non-trailing slash check for fallback `.html`
|
|
112
|
+
assets.get(pathname + '.html');
|
|
113
|
+
if (htmlAssetSourcePath) {
|
|
114
|
+
req.url = `${server.config.base}@fs/${encodeURI(htmlAssetSourcePath)}`;
|
|
115
|
+
next();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Resource files are handled directly.
|
|
119
|
+
// Global stylesheets (CSS files) are currently considered resources to workaround
|
|
120
|
+
// dev server sourcemap issues with stylesheets.
|
|
121
|
+
if (extension !== '.js' && extension !== '.html') {
|
|
122
|
+
const outputFile = outputFiles.get(pathname);
|
|
123
|
+
if (outputFile?.servable) {
|
|
124
|
+
const mimeType = (0, mrmime_1.lookup)(extension);
|
|
125
|
+
if (mimeType) {
|
|
126
|
+
res.setHeader('Content-Type', mimeType);
|
|
127
|
+
}
|
|
128
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
129
|
+
if (extraHeaders) {
|
|
130
|
+
Object.entries(extraHeaders).forEach(([name, value]) => res.setHeader(name, value));
|
|
131
|
+
}
|
|
132
|
+
res.end(outputFile.contents);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
next();
|
|
137
|
+
});
|
|
138
|
+
if (extensionMiddleware?.length) {
|
|
139
|
+
extensionMiddleware.forEach((middleware) => server.middlewares.use(middleware));
|
|
140
|
+
}
|
|
141
|
+
// Returning a function, installs middleware after the main transform middleware but
|
|
142
|
+
// before the built-in HTML middleware
|
|
143
|
+
return () => {
|
|
144
|
+
server.middlewares.use(angularHtmlFallbackMiddleware);
|
|
145
|
+
function angularSSRMiddleware(req, res, next) {
|
|
146
|
+
const url = req.originalUrl;
|
|
147
|
+
if (!req.url ||
|
|
148
|
+
// Skip if path is not defined.
|
|
149
|
+
!url ||
|
|
150
|
+
// Skip if path is like a file.
|
|
151
|
+
// NOTE: We use a mime type lookup to mitigate against matching requests like: /browse/pl.0ef59752c0cd457dbf1391f08cbd936f
|
|
152
|
+
lookupMimeTypeFromRequest(url)) {
|
|
153
|
+
next();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const rawHtml = outputFiles.get('/index.server.html')?.contents;
|
|
157
|
+
if (!rawHtml) {
|
|
158
|
+
next();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
transformIndexHtmlAndAddHeaders(req.url, rawHtml, res, next, async (html) => {
|
|
162
|
+
const resolvedUrls = server.resolvedUrls;
|
|
163
|
+
const baseUrl = resolvedUrls?.local[0] ?? resolvedUrls?.network[0];
|
|
164
|
+
const { content } = await (0, render_page_1.renderPage)({
|
|
165
|
+
document: html,
|
|
166
|
+
route: new URL(req.originalUrl ?? '/', baseUrl).toString(),
|
|
167
|
+
serverContext: 'ssr',
|
|
168
|
+
loadBundle: (uri) =>
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
170
|
+
server.ssrLoadModule(uri.slice(1)),
|
|
171
|
+
// Files here are only needed for critical CSS inlining.
|
|
172
|
+
outputFiles: {},
|
|
173
|
+
// TODO: add support for critical css inlining.
|
|
174
|
+
inlineCriticalCss: false,
|
|
175
|
+
});
|
|
176
|
+
return indexHtmlTransformer && content ? await indexHtmlTransformer(content) : content;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (ssr) {
|
|
180
|
+
server.middlewares.use(angularSSRMiddleware);
|
|
181
|
+
}
|
|
182
|
+
server.middlewares.use(function angularIndexMiddleware(req, res, next) {
|
|
183
|
+
if (!req.url) {
|
|
184
|
+
next();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Parse the incoming request.
|
|
188
|
+
// The base of the URL is unused but required to parse the URL.
|
|
189
|
+
const pathname = pathnameWithoutBasePath(req.url, server.config.base);
|
|
190
|
+
if (pathname === '/' || pathname === `/index.html`) {
|
|
191
|
+
const rawHtml = outputFiles.get('/index.html')?.contents;
|
|
192
|
+
if (rawHtml) {
|
|
193
|
+
transformIndexHtmlAndAddHeaders(req.url, rawHtml, res, next, indexHtmlTransformer);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
next();
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
function transformIndexHtmlAndAddHeaders(url, rawHtml, res, next, additionalTransformer) {
|
|
201
|
+
server
|
|
202
|
+
.transformIndexHtml(url, Buffer.from(rawHtml).toString('utf-8'))
|
|
203
|
+
.then(async (processedHtml) => {
|
|
204
|
+
if (additionalTransformer) {
|
|
205
|
+
const content = await additionalTransformer(processedHtml);
|
|
206
|
+
if (!content) {
|
|
207
|
+
next();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
processedHtml = content;
|
|
211
|
+
}
|
|
212
|
+
res.setHeader('Content-Type', 'text/html');
|
|
213
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
214
|
+
if (extraHeaders) {
|
|
215
|
+
Object.entries(extraHeaders).forEach(([name, value]) => res.setHeader(name, value));
|
|
216
|
+
}
|
|
217
|
+
res.end(processedHtml);
|
|
218
|
+
})
|
|
219
|
+
.catch((error) => next(error));
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
exports.createAngularMemoryPlugin = createAngularMemoryPlugin;
|
|
225
|
+
/**
|
|
226
|
+
* Reads the resolved Vite client code from disk and updates the content to remove
|
|
227
|
+
* an unactionable suggestion to update the Vite configuration file to disable the
|
|
228
|
+
* error overlay. The Vite configuration file is not present when used in the Angular
|
|
229
|
+
* CLI.
|
|
230
|
+
* @param file The absolute path to the Vite client code.
|
|
231
|
+
* @returns
|
|
232
|
+
*/
|
|
233
|
+
async function loadViteClientCode(file) {
|
|
234
|
+
const originalContents = await (0, promises_1.readFile)(file, 'utf-8');
|
|
235
|
+
const updatedContents = originalContents.replace(`h('br'), 'You can also disable this overlay by setting ', ` +
|
|
236
|
+
`h('code', { part: 'config-option-name' }, 'server.hmr.overlay'), '` +
|
|
237
|
+
` to ', h('code', { part: 'config-option-value' }, 'false'), ' in ', h('code', { part: 'config-file-name' }, hmrConfigName), '.'`, '');
|
|
238
|
+
(0, node_assert_1.default)(originalContents !== updatedContents, 'Failed to update Vite client error overlay text.');
|
|
239
|
+
return updatedContents;
|
|
240
|
+
}
|
|
241
|
+
function pathnameWithoutBasePath(url, basePath) {
|
|
242
|
+
const parsedUrl = new URL(url, 'http://localhost');
|
|
243
|
+
const pathname = decodeURIComponent(parsedUrl.pathname);
|
|
244
|
+
// slice(basePath.length - 1) to retain the trailing slash
|
|
245
|
+
return basePath !== '/' && pathname.startsWith(basePath)
|
|
246
|
+
? pathname.slice(basePath.length - 1)
|
|
247
|
+
: pathname;
|
|
248
|
+
}
|
|
249
|
+
function angularHtmlFallbackMiddleware(req, res, next) {
|
|
250
|
+
// Similar to how it is handled in vite
|
|
251
|
+
// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L15C19-L15C45
|
|
252
|
+
if ((req.method === 'GET' || req.method === 'HEAD') &&
|
|
253
|
+
(!req.url || !lookupMimeTypeFromRequest(req.url)) &&
|
|
254
|
+
(!req.headers.accept ||
|
|
255
|
+
req.headers.accept.includes('text/html') ||
|
|
256
|
+
req.headers.accept.includes('text/*') ||
|
|
257
|
+
req.headers.accept.includes('*/*'))) {
|
|
258
|
+
req.url = '/index.html';
|
|
259
|
+
}
|
|
260
|
+
next();
|
|
261
|
+
}
|
|
262
|
+
function lookupMimeTypeFromRequest(url) {
|
|
263
|
+
const extension = (0, node_path_1.extname)(url.split('?')[0]);
|
|
264
|
+
if (extension === '.ico') {
|
|
265
|
+
return 'image/x-icon';
|
|
266
|
+
}
|
|
267
|
+
return extension && (0, mrmime_1.lookup)(extension);
|
|
268
|
+
}
|
|
@@ -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 type { Plugin } from 'vite';
|
|
9
|
+
/**
|
|
10
|
+
* The base module location used to search for locale specific data.
|
|
11
|
+
*/
|
|
12
|
+
export declare const LOCALE_DATA_BASE_MODULE = "@angular/common/locales/global";
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Vite plugin that resolves Angular locale data files from `@angular/common`.
|
|
15
|
+
*
|
|
16
|
+
* @returns A Vite plugin.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createAngularLocaleDataPlugin(): Plugin;
|
|
@@ -0,0 +1,55 @@
|
|
|
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.createAngularLocaleDataPlugin = exports.LOCALE_DATA_BASE_MODULE = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* The base module location used to search for locale specific data.
|
|
13
|
+
*/
|
|
14
|
+
exports.LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global';
|
|
15
|
+
/**
|
|
16
|
+
* Creates a Vite plugin that resolves Angular locale data files from `@angular/common`.
|
|
17
|
+
*
|
|
18
|
+
* @returns A Vite plugin.
|
|
19
|
+
*/
|
|
20
|
+
function createAngularLocaleDataPlugin() {
|
|
21
|
+
return {
|
|
22
|
+
name: 'angular-locale-data',
|
|
23
|
+
enforce: 'pre',
|
|
24
|
+
async resolveId(source) {
|
|
25
|
+
if (!source.startsWith('angular:locale/data:')) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Extract the locale from the path
|
|
29
|
+
const originalLocale = source.split(':', 3)[2];
|
|
30
|
+
// Remove any private subtags since these will never match
|
|
31
|
+
let partialLocale = originalLocale.replace(/-x(-[a-zA-Z0-9]{1,8})+$/, '');
|
|
32
|
+
let exact = true;
|
|
33
|
+
while (partialLocale) {
|
|
34
|
+
const potentialPath = `${exports.LOCALE_DATA_BASE_MODULE}/${partialLocale}`;
|
|
35
|
+
const result = await this.resolve(potentialPath);
|
|
36
|
+
if (result) {
|
|
37
|
+
if (!exact) {
|
|
38
|
+
this.warn(`Locale data for '${originalLocale}' cannot be found. Using locale data for '${partialLocale}'.`);
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
// Remove the last subtag and try again with a less specific locale
|
|
43
|
+
const parts = partialLocale.split('-');
|
|
44
|
+
partialLocale = parts.slice(0, -1).join('-');
|
|
45
|
+
exact = false;
|
|
46
|
+
// The locales "en" and "en-US" are considered exact to retain existing behavior
|
|
47
|
+
if (originalLocale === 'en-US' && partialLocale === 'en') {
|
|
48
|
+
exact = true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
exports.createAngularLocaleDataPlugin = createAngularLocaleDataPlugin;
|
|
@@ -0,0 +1,44 @@
|
|
|
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 { Budget as BudgetEntry, Type as BudgetType } from '../builders/application/schema';
|
|
9
|
+
export { BudgetEntry, BudgetType };
|
|
10
|
+
export interface Threshold {
|
|
11
|
+
limit: number;
|
|
12
|
+
type: ThresholdType;
|
|
13
|
+
severity: ThresholdSeverity;
|
|
14
|
+
}
|
|
15
|
+
declare enum ThresholdType {
|
|
16
|
+
Max = "maximum",
|
|
17
|
+
Min = "minimum"
|
|
18
|
+
}
|
|
19
|
+
export declare enum ThresholdSeverity {
|
|
20
|
+
Warning = "warning",
|
|
21
|
+
Error = "error"
|
|
22
|
+
}
|
|
23
|
+
export interface BudgetCalculatorResult {
|
|
24
|
+
severity: ThresholdSeverity;
|
|
25
|
+
message: string;
|
|
26
|
+
label?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface BudgetChunk {
|
|
29
|
+
files?: string[];
|
|
30
|
+
names?: string[];
|
|
31
|
+
initial?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface BudgetAsset {
|
|
34
|
+
name: string;
|
|
35
|
+
size: number;
|
|
36
|
+
componentStyle?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface BudgetStats {
|
|
39
|
+
chunks?: BudgetChunk[];
|
|
40
|
+
assets?: BudgetAsset[];
|
|
41
|
+
}
|
|
42
|
+
export declare function calculateThresholds(budget: BudgetEntry): IterableIterator<Threshold>;
|
|
43
|
+
export declare function checkBudgets(budgets: BudgetEntry[], stats: BudgetStats, checkComponentStyles?: boolean): IterableIterator<BudgetCalculatorResult>;
|
|
44
|
+
export declare function checkThresholds(thresholds: Iterable<Threshold>, size: number, label?: string): IterableIterator<BudgetCalculatorResult>;
|
|
@@ -0,0 +1,303 @@
|
|
|
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.checkThresholds = exports.checkBudgets = exports.calculateThresholds = exports.ThresholdSeverity = exports.BudgetType = void 0;
|
|
11
|
+
const schema_1 = require("../builders/application/schema");
|
|
12
|
+
Object.defineProperty(exports, "BudgetType", { enumerable: true, get: function () { return schema_1.Type; } });
|
|
13
|
+
const format_bytes_1 = require("./format-bytes");
|
|
14
|
+
var ThresholdType;
|
|
15
|
+
(function (ThresholdType) {
|
|
16
|
+
ThresholdType["Max"] = "maximum";
|
|
17
|
+
ThresholdType["Min"] = "minimum";
|
|
18
|
+
})(ThresholdType || (ThresholdType = {}));
|
|
19
|
+
var ThresholdSeverity;
|
|
20
|
+
(function (ThresholdSeverity) {
|
|
21
|
+
ThresholdSeverity["Warning"] = "warning";
|
|
22
|
+
ThresholdSeverity["Error"] = "error";
|
|
23
|
+
})(ThresholdSeverity || (exports.ThresholdSeverity = ThresholdSeverity = {}));
|
|
24
|
+
function* calculateThresholds(budget) {
|
|
25
|
+
if (budget.maximumWarning) {
|
|
26
|
+
yield {
|
|
27
|
+
limit: calculateBytes(budget.maximumWarning, budget.baseline, 1),
|
|
28
|
+
type: ThresholdType.Max,
|
|
29
|
+
severity: ThresholdSeverity.Warning,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (budget.maximumError) {
|
|
33
|
+
yield {
|
|
34
|
+
limit: calculateBytes(budget.maximumError, budget.baseline, 1),
|
|
35
|
+
type: ThresholdType.Max,
|
|
36
|
+
severity: ThresholdSeverity.Error,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (budget.minimumWarning) {
|
|
40
|
+
yield {
|
|
41
|
+
limit: calculateBytes(budget.minimumWarning, budget.baseline, -1),
|
|
42
|
+
type: ThresholdType.Min,
|
|
43
|
+
severity: ThresholdSeverity.Warning,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (budget.minimumError) {
|
|
47
|
+
yield {
|
|
48
|
+
limit: calculateBytes(budget.minimumError, budget.baseline, -1),
|
|
49
|
+
type: ThresholdType.Min,
|
|
50
|
+
severity: ThresholdSeverity.Error,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (budget.warning) {
|
|
54
|
+
yield {
|
|
55
|
+
limit: calculateBytes(budget.warning, budget.baseline, -1),
|
|
56
|
+
type: ThresholdType.Min,
|
|
57
|
+
severity: ThresholdSeverity.Warning,
|
|
58
|
+
};
|
|
59
|
+
yield {
|
|
60
|
+
limit: calculateBytes(budget.warning, budget.baseline, 1),
|
|
61
|
+
type: ThresholdType.Max,
|
|
62
|
+
severity: ThresholdSeverity.Warning,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (budget.error) {
|
|
66
|
+
yield {
|
|
67
|
+
limit: calculateBytes(budget.error, budget.baseline, -1),
|
|
68
|
+
type: ThresholdType.Min,
|
|
69
|
+
severity: ThresholdSeverity.Error,
|
|
70
|
+
};
|
|
71
|
+
yield {
|
|
72
|
+
limit: calculateBytes(budget.error, budget.baseline, 1),
|
|
73
|
+
type: ThresholdType.Max,
|
|
74
|
+
severity: ThresholdSeverity.Error,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.calculateThresholds = calculateThresholds;
|
|
79
|
+
/**
|
|
80
|
+
* Calculates the sizes for bundles in the budget type provided.
|
|
81
|
+
*/
|
|
82
|
+
function calculateSizes(budget, stats) {
|
|
83
|
+
const calculatorMap = {
|
|
84
|
+
all: AllCalculator,
|
|
85
|
+
allScript: AllScriptCalculator,
|
|
86
|
+
any: AnyCalculator,
|
|
87
|
+
anyScript: AnyScriptCalculator,
|
|
88
|
+
anyComponentStyle: AnyComponentStyleCalculator,
|
|
89
|
+
bundle: BundleCalculator,
|
|
90
|
+
initial: InitialCalculator,
|
|
91
|
+
};
|
|
92
|
+
const ctor = calculatorMap[budget.type];
|
|
93
|
+
const { chunks, assets } = stats;
|
|
94
|
+
if (!chunks) {
|
|
95
|
+
throw new Error('Webpack stats output did not include chunk information.');
|
|
96
|
+
}
|
|
97
|
+
if (!assets) {
|
|
98
|
+
throw new Error('Webpack stats output did not include asset information.');
|
|
99
|
+
}
|
|
100
|
+
const calculator = new ctor(budget, chunks, assets);
|
|
101
|
+
return calculator.calculate();
|
|
102
|
+
}
|
|
103
|
+
class Calculator {
|
|
104
|
+
budget;
|
|
105
|
+
chunks;
|
|
106
|
+
assets;
|
|
107
|
+
constructor(budget, chunks, assets) {
|
|
108
|
+
this.budget = budget;
|
|
109
|
+
this.chunks = chunks;
|
|
110
|
+
this.assets = assets;
|
|
111
|
+
}
|
|
112
|
+
/** Calculates the size of the given chunk for the provided build type. */
|
|
113
|
+
calculateChunkSize(chunk) {
|
|
114
|
+
// No differential builds, get the chunk size by summing its assets.
|
|
115
|
+
if (!chunk.files) {
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
return chunk.files
|
|
119
|
+
.filter((file) => !file.endsWith('.map'))
|
|
120
|
+
.map((file) => {
|
|
121
|
+
const asset = this.assets.find((asset) => asset.name === file);
|
|
122
|
+
if (!asset) {
|
|
123
|
+
throw new Error(`Could not find asset for file: ${file}`);
|
|
124
|
+
}
|
|
125
|
+
return asset.size;
|
|
126
|
+
})
|
|
127
|
+
.reduce((l, r) => l + r, 0);
|
|
128
|
+
}
|
|
129
|
+
getAssetSize(asset) {
|
|
130
|
+
return asset.size;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A named bundle.
|
|
135
|
+
*/
|
|
136
|
+
class BundleCalculator extends Calculator {
|
|
137
|
+
calculate() {
|
|
138
|
+
const budgetName = this.budget.name;
|
|
139
|
+
if (!budgetName) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
const size = this.chunks
|
|
143
|
+
.filter((chunk) => chunk?.names?.includes(budgetName))
|
|
144
|
+
.map((chunk) => this.calculateChunkSize(chunk))
|
|
145
|
+
.reduce((l, r) => l + r, 0);
|
|
146
|
+
return [{ size, label: this.budget.name }];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The sum of all initial chunks (marked as initial).
|
|
151
|
+
*/
|
|
152
|
+
class InitialCalculator extends Calculator {
|
|
153
|
+
calculate() {
|
|
154
|
+
return [
|
|
155
|
+
{
|
|
156
|
+
label: `bundle initial`,
|
|
157
|
+
size: this.chunks
|
|
158
|
+
.filter((chunk) => chunk.initial)
|
|
159
|
+
.map((chunk) => this.calculateChunkSize(chunk))
|
|
160
|
+
.reduce((l, r) => l + r, 0),
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The sum of all the scripts portions.
|
|
167
|
+
*/
|
|
168
|
+
class AllScriptCalculator extends Calculator {
|
|
169
|
+
calculate() {
|
|
170
|
+
const size = this.assets
|
|
171
|
+
.filter((asset) => asset.name.endsWith('.js'))
|
|
172
|
+
.map((asset) => this.getAssetSize(asset))
|
|
173
|
+
.reduce((total, size) => total + size, 0);
|
|
174
|
+
return [{ size, label: 'total scripts' }];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* All scripts and assets added together.
|
|
179
|
+
*/
|
|
180
|
+
class AllCalculator extends Calculator {
|
|
181
|
+
calculate() {
|
|
182
|
+
const size = this.assets
|
|
183
|
+
.filter((asset) => !asset.name.endsWith('.map'))
|
|
184
|
+
.map((asset) => this.getAssetSize(asset))
|
|
185
|
+
.reduce((total, size) => total + size, 0);
|
|
186
|
+
return [{ size, label: 'total' }];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Any script, individually.
|
|
191
|
+
*/
|
|
192
|
+
class AnyScriptCalculator extends Calculator {
|
|
193
|
+
calculate() {
|
|
194
|
+
return this.assets
|
|
195
|
+
.filter((asset) => asset.name.endsWith('.js'))
|
|
196
|
+
.map((asset) => ({
|
|
197
|
+
size: this.getAssetSize(asset),
|
|
198
|
+
label: asset.name,
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Any script or asset (images, css, etc).
|
|
204
|
+
*/
|
|
205
|
+
class AnyCalculator extends Calculator {
|
|
206
|
+
calculate() {
|
|
207
|
+
return this.assets
|
|
208
|
+
.filter((asset) => !asset.name.endsWith('.map'))
|
|
209
|
+
.map((asset) => ({
|
|
210
|
+
size: this.getAssetSize(asset),
|
|
211
|
+
label: asset.name,
|
|
212
|
+
}));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Any compoonent stylesheet
|
|
217
|
+
*/
|
|
218
|
+
class AnyComponentStyleCalculator extends Calculator {
|
|
219
|
+
calculate() {
|
|
220
|
+
return this.assets
|
|
221
|
+
.filter((asset) => asset.componentStyle)
|
|
222
|
+
.map((asset) => ({
|
|
223
|
+
size: this.getAssetSize(asset),
|
|
224
|
+
label: asset.name,
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Calculate the bytes given a string value.
|
|
230
|
+
*/
|
|
231
|
+
function calculateBytes(input, baseline, factor = 1) {
|
|
232
|
+
const matches = input.trim().match(/^(\d+(?:\.\d+)?)[ \t]*(%|[kmg]?b)?$/i);
|
|
233
|
+
if (!matches) {
|
|
234
|
+
return NaN;
|
|
235
|
+
}
|
|
236
|
+
const baselineBytes = (baseline && calculateBytes(baseline)) || 0;
|
|
237
|
+
let value = Number(matches[1]);
|
|
238
|
+
switch (matches[2] && matches[2].toLowerCase()) {
|
|
239
|
+
case '%':
|
|
240
|
+
value = (baselineBytes * value) / 100;
|
|
241
|
+
break;
|
|
242
|
+
case 'kb':
|
|
243
|
+
value *= 1024;
|
|
244
|
+
break;
|
|
245
|
+
case 'mb':
|
|
246
|
+
value *= 1024 * 1024;
|
|
247
|
+
break;
|
|
248
|
+
case 'gb':
|
|
249
|
+
value *= 1024 * 1024 * 1024;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
if (baselineBytes === 0) {
|
|
253
|
+
return value;
|
|
254
|
+
}
|
|
255
|
+
return baselineBytes + value * factor;
|
|
256
|
+
}
|
|
257
|
+
function* checkBudgets(budgets, stats, checkComponentStyles) {
|
|
258
|
+
// Ignore AnyComponentStyle budgets as these are handled in `AnyComponentStyleBudgetChecker` unless requested
|
|
259
|
+
const computableBudgets = checkComponentStyles
|
|
260
|
+
? budgets
|
|
261
|
+
: budgets.filter((budget) => budget.type !== schema_1.Type.AnyComponentStyle);
|
|
262
|
+
for (const budget of computableBudgets) {
|
|
263
|
+
const sizes = calculateSizes(budget, stats);
|
|
264
|
+
for (const { size, label } of sizes) {
|
|
265
|
+
yield* checkThresholds(calculateThresholds(budget), size, label);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
exports.checkBudgets = checkBudgets;
|
|
270
|
+
function* checkThresholds(thresholds, size, label) {
|
|
271
|
+
for (const threshold of thresholds) {
|
|
272
|
+
switch (threshold.type) {
|
|
273
|
+
case ThresholdType.Max: {
|
|
274
|
+
if (size <= threshold.limit) {
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
const sizeDifference = (0, format_bytes_1.formatSize)(size - threshold.limit);
|
|
278
|
+
yield {
|
|
279
|
+
severity: threshold.severity,
|
|
280
|
+
label,
|
|
281
|
+
message: `${label} exceeded maximum budget. Budget ${(0, format_bytes_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, format_bytes_1.formatSize)(size)}.`,
|
|
282
|
+
};
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
case ThresholdType.Min: {
|
|
286
|
+
if (size >= threshold.limit) {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
const sizeDifference = (0, format_bytes_1.formatSize)(threshold.limit - size);
|
|
290
|
+
yield {
|
|
291
|
+
severity: threshold.severity,
|
|
292
|
+
label,
|
|
293
|
+
message: `${label} failed to meet minimum budget. Budget ${(0, format_bytes_1.formatSize)(threshold.limit)} was not met by ${sizeDifference} with a total of ${(0, format_bytes_1.formatSize)(size)}.`,
|
|
294
|
+
};
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
default: {
|
|
298
|
+
throw new Error(`Unexpected threshold type: ${ThresholdType[threshold.type]}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
exports.checkThresholds = checkThresholds;
|