@angular/build 19.0.0-next.8 → 19.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -5
- package/package.json +22 -19
- package/src/builders/application/build-action.js +9 -9
- package/src/builders/application/chunk-optimizer.js +1 -4
- package/src/builders/application/execute-build.js +34 -6
- package/src/builders/application/execute-post-bundle.js +9 -1
- package/src/builders/application/index.d.ts +0 -16
- package/src/builders/application/index.js +15 -10
- package/src/builders/application/options.d.ts +11 -1
- package/src/builders/application/options.js +17 -10
- package/src/builders/application/results.d.ts +5 -3
- package/src/builders/application/schema.d.ts +86 -0
- package/src/builders/application/schema.js +19 -1
- package/src/builders/application/schema.json +73 -4
- package/src/builders/application/setup-bundling.d.ts +3 -1
- package/src/builders/application/setup-bundling.js +33 -6
- package/src/builders/dev-server/vite-server.d.ts +2 -2
- package/src/builders/dev-server/vite-server.js +46 -16
- package/src/index.d.ts +1 -0
- package/src/tools/angular/angular-host.d.ts +1 -1
- package/src/tools/angular/angular-host.js +1 -4
- package/src/tools/angular/compilation/angular-compilation.d.ts +1 -0
- package/src/tools/angular/compilation/aot-compilation.d.ts +1 -0
- package/src/tools/angular/compilation/aot-compilation.js +39 -0
- package/src/tools/angular/compilation/parallel-compilation.js +2 -2
- package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
- package/src/tools/angular/compilation/parallel-worker.js +5 -2
- package/src/tools/babel/plugins/add-code-coverage.d.ts +14 -0
- package/src/tools/babel/plugins/add-code-coverage.js +44 -0
- package/src/tools/babel/plugins/types.d.ts +20 -0
- package/src/tools/esbuild/angular/compiler-plugin.d.ts +3 -4
- package/src/tools/esbuild/angular/compiler-plugin.js +55 -34
- package/src/tools/esbuild/angular/component-stylesheets.d.ts +17 -18
- package/src/tools/esbuild/angular/component-stylesheets.js +63 -38
- package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +1 -1
- package/src/tools/esbuild/angular/jit-plugin-callbacks.js +11 -3
- package/src/tools/esbuild/application-code-bundle.d.ts +5 -4
- package/src/tools/esbuild/application-code-bundle.js +66 -41
- package/src/tools/esbuild/bundler-context.d.ts +2 -1
- package/src/tools/esbuild/bundler-context.js +10 -12
- package/src/tools/esbuild/bundler-execution-result.d.ts +5 -2
- package/src/tools/esbuild/bundler-execution-result.js +5 -1
- package/src/tools/esbuild/commonjs-checker.js +2 -2
- package/src/tools/esbuild/compiler-plugin-options.d.ts +1 -4
- package/src/tools/esbuild/compiler-plugin-options.js +14 -36
- package/src/tools/esbuild/global-scripts.js +1 -1
- package/src/tools/esbuild/global-styles.js +4 -1
- package/src/tools/esbuild/index-html-generator.js +8 -0
- package/src/tools/esbuild/javascript-transformer-worker.d.ts +1 -0
- package/src/tools/esbuild/javascript-transformer-worker.js +5 -1
- package/src/tools/esbuild/javascript-transformer.d.ts +2 -2
- package/src/tools/esbuild/javascript-transformer.js +7 -3
- package/src/tools/esbuild/server-bundle-metadata-plugin.d.ts +22 -0
- package/src/tools/esbuild/server-bundle-metadata-plugin.js +36 -0
- package/src/tools/esbuild/stylesheets/bundle-options.d.ts +2 -0
- package/src/tools/esbuild/stylesheets/bundle-options.js +2 -1
- package/src/tools/esbuild/stylesheets/sass-language.js +4 -0
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +9 -0
- package/src/tools/esbuild/utils.js +13 -31
- package/src/tools/sass/worker.js +19 -0
- package/src/tools/vite/middlewares/assets-middleware.d.ts +1 -1
- package/src/tools/vite/middlewares/assets-middleware.js +19 -3
- package/src/tools/vite/middlewares/component-middleware.d.ts +9 -0
- package/src/tools/vite/middlewares/component-middleware.js +33 -0
- package/src/tools/vite/middlewares/index.d.ts +1 -0
- package/src/tools/vite/middlewares/index.js +3 -1
- package/src/tools/vite/middlewares/ssr-middleware.js +13 -12
- package/src/tools/vite/plugins/setup-middlewares-plugin.d.ts +2 -1
- package/src/tools/vite/plugins/setup-middlewares-plugin.js +2 -1
- package/src/tools/vite/utils.d.ts +1 -0
- package/src/typings.d.ts +1 -1
- package/src/utils/environment-options.js +1 -1
- package/src/utils/index-file/auto-csp.d.ts +23 -0
- package/src/utils/index-file/auto-csp.js +283 -0
- package/src/utils/index-file/html-rewriting-stream.d.ts +5 -1
- package/src/utils/index-file/index-html-generator.d.ts +4 -0
- package/src/utils/index-file/index-html-generator.js +16 -0
- package/src/utils/index-file/inline-critical-css.js +17 -18
- package/src/utils/index-file/ngcm-attribute.d.ts +15 -0
- package/src/utils/index-file/ngcm-attribute.js +37 -0
- package/src/utils/index-file/valid-self-closing-tags.js +27 -0
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/fetch-patch.d.ts +1 -1
- package/src/utils/server-rendering/fetch-patch.js +2 -2
- package/src/utils/server-rendering/launch-server.d.ts +14 -0
- package/src/utils/server-rendering/launch-server.js +63 -0
- package/src/utils/server-rendering/load-esm-from-memory.d.ts +7 -0
- package/src/utils/server-rendering/manifest.d.ts +1 -1
- package/src/utils/server-rendering/manifest.js +4 -13
- package/src/utils/server-rendering/prerender.js +10 -6
- package/src/utils/server-rendering/render-worker.d.ts +4 -1
- package/src/utils/server-rendering/render-worker.js +13 -3
- package/src/utils/server-rendering/routes-extractor-worker.d.ts +5 -4
- package/src/utils/server-rendering/routes-extractor-worker.js +14 -4
- package/src/utils/server-rendering/utils.d.ts +11 -0
- package/src/utils/server-rendering/utils.js +17 -0
- package/src/utils/supported-browsers.js +1 -0
|
@@ -18,7 +18,18 @@
|
|
|
18
18
|
},
|
|
19
19
|
"server": {
|
|
20
20
|
"type": "string",
|
|
21
|
-
"description": "The full path for the server entry point to the application, relative to the current workspace."
|
|
21
|
+
"description": "The full path for the server entry point to the application, relative to the current workspace.",
|
|
22
|
+
"oneOf": [
|
|
23
|
+
{
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "The full path for the server entry point to the application, relative to the current workspace."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"const": false,
|
|
29
|
+
"type": "boolean",
|
|
30
|
+
"description": "Indicates that a server entry point is not provided."
|
|
31
|
+
}
|
|
32
|
+
]
|
|
22
33
|
},
|
|
23
34
|
"polyfills": {
|
|
24
35
|
"description": "A list of polyfills to include in the build. Can be a full path for a file, relative to the current workspace or module specifier. Example: 'zone.js'.",
|
|
@@ -37,6 +48,33 @@
|
|
|
37
48
|
"type": "string",
|
|
38
49
|
"description": "Customize the base path for the URLs of resources in 'index.html' and component stylesheets. This option is only necessary for specific deployment scenarios, such as with Angular Elements or when utilizing different CDN locations."
|
|
39
50
|
},
|
|
51
|
+
"security": {
|
|
52
|
+
"description": "Security features to protect against XSS and other common attacks",
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"properties": {
|
|
56
|
+
"autoCsp": {
|
|
57
|
+
"description": "Enables automatic generation of a hash-based Strict Content Security Policy (https://web.dev/articles/strict-csp#choose-hash) based on scripts in index.html. Will default to true once we are out of experimental/preview phases.",
|
|
58
|
+
"default": false,
|
|
59
|
+
"oneOf": [
|
|
60
|
+
{
|
|
61
|
+
"type": "object",
|
|
62
|
+
"properties": {
|
|
63
|
+
"unsafeEval": {
|
|
64
|
+
"type": "boolean",
|
|
65
|
+
"description": "Include the `unsafe-eval` directive (https://web.dev/articles/strict-csp#remove-eval) in the auto-CSP. Please only enable this if you are absolutely sure that you need to, as allowing calls to eval will weaken the XSS defenses provided by the auto-CSP.",
|
|
66
|
+
"default": false
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"additionalProperties": false
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"type": "boolean"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
40
78
|
"scripts": {
|
|
41
79
|
"description": "Global scripts to be included in the build.",
|
|
42
80
|
"type": "array",
|
|
@@ -125,6 +163,34 @@
|
|
|
125
163
|
"type": "string"
|
|
126
164
|
},
|
|
127
165
|
"default": []
|
|
166
|
+
},
|
|
167
|
+
"sass": {
|
|
168
|
+
"description": "Options to pass to the sass preprocessor.",
|
|
169
|
+
"type": "object",
|
|
170
|
+
"properties": {
|
|
171
|
+
"fatalDeprecations": {
|
|
172
|
+
"description": "A set of deprecations to treat as fatal. If a deprecation warning of any provided type is encountered during compilation, the compiler will error instead. If a Version is provided, then all deprecations that were active in that compiler version will be treated as fatal.",
|
|
173
|
+
"type": "array",
|
|
174
|
+
"items": {
|
|
175
|
+
"type": "string"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"silenceDeprecations": {
|
|
179
|
+
"description": " A set of active deprecations to ignore. If a deprecation warning of any provided type is encountered during compilation, the compiler will ignore it instead.",
|
|
180
|
+
"type": "array",
|
|
181
|
+
"items": {
|
|
182
|
+
"type": "string"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"futureDeprecations": {
|
|
186
|
+
"description": "A set of future deprecations to opt into early. Future deprecations passed here will be treated as active by the compiler, emitting warnings as necessary.",
|
|
187
|
+
"type": "array",
|
|
188
|
+
"items": {
|
|
189
|
+
"type": "string"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"additionalProperties": false
|
|
128
194
|
}
|
|
129
195
|
},
|
|
130
196
|
"additionalProperties": false
|
|
@@ -481,7 +547,6 @@
|
|
|
481
547
|
},
|
|
482
548
|
"prerender": {
|
|
483
549
|
"description": "Prerender (SSG) pages of your application during build time.",
|
|
484
|
-
"default": false,
|
|
485
550
|
"oneOf": [
|
|
486
551
|
{
|
|
487
552
|
"type": "boolean",
|
|
@@ -518,6 +583,11 @@
|
|
|
518
583
|
"entry": {
|
|
519
584
|
"type": "string",
|
|
520
585
|
"description": "The server entry-point that when executed will spawn the web server."
|
|
586
|
+
},
|
|
587
|
+
"experimentalPlatform": {
|
|
588
|
+
"description": "Specifies the platform for which the server bundle is generated. This affects the APIs and modules available in the server-side code. \n\n- `node`: (Default) Generates a bundle optimized for Node.js environments. \n- `neutral`: Generates a platform-neutral bundle suitable for environments like edge workers, and other serverless platforms. This option avoids using Node.js-specific APIs, making the bundle more portable. \n\nPlease note that this feature does not provide polyfills for Node.js modules. Additionally, it is experimental, and the schematics may undergo changes in future versions.",
|
|
589
|
+
"default": "node",
|
|
590
|
+
"enum": ["node", "neutral"]
|
|
521
591
|
}
|
|
522
592
|
},
|
|
523
593
|
"additionalProperties": false
|
|
@@ -526,8 +596,7 @@
|
|
|
526
596
|
},
|
|
527
597
|
"appShell": {
|
|
528
598
|
"type": "boolean",
|
|
529
|
-
"description": "Generates an application shell during build time."
|
|
530
|
-
"default": false
|
|
599
|
+
"description": "Generates an application shell during build time."
|
|
531
600
|
},
|
|
532
601
|
"outputMode": {
|
|
533
602
|
"type": "string",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
+
import { ComponentStylesheetBundler } from '../../tools/esbuild/angular/component-stylesheets';
|
|
8
9
|
import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache';
|
|
9
10
|
import { BundlerContext } from '../../tools/esbuild/bundler-context';
|
|
10
11
|
import { NormalizedApplicationBuildOptions } from './options';
|
|
@@ -16,4 +17,5 @@ import { NormalizedApplicationBuildOptions } from './options';
|
|
|
16
17
|
* @param codeBundleCache An instance of the TypeScript source file cache.
|
|
17
18
|
* @returns An array of BundlerContext objects.
|
|
18
19
|
*/
|
|
19
|
-
export declare function setupBundlerContexts(options: NormalizedApplicationBuildOptions,
|
|
20
|
+
export declare function setupBundlerContexts(options: NormalizedApplicationBuildOptions, target: string[], codeBundleCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler): BundlerContext[];
|
|
21
|
+
export declare function createComponentStyleBundler(options: NormalizedApplicationBuildOptions, target: string[]): ComponentStylesheetBundler;
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.setupBundlerContexts = setupBundlerContexts;
|
|
11
|
+
exports.createComponentStyleBundler = createComponentStyleBundler;
|
|
12
|
+
const component_stylesheets_1 = require("../../tools/esbuild/angular/component-stylesheets");
|
|
11
13
|
const application_code_bundle_1 = require("../../tools/esbuild/application-code-bundle");
|
|
12
14
|
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
13
15
|
const global_scripts_1 = require("../../tools/esbuild/global-scripts");
|
|
@@ -21,14 +23,13 @@ const utils_1 = require("../../tools/esbuild/utils");
|
|
|
21
23
|
* @param codeBundleCache An instance of the TypeScript source file cache.
|
|
22
24
|
* @returns An array of BundlerContext objects.
|
|
23
25
|
*/
|
|
24
|
-
function setupBundlerContexts(options,
|
|
26
|
+
function setupBundlerContexts(options, target, codeBundleCache, stylesheetBundler) {
|
|
25
27
|
const { outputMode, serverEntryPoint, appShellOptions, prerenderOptions, ssrOptions, workspaceRoot, watch = false, } = options;
|
|
26
|
-
const target = (0, utils_1.transformSupportedBrowsersToTargets)(browsers);
|
|
27
28
|
const bundlerContexts = [];
|
|
28
29
|
// Browser application code
|
|
29
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createBrowserCodeBundleOptions)(options, target, codeBundleCache)));
|
|
30
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createBrowserCodeBundleOptions)(options, target, codeBundleCache, stylesheetBundler)));
|
|
30
31
|
// Browser polyfills code
|
|
31
|
-
const browserPolyfillBundleOptions = (0, application_code_bundle_1.createBrowserPolyfillBundleOptions)(options, target, codeBundleCache);
|
|
32
|
+
const browserPolyfillBundleOptions = (0, application_code_bundle_1.createBrowserPolyfillBundleOptions)(options, target, codeBundleCache, stylesheetBundler);
|
|
32
33
|
if (browserPolyfillBundleOptions) {
|
|
33
34
|
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, browserPolyfillBundleOptions));
|
|
34
35
|
}
|
|
@@ -53,10 +54,10 @@ function setupBundlerContexts(options, browsers, codeBundleCache) {
|
|
|
53
54
|
// Skip server build when none of the features are enabled.
|
|
54
55
|
if (serverEntryPoint && (outputMode || prerenderOptions || appShellOptions || ssrOptions)) {
|
|
55
56
|
const nodeTargets = [...target, ...(0, utils_1.getSupportedNodeTargets)()];
|
|
56
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createServerMainCodeBundleOptions)(options, nodeTargets, codeBundleCache)));
|
|
57
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createServerMainCodeBundleOptions)(options, nodeTargets, codeBundleCache, stylesheetBundler)));
|
|
57
58
|
if (outputMode && ssrOptions?.entry) {
|
|
58
59
|
// New behavior introduced: 'server.ts' is now bundled separately from 'main.server.ts'.
|
|
59
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createSsrEntryCodeBundleOptions)(options, nodeTargets, codeBundleCache)));
|
|
60
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createSsrEntryCodeBundleOptions)(options, nodeTargets, codeBundleCache, stylesheetBundler)));
|
|
60
61
|
}
|
|
61
62
|
// Server polyfills code
|
|
62
63
|
const serverPolyfillBundleOptions = (0, application_code_bundle_1.createServerPolyfillBundleOptions)(options, nodeTargets, codeBundleCache);
|
|
@@ -66,3 +67,29 @@ function setupBundlerContexts(options, browsers, codeBundleCache) {
|
|
|
66
67
|
}
|
|
67
68
|
return bundlerContexts;
|
|
68
69
|
}
|
|
70
|
+
function createComponentStyleBundler(options, target) {
|
|
71
|
+
const { workspaceRoot, optimizationOptions, sourcemapOptions, outputNames, externalDependencies, preserveSymlinks, stylePreprocessorOptions, inlineStyleLanguage, cacheOptions, tailwindConfiguration, postcssConfiguration, publicPath, } = options;
|
|
72
|
+
const incremental = !!options.watch;
|
|
73
|
+
return new component_stylesheets_1.ComponentStylesheetBundler({
|
|
74
|
+
workspaceRoot,
|
|
75
|
+
inlineFonts: !!optimizationOptions.fonts.inline,
|
|
76
|
+
optimization: !!optimizationOptions.styles.minify,
|
|
77
|
+
sourcemap:
|
|
78
|
+
// Hidden component stylesheet sourcemaps are inaccessible which is effectively
|
|
79
|
+
// the same as being disabled. Disabling has the advantage of avoiding the overhead
|
|
80
|
+
// of sourcemap processing.
|
|
81
|
+
sourcemapOptions.styles && !sourcemapOptions.hidden ? 'linked' : false,
|
|
82
|
+
outputNames,
|
|
83
|
+
includePaths: stylePreprocessorOptions?.includePaths,
|
|
84
|
+
// string[] | undefined' is not assignable to type '(Version | DeprecationOrId)[] | undefined'.
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
86
|
+
sass: stylePreprocessorOptions?.sass,
|
|
87
|
+
externalDependencies,
|
|
88
|
+
target,
|
|
89
|
+
preserveSymlinks,
|
|
90
|
+
tailwindConfiguration,
|
|
91
|
+
postcssConfiguration,
|
|
92
|
+
cacheOptions,
|
|
93
|
+
publicPath,
|
|
94
|
+
}, inlineStyleLanguage, incremental);
|
|
95
|
+
}
|
|
@@ -16,7 +16,7 @@ import type { DevServerBuilderOutput } from './output';
|
|
|
16
16
|
interface OutputFileRecord {
|
|
17
17
|
contents: Uint8Array;
|
|
18
18
|
size: number;
|
|
19
|
-
hash
|
|
19
|
+
hash: string;
|
|
20
20
|
updated: boolean;
|
|
21
21
|
servable: boolean;
|
|
22
22
|
type: BuildOutputFileType;
|
|
@@ -32,6 +32,6 @@ export declare function serveWithVite(serverOptions: NormalizedDevServerOptions,
|
|
|
32
32
|
middleware?: Connect.NextHandleFunction[];
|
|
33
33
|
buildPlugins?: Plugin[];
|
|
34
34
|
}): AsyncIterableIterator<DevServerBuilderOutput>;
|
|
35
|
-
export declare function setupServer(serverOptions: NormalizedDevServerOptions, outputFiles: Map<string, OutputFileRecord>, assets: Map<string, string>, preserveSymlinks: boolean | undefined, externalMetadata: DevServerExternalResultMetadata, ssrMode: ServerSsrMode, prebundleTransformer: JavaScriptTransformer, target: string[], zoneless: boolean, usedComponentStyles: Map<string, string
|
|
35
|
+
export declare function setupServer(serverOptions: NormalizedDevServerOptions, outputFiles: Map<string, OutputFileRecord>, assets: Map<string, string>, preserveSymlinks: boolean | undefined, externalMetadata: DevServerExternalResultMetadata, ssrMode: ServerSsrMode, prebundleTransformer: JavaScriptTransformer, target: string[], zoneless: boolean, usedComponentStyles: Map<string, Set<string>>, templateUpdates: Map<string, string>, prebundleLoaderExtensions: EsbuildLoaderOption | undefined, extensionMiddleware?: Connect.NextHandleFunction[], indexHtmlTransformer?: (content: string) => Promise<string>, thirdPartySourcemaps?: boolean): Promise<InlineConfig>;
|
|
36
36
|
type EsbuildLoaderOption = Exclude<DepOptimizationConfig['esbuildOptions'], undefined>['loader'];
|
|
37
37
|
export {};
|
|
@@ -65,10 +65,11 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
65
65
|
}
|
|
66
66
|
// TODO: Adjust architect to not force a JsonObject derived return type
|
|
67
67
|
const browserOptions = (await context.validateOptions(rawBrowserOptions, builderName));
|
|
68
|
-
if (browserOptions.prerender) {
|
|
68
|
+
if (browserOptions.prerender || (browserOptions.outputMode && browserOptions.server)) {
|
|
69
69
|
// Disable prerendering if enabled and force SSR.
|
|
70
70
|
// This is so instead of prerendering all the routes for every change, the page is "prerendered" when it is requested.
|
|
71
|
-
browserOptions.prerender =
|
|
71
|
+
browserOptions.prerender = undefined;
|
|
72
|
+
browserOptions.ssr ||= true;
|
|
72
73
|
}
|
|
73
74
|
// Set all packages as external to support Vite's prebundle caching
|
|
74
75
|
browserOptions.externalPackages = serverOptions.prebundle;
|
|
@@ -91,8 +92,13 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
91
92
|
// https://nodejs.org/api/process.html#processsetsourcemapsenabledval
|
|
92
93
|
process.setSourceMapsEnabled(true);
|
|
93
94
|
}
|
|
94
|
-
//
|
|
95
|
-
browserOptions.externalRuntimeStyles = environment_options_1.useComponentStyleHmr;
|
|
95
|
+
// Enable to support component style hot reloading (`NG_HMR_CSTYLES=0` can be used to disable)
|
|
96
|
+
browserOptions.externalRuntimeStyles = !!serverOptions.liveReload && environment_options_1.useComponentStyleHmr;
|
|
97
|
+
if (browserOptions.externalRuntimeStyles) {
|
|
98
|
+
// Preload the @angular/compiler package to avoid first stylesheet request delays.
|
|
99
|
+
// Once @angular/build is native ESM, this should be re-evaluated.
|
|
100
|
+
void (0, load_esm_1.loadEsmModule)('@angular/compiler');
|
|
101
|
+
}
|
|
96
102
|
// Setup the prebundling transformer that will be shared across Vite prebundling requests
|
|
97
103
|
const prebundleTransformer = new internal_1.JavaScriptTransformer(
|
|
98
104
|
// Always enable JIT linking to support applications built with and without AOT.
|
|
@@ -115,6 +121,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
115
121
|
explicitServer: [],
|
|
116
122
|
};
|
|
117
123
|
const usedComponentStyles = new Map();
|
|
124
|
+
const templateUpdates = new Map();
|
|
118
125
|
// Add cleanup logic via a builder teardown.
|
|
119
126
|
let deferred;
|
|
120
127
|
context.addTeardown(async () => {
|
|
@@ -128,7 +135,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
128
135
|
case results_1.ResultKind.Failure:
|
|
129
136
|
if (result.errors.length && server) {
|
|
130
137
|
hadError = true;
|
|
131
|
-
server.
|
|
138
|
+
server.ws.send({
|
|
132
139
|
type: 'error',
|
|
133
140
|
err: {
|
|
134
141
|
message: result.errors[0].text,
|
|
@@ -156,6 +163,8 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
156
163
|
assetFiles.set('/' + normalizePath(outputPath), normalizePath(file.inputPath));
|
|
157
164
|
}
|
|
158
165
|
}
|
|
166
|
+
// Clear stale template updates on a code rebuilds
|
|
167
|
+
templateUpdates.clear();
|
|
159
168
|
// Analyze result files for changes
|
|
160
169
|
analyzeResultFiles(normalizePath, htmlIndexPath, result.files, generatedFiles);
|
|
161
170
|
break;
|
|
@@ -165,8 +174,18 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
165
174
|
break;
|
|
166
175
|
case results_1.ResultKind.ComponentUpdate:
|
|
167
176
|
(0, node_assert_1.default)(serverOptions.hmr, 'Component updates are only supported with HMR enabled.');
|
|
168
|
-
|
|
169
|
-
|
|
177
|
+
(0, node_assert_1.default)(server, 'Builder must provide an initial full build before component update results.');
|
|
178
|
+
for (const componentUpdate of result.updates) {
|
|
179
|
+
if (componentUpdate.type === 'template') {
|
|
180
|
+
templateUpdates.set(componentUpdate.id, componentUpdate.content);
|
|
181
|
+
server.ws.send('angular:component-update', {
|
|
182
|
+
id: componentUpdate.id,
|
|
183
|
+
timestamp: Date.now(),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
context.logger.info('Component update sent to client(s).');
|
|
188
|
+
continue;
|
|
170
189
|
default:
|
|
171
190
|
context.logger.warn(`Unknown result kind [${result.kind}] provided by build.`);
|
|
172
191
|
continue;
|
|
@@ -175,7 +194,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
175
194
|
if (hadError && server) {
|
|
176
195
|
hadError = false;
|
|
177
196
|
// Send an empty update to clear the error overlay
|
|
178
|
-
server.
|
|
197
|
+
server.ws.send({
|
|
179
198
|
'type': 'update',
|
|
180
199
|
updates: [],
|
|
181
200
|
});
|
|
@@ -248,11 +267,17 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
248
267
|
browserOptions.ssr.entry) {
|
|
249
268
|
ssrMode = plugins_1.ServerSsrMode.ExternalSsrMiddleware;
|
|
250
269
|
}
|
|
251
|
-
else if (browserOptions.
|
|
270
|
+
else if (browserOptions.ssr) {
|
|
252
271
|
ssrMode = plugins_1.ServerSsrMode.InternalSsrMiddleware;
|
|
253
272
|
}
|
|
273
|
+
if (browserOptions.progress !== false && ssrMode !== plugins_1.ServerSsrMode.NoSsr) {
|
|
274
|
+
// This is a workaround for https://github.com/angular/angular-cli/issues/28336, which is caused by the interaction between `zone.js` and `listr2`.
|
|
275
|
+
process.once('SIGINT', () => {
|
|
276
|
+
process.kill(process.pid);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
254
279
|
// Setup server and start listening
|
|
255
|
-
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), usedComponentStyles, browserOptions.loader, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
|
|
280
|
+
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), usedComponentStyles, templateUpdates, browserOptions.loader, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
|
|
256
281
|
server = await createServer(serverConfiguration);
|
|
257
282
|
await server.listen();
|
|
258
283
|
const urls = server.resolvedUrls;
|
|
@@ -268,7 +293,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
268
293
|
key: 'r',
|
|
269
294
|
description: 'force reload browser',
|
|
270
295
|
action(server) {
|
|
271
|
-
server.
|
|
296
|
+
server.ws.send({
|
|
272
297
|
type: 'full-reload',
|
|
273
298
|
path: '*',
|
|
274
299
|
});
|
|
@@ -311,7 +336,7 @@ async function handleUpdate(normalizePath, generatedFiles, server, serverOptions
|
|
|
311
336
|
if (serverOptions.liveReload || serverOptions.hmr) {
|
|
312
337
|
if (updatedFiles.every((f) => f.endsWith('.css'))) {
|
|
313
338
|
const timestamp = Date.now();
|
|
314
|
-
server.
|
|
339
|
+
server.ws.send({
|
|
315
340
|
type: 'update',
|
|
316
341
|
updates: updatedFiles.flatMap((filePath) => {
|
|
317
342
|
// For component styles, an HMR update must be sent for each one with the corresponding
|
|
@@ -321,7 +346,7 @@ async function handleUpdate(normalizePath, generatedFiles, server, serverOptions
|
|
|
321
346
|
// are not typically reused across components.
|
|
322
347
|
const componentIds = usedComponentStyles.get(filePath);
|
|
323
348
|
if (componentIds) {
|
|
324
|
-
return componentIds.map((id) => ({
|
|
349
|
+
return Array.from(componentIds).map((id) => ({
|
|
325
350
|
type: 'css-update',
|
|
326
351
|
timestamp,
|
|
327
352
|
path: `${filePath}?ngcomp` + (id ? `=${id}` : ''),
|
|
@@ -342,7 +367,7 @@ async function handleUpdate(normalizePath, generatedFiles, server, serverOptions
|
|
|
342
367
|
}
|
|
343
368
|
// Send reload command to clients
|
|
344
369
|
if (serverOptions.liveReload) {
|
|
345
|
-
server.
|
|
370
|
+
server.ws.send({
|
|
346
371
|
type: 'full-reload',
|
|
347
372
|
path: '*',
|
|
348
373
|
});
|
|
@@ -372,6 +397,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
372
397
|
contents: file.contents,
|
|
373
398
|
servable,
|
|
374
399
|
size: file.contents.byteLength,
|
|
400
|
+
hash: file.hash,
|
|
375
401
|
type: file.type,
|
|
376
402
|
updated: false,
|
|
377
403
|
});
|
|
@@ -402,13 +428,13 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
402
428
|
}
|
|
403
429
|
}
|
|
404
430
|
}
|
|
405
|
-
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, zoneless, usedComponentStyles, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
|
|
431
|
+
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, zoneless, usedComponentStyles, templateUpdates, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
|
|
406
432
|
const proxy = await (0, utils_1.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig);
|
|
407
433
|
// dynamically import Vite for ESM compatibility
|
|
408
434
|
const { normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
|
|
409
435
|
// Path will not exist on disk and only used to provide separate path for Vite requests
|
|
410
436
|
const virtualProjectRoot = normalizePath((0, node_path_1.join)(serverOptions.workspaceRoot, `.angular/vite-root`, serverOptions.buildTarget.project));
|
|
411
|
-
const cacheDir = (0, node_path_1.join)(serverOptions.cacheOptions.path, 'vite');
|
|
437
|
+
const cacheDir = (0, node_path_1.join)(serverOptions.cacheOptions.path, serverOptions.buildTarget.project, 'vite');
|
|
412
438
|
const configuration = {
|
|
413
439
|
configFile: false,
|
|
414
440
|
envFile: false,
|
|
@@ -495,6 +521,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
495
521
|
indexHtmlTransformer,
|
|
496
522
|
extensionMiddleware,
|
|
497
523
|
usedComponentStyles,
|
|
524
|
+
templateUpdates,
|
|
498
525
|
ssrMode,
|
|
499
526
|
}),
|
|
500
527
|
(0, plugins_1.createRemoveIdPrefixPlugin)(externalMetadata.explicitBrowser),
|
|
@@ -567,6 +594,9 @@ function getDepOptimizationConfig({ disabled, exclude, include, target, zoneless
|
|
|
567
594
|
supported: (0, internal_1.getFeatureSupport)(target, zoneless),
|
|
568
595
|
plugins,
|
|
569
596
|
loader,
|
|
597
|
+
define: {
|
|
598
|
+
'ngServerMode': `${ssr}`,
|
|
599
|
+
},
|
|
570
600
|
resolveExtensions: ['.mjs', '.js', '.cjs'],
|
|
571
601
|
},
|
|
572
602
|
};
|
package/src/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
8
|
export { buildApplication, type ApplicationBuilderOptions, type ApplicationBuilderOutput, } from './builders/application';
|
|
9
|
+
export type { ApplicationBuilderExtensions } from './builders/application/options';
|
|
9
10
|
export { type BuildOutputFile, BuildOutputFileType } from './tools/esbuild/bundler-context';
|
|
10
11
|
export type { BuildOutputAsset } from './tools/esbuild/bundler-execution-result';
|
|
11
12
|
export { executeDevServerBuilder, type DevServerBuilderOptions, type DevServerBuilderOutput, } from './builders/dev-server';
|
|
@@ -14,7 +14,7 @@ export interface AngularHostOptions {
|
|
|
14
14
|
sourceFileCache?: Map<string, ts.SourceFile>;
|
|
15
15
|
modifiedFiles?: Set<string>;
|
|
16
16
|
externalStylesheets?: Map<string, string>;
|
|
17
|
-
transformStylesheet(data: string, containingFile: string, stylesheetFile?: string, order?: number): Promise<string | null>;
|
|
17
|
+
transformStylesheet(data: string, containingFile: string, stylesheetFile?: string, order?: number, className?: string): Promise<string | null>;
|
|
18
18
|
processWebWorker(workerFile: string, containingFile: string): string;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
@@ -113,10 +113,7 @@ function createAngularCompilerHost(typescript, compilerOptions, hostOptions) {
|
|
|
113
113
|
if (data.trim().length === 0) {
|
|
114
114
|
return { content: '' };
|
|
115
115
|
}
|
|
116
|
-
const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined,
|
|
117
|
-
// TODO: Remove once available in compiler-cli types
|
|
118
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
-
context.order);
|
|
116
|
+
const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined, context.order, context.className);
|
|
120
117
|
return typeof result === 'string' ? { content: result } : null;
|
|
121
118
|
};
|
|
122
119
|
host.resourceNameToFileName = function (resourceName, containingFile) {
|
|
@@ -31,6 +31,7 @@ export declare abstract class AngularCompilation {
|
|
|
31
31
|
compilerOptions: ng.CompilerOptions;
|
|
32
32
|
referencedFiles: readonly string[];
|
|
33
33
|
externalStylesheets?: ReadonlyMap<string, string>;
|
|
34
|
+
templateUpdates?: ReadonlyMap<string, string>;
|
|
34
35
|
}>;
|
|
35
36
|
abstract emitAffectedFiles(): Iterable<EmitFileResult> | Promise<Iterable<EmitFileResult>>;
|
|
36
37
|
protected abstract collectDiagnostics(modes: DiagnosticModes): Iterable<ts.Diagnostic> | Promise<Iterable<ts.Diagnostic>>;
|
|
@@ -16,6 +16,7 @@ export declare class AotCompilation extends AngularCompilation {
|
|
|
16
16
|
compilerOptions: ng.CompilerOptions;
|
|
17
17
|
referencedFiles: readonly string[];
|
|
18
18
|
externalStylesheets?: ReadonlyMap<string, string>;
|
|
19
|
+
templateUpdates?: ReadonlyMap<string, string>;
|
|
19
20
|
}>;
|
|
20
21
|
collectDiagnostics(modes: DiagnosticModes): Iterable<ts.Diagnostic>;
|
|
21
22
|
emitAffectedFiles(): Iterable<EmitFileResult>;
|
|
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.AotCompilation = void 0;
|
|
14
14
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
|
+
const node_path_1 = require("node:path");
|
|
15
16
|
const typescript_1 = __importDefault(require("typescript"));
|
|
16
17
|
const profiling_1 = require("../../esbuild/profiling");
|
|
17
18
|
const angular_host_1 = require("../angular-host");
|
|
@@ -65,6 +66,33 @@ class AotCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
65
66
|
}
|
|
66
67
|
const typeScriptProgram = typescript_1.default.createEmitAndSemanticDiagnosticsBuilderProgram(angularTypeScriptProgram, host, oldProgram, configurationDiagnostics);
|
|
67
68
|
await (0, profiling_1.profileAsync)('NG_ANALYZE_PROGRAM', () => angularCompiler.analyzeAsync());
|
|
69
|
+
let templateUpdates;
|
|
70
|
+
if (compilerOptions['_enableHmr'] &&
|
|
71
|
+
hostOptions.modifiedFiles &&
|
|
72
|
+
hasOnlyTemplates(hostOptions.modifiedFiles)) {
|
|
73
|
+
const componentNodes = [...hostOptions.modifiedFiles].flatMap((file) => [
|
|
74
|
+
...angularCompiler.getComponentsWithTemplateFile(file),
|
|
75
|
+
]);
|
|
76
|
+
for (const node of componentNodes) {
|
|
77
|
+
if (!typescript_1.default.isClassDeclaration(node)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const componentFilename = node.getSourceFile().fileName;
|
|
81
|
+
let relativePath = (0, node_path_1.relative)(host.getCurrentDirectory(), componentFilename);
|
|
82
|
+
if (relativePath.startsWith('..')) {
|
|
83
|
+
relativePath = componentFilename;
|
|
84
|
+
}
|
|
85
|
+
const updateId = encodeURIComponent(`${host.getCanonicalFileName(relativePath)}@${node.name?.text}`);
|
|
86
|
+
const updateText = angularCompiler.emitHmrUpdateModule(node);
|
|
87
|
+
if (updateText === null) {
|
|
88
|
+
// Build is needed if a template cannot be updated
|
|
89
|
+
templateUpdates = undefined;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
templateUpdates ??= new Map();
|
|
93
|
+
templateUpdates.set(updateId, updateText);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
68
96
|
const affectedFiles = (0, profiling_1.profileSync)('NG_FIND_AFFECTED', () => findAffectedFiles(typeScriptProgram, angularCompiler, usingBuildInfo));
|
|
69
97
|
// Get all files referenced in the TypeScript/Angular program including component resources
|
|
70
98
|
const referencedFiles = typeScriptProgram
|
|
@@ -90,6 +118,7 @@ class AotCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
90
118
|
compilerOptions,
|
|
91
119
|
referencedFiles,
|
|
92
120
|
externalStylesheets: hostOptions.externalStylesheets,
|
|
121
|
+
templateUpdates,
|
|
93
122
|
};
|
|
94
123
|
}
|
|
95
124
|
*collectDiagnostics(modes) {
|
|
@@ -267,3 +296,13 @@ function findAffectedFiles(builder, { ignoreForDiagnostics }, includeTTC) {
|
|
|
267
296
|
}
|
|
268
297
|
return affectedFiles;
|
|
269
298
|
}
|
|
299
|
+
function hasOnlyTemplates(modifiedFiles) {
|
|
300
|
+
for (const file of modifiedFiles) {
|
|
301
|
+
const lowerFile = file.toLowerCase();
|
|
302
|
+
if (lowerFile.endsWith('.html') || lowerFile.endsWith('.svg')) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
@@ -37,9 +37,9 @@ class ParallelCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
37
37
|
initialize(tsconfig, hostOptions, compilerOptionsTransformer) {
|
|
38
38
|
const stylesheetChannel = new node_worker_threads_1.MessageChannel();
|
|
39
39
|
// The request identifier is required because Angular can issue multiple concurrent requests
|
|
40
|
-
stylesheetChannel.port1.on('message', ({ requestId, data, containingFile, stylesheetFile }) => {
|
|
40
|
+
stylesheetChannel.port1.on('message', ({ requestId, data, containingFile, stylesheetFile, order, className }) => {
|
|
41
41
|
hostOptions
|
|
42
|
-
.transformStylesheet(data, containingFile, stylesheetFile)
|
|
42
|
+
.transformStylesheet(data, containingFile, stylesheetFile, order, className)
|
|
43
43
|
.then((value) => stylesheetChannel.port1.postMessage({ requestId, value }))
|
|
44
44
|
.catch((error) => stylesheetChannel.port1.postMessage({ requestId, error }));
|
|
45
45
|
});
|
|
@@ -20,6 +20,7 @@ export interface InitRequest {
|
|
|
20
20
|
}
|
|
21
21
|
export declare function initialize(request: InitRequest): Promise<{
|
|
22
22
|
externalStylesheets: ReadonlyMap<string, string> | undefined;
|
|
23
|
+
templateUpdates: ReadonlyMap<string, string> | undefined;
|
|
23
24
|
referencedFiles: readonly string[];
|
|
24
25
|
compilerOptions: {
|
|
25
26
|
allowJs: boolean | undefined;
|
|
@@ -33,11 +33,11 @@ async function initialize(request) {
|
|
|
33
33
|
stylesheetRequests.get(requestId)?.[0](value);
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
-
const { compilerOptions, referencedFiles, externalStylesheets } = await compilation.initialize(request.tsconfig, {
|
|
36
|
+
const { compilerOptions, referencedFiles, externalStylesheets, templateUpdates } = await compilation.initialize(request.tsconfig, {
|
|
37
37
|
fileReplacements: request.fileReplacements,
|
|
38
38
|
sourceFileCache,
|
|
39
39
|
modifiedFiles: sourceFileCache.modifiedFiles,
|
|
40
|
-
transformStylesheet(data, containingFile, stylesheetFile) {
|
|
40
|
+
transformStylesheet(data, containingFile, stylesheetFile, order, className) {
|
|
41
41
|
const requestId = (0, node_crypto_1.randomUUID)();
|
|
42
42
|
const resultPromise = new Promise((resolve, reject) => stylesheetRequests.set(requestId, [resolve, reject]));
|
|
43
43
|
request.stylesheetPort.postMessage({
|
|
@@ -45,6 +45,8 @@ async function initialize(request) {
|
|
|
45
45
|
data,
|
|
46
46
|
containingFile,
|
|
47
47
|
stylesheetFile,
|
|
48
|
+
order,
|
|
49
|
+
className,
|
|
48
50
|
});
|
|
49
51
|
return resultPromise;
|
|
50
52
|
},
|
|
@@ -70,6 +72,7 @@ async function initialize(request) {
|
|
|
70
72
|
});
|
|
71
73
|
return {
|
|
72
74
|
externalStylesheets,
|
|
75
|
+
templateUpdates,
|
|
73
76
|
referencedFiles,
|
|
74
77
|
// TODO: Expand? `allowJs`, `isolatedModules`, `sourceMap`, `inlineSourceMap` are the only fields needed currently.
|
|
75
78
|
compilerOptions: {
|
|
@@ -0,0 +1,14 @@
|
|
|
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.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { PluginObj } from '@babel/core';
|
|
9
|
+
/**
|
|
10
|
+
* A babel plugin factory function for adding istanbul instrumentation.
|
|
11
|
+
*
|
|
12
|
+
* @returns A babel plugin object instance.
|
|
13
|
+
*/
|
|
14
|
+
export default function (): PluginObj;
|
|
@@ -0,0 +1,44 @@
|
|
|
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.dev/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.default = default_1;
|
|
14
|
+
const core_1 = require("@babel/core");
|
|
15
|
+
const istanbul_lib_instrument_1 = require("istanbul-lib-instrument");
|
|
16
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
17
|
+
/**
|
|
18
|
+
* A babel plugin factory function for adding istanbul instrumentation.
|
|
19
|
+
*
|
|
20
|
+
* @returns A babel plugin object instance.
|
|
21
|
+
*/
|
|
22
|
+
function default_1() {
|
|
23
|
+
const visitors = new WeakMap();
|
|
24
|
+
return {
|
|
25
|
+
visitor: {
|
|
26
|
+
Program: {
|
|
27
|
+
enter(path, state) {
|
|
28
|
+
const visitor = (0, istanbul_lib_instrument_1.programVisitor)(core_1.types, state.filename, {
|
|
29
|
+
// Babel returns a Converter object from the `convert-source-map` package
|
|
30
|
+
inputSourceMap: state.file.inputMap?.toObject(),
|
|
31
|
+
});
|
|
32
|
+
visitors.set(path, visitor);
|
|
33
|
+
visitor.enter(path);
|
|
34
|
+
},
|
|
35
|
+
exit(path) {
|
|
36
|
+
const visitor = visitors.get(path);
|
|
37
|
+
(0, node_assert_1.default)(visitor, 'Instrumentation visitor should always be present for program path.');
|
|
38
|
+
visitor.exit(path);
|
|
39
|
+
visitors.delete(path);
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|