@angular/build 19.0.0-next.1 → 19.0.0-next.10
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 +20 -16
- 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 +19 -2
- package/src/builders/application/execute-post-bundle.d.ts +2 -2
- package/src/builders/application/execute-post-bundle.js +58 -20
- package/src/builders/application/i18n.d.ts +2 -2
- package/src/builders/application/i18n.js +6 -16
- package/src/builders/application/index.js +8 -5
- package/src/builders/application/options.d.ts +36 -1
- package/src/builders/application/options.js +60 -3
- package/src/builders/application/schema.d.ts +15 -0
- package/src/builders/application/schema.js +11 -1
- package/src/builders/application/schema.json +5 -0
- package/src/builders/application/setup-bundling.js +12 -9
- package/src/builders/dev-server/internal.d.ts +0 -1
- package/src/builders/dev-server/internal.js +1 -3
- package/src/builders/dev-server/vite-server.d.ts +8 -2
- package/src/builders/dev-server/vite-server.js +111 -56
- package/src/builders/extract-i18n/application-extraction.js +3 -3
- package/src/tools/angular/angular-host.d.ts +2 -1
- package/src/tools/angular/angular-host.js +20 -1
- 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 +9 -1
- package/src/tools/angular/compilation/parallel-compilation.d.ts +2 -1
- package/src/tools/angular/compilation/parallel-compilation.js +2 -10
- package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
- package/src/tools/angular/compilation/parallel-worker.js +2 -1
- 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 +2 -0
- package/src/tools/esbuild/angular/compiler-plugin.js +44 -4
- package/src/tools/esbuild/angular/component-stylesheets.d.ts +8 -3
- package/src/tools/esbuild/angular/component-stylesheets.js +46 -11
- package/src/tools/esbuild/angular/file-reference-tracker.d.ts +1 -1
- package/src/tools/esbuild/application-code-bundle.d.ts +2 -6
- package/src/tools/esbuild/application-code-bundle.js +208 -67
- package/src/tools/esbuild/budget-stats.js +1 -1
- package/src/tools/esbuild/bundler-context.d.ts +4 -3
- package/src/tools/esbuild/bundler-context.js +21 -13
- package/src/tools/esbuild/bundler-execution-result.d.ts +5 -2
- package/src/tools/esbuild/bundler-execution-result.js +7 -3
- package/src/tools/esbuild/cache.d.ts +6 -1
- package/src/tools/esbuild/cache.js +7 -0
- package/src/tools/esbuild/compiler-plugin-options.js +3 -1
- package/src/tools/esbuild/i18n-inliner.js +4 -4
- 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 -12
- package/src/tools/esbuild/utils.d.ts +9 -0
- package/src/tools/esbuild/utils.js +21 -3
- package/src/tools/sass/sass-service.js +11 -13
- package/src/tools/sass/worker.d.ts +13 -32
- package/src/tools/sass/worker.js +1 -0
- package/src/tools/vite/middlewares/assets-middleware.d.ts +1 -1
- package/src/tools/vite/middlewares/assets-middleware.js +43 -4
- package/src/tools/vite/middlewares/headers-middleware.d.ts +19 -0
- package/src/tools/vite/middlewares/headers-middleware.js +34 -0
- package/src/tools/vite/middlewares/html-fallback-middleware.d.ts +1 -1
- package/src/tools/vite/middlewares/html-fallback-middleware.js +23 -7
- package/src/tools/vite/middlewares/index-html-middleware.js +1 -2
- package/src/tools/vite/middlewares/index.d.ts +2 -1
- package/src/tools/vite/middlewares/index.js +5 -2
- package/src/tools/vite/middlewares/ssr-middleware.d.ts +2 -4
- package/src/tools/vite/middlewares/ssr-middleware.js +75 -43
- package/src/tools/vite/plugins/angular-memory-plugin.d.ts +16 -0
- package/src/tools/vite/{angular-memory-plugin.js → plugins/angular-memory-plugin.js} +19 -40
- package/src/tools/vite/{i18n-locale-plugin.d.ts → plugins/i18n-locale-plugin.d.ts} +0 -4
- package/src/tools/vite/{i18n-locale-plugin.js → plugins/i18n-locale-plugin.js} +2 -3
- package/src/tools/vite/plugins/index.d.ts +12 -0
- package/src/tools/vite/plugins/index.js +21 -0
- package/src/tools/vite/plugins/setup-middlewares-plugin.d.ts +41 -0
- package/src/tools/vite/plugins/setup-middlewares-plugin.js +62 -0
- package/src/{utils/server-rendering/main-bundle-exports.js → tools/vite/plugins/ssr-transform-plugin.d.ts} +2 -2
- package/src/tools/vite/plugins/ssr-transform-plugin.js +38 -0
- package/src/tools/vite/utils.d.ts +0 -3
- package/src/tools/vite/utils.js +0 -12
- package/src/typings.d.ts +26 -0
- package/src/utils/environment-options.d.ts +2 -0
- package/src/utils/environment-options.js +5 -1
- package/src/utils/index-file/index-html-generator.js +5 -0
- package/src/utils/index-file/inline-critical-css.js +43 -33
- 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 +28 -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 +5 -6
- 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 +18 -2
- package/src/utils/server-rendering/manifest.d.ts +50 -0
- package/src/utils/server-rendering/manifest.js +126 -0
- package/src/utils/server-rendering/models.d.ts +27 -0
- package/src/utils/server-rendering/models.js +22 -0
- package/src/utils/server-rendering/prerender.d.ts +26 -10
- package/src/utils/server-rendering/prerender.js +122 -75
- package/src/utils/server-rendering/render-worker.d.ts +9 -8
- package/src/utils/server-rendering/render-worker.js +19 -14
- package/src/utils/server-rendering/routes-extractor-worker.d.ts +6 -10
- package/src/utils/server-rendering/routes-extractor-worker.js +16 -33
- package/src/utils/server-rendering/utils.d.ts +11 -0
- package/src/utils/server-rendering/utils.js +17 -0
- package/src/utils/worker-pool.d.ts +12 -0
- package/src/utils/worker-pool.js +43 -0
- package/src/tools/vite/angular-memory-plugin.d.ts +0 -21
- package/src/utils/server-rendering/main-bundle-exports.d.ts +0 -27
- package/src/utils/server-rendering/render-page.d.ts +0 -26
- package/src/utils/server-rendering/render-page.js +0 -114
- /package/src/tools/vite/{id-prefix-plugin.d.ts → plugins/id-prefix-plugin.d.ts} +0 -0
- /package/src/tools/vite/{id-prefix-plugin.js → plugins/id-prefix-plugin.js} +0 -0
|
@@ -28,7 +28,7 @@ function generateBudgetStats(metafile, outputFiles, initialFiles) {
|
|
|
28
28
|
continue;
|
|
29
29
|
}
|
|
30
30
|
// Exclude server bundles
|
|
31
|
-
if (type === bundler_context_1.BuildOutputFileType.
|
|
31
|
+
if (type === bundler_context_1.BuildOutputFileType.ServerApplication || type === bundler_context_1.BuildOutputFileType.ServerRoot) {
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
34
34
|
const initialRecord = initialFiles.get(file);
|
|
@@ -31,9 +31,10 @@ export interface InitialFileRecord {
|
|
|
31
31
|
depth: number;
|
|
32
32
|
}
|
|
33
33
|
export declare enum BuildOutputFileType {
|
|
34
|
-
Browser =
|
|
35
|
-
Media =
|
|
36
|
-
|
|
34
|
+
Browser = 0,
|
|
35
|
+
Media = 1,
|
|
36
|
+
ServerApplication = 2,
|
|
37
|
+
ServerRoot = 3,
|
|
37
38
|
Root = 4
|
|
38
39
|
}
|
|
39
40
|
export interface BuildOutputFile extends OutputFile {
|
|
@@ -18,9 +18,10 @@ const load_result_cache_1 = require("./load-result-cache");
|
|
|
18
18
|
const utils_1 = require("./utils");
|
|
19
19
|
var BuildOutputFileType;
|
|
20
20
|
(function (BuildOutputFileType) {
|
|
21
|
-
BuildOutputFileType[BuildOutputFileType["Browser"] =
|
|
22
|
-
BuildOutputFileType[BuildOutputFileType["Media"] =
|
|
23
|
-
BuildOutputFileType[BuildOutputFileType["
|
|
21
|
+
BuildOutputFileType[BuildOutputFileType["Browser"] = 0] = "Browser";
|
|
22
|
+
BuildOutputFileType[BuildOutputFileType["Media"] = 1] = "Media";
|
|
23
|
+
BuildOutputFileType[BuildOutputFileType["ServerApplication"] = 2] = "ServerApplication";
|
|
24
|
+
BuildOutputFileType[BuildOutputFileType["ServerRoot"] = 3] = "ServerRoot";
|
|
24
25
|
BuildOutputFileType[BuildOutputFileType["Root"] = 4] = "Root";
|
|
25
26
|
})(BuildOutputFileType || (exports.BuildOutputFileType = BuildOutputFileType = {}));
|
|
26
27
|
/**
|
|
@@ -138,6 +139,7 @@ class BundlerContext {
|
|
|
138
139
|
}
|
|
139
140
|
return result;
|
|
140
141
|
}
|
|
142
|
+
// eslint-disable-next-line max-lines-per-function
|
|
141
143
|
async #performBundle() {
|
|
142
144
|
// Create esbuild options if not present
|
|
143
145
|
if (this.#esbuildOptions === undefined) {
|
|
@@ -165,12 +167,6 @@ class BundlerContext {
|
|
|
165
167
|
// For non-incremental builds, perform a single build
|
|
166
168
|
result = await (0, esbuild_1.build)(this.#esbuildOptions);
|
|
167
169
|
}
|
|
168
|
-
if (this.#platformIsServer) {
|
|
169
|
-
for (const entry of Object.values(result.metafile.outputs)) {
|
|
170
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
171
|
-
entry['ng-platform-server'] = true;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
170
|
}
|
|
175
171
|
catch (failure) {
|
|
176
172
|
// Build failures will throw an exception which contains errors/warnings
|
|
@@ -280,6 +276,7 @@ class BundlerContext {
|
|
|
280
276
|
for (const { imports } of Object.values(result.metafile.outputs)) {
|
|
281
277
|
for (const importData of imports) {
|
|
282
278
|
if (!importData.external ||
|
|
279
|
+
utils_1.SERVER_GENERATED_EXTERNALS.has(importData.path) ||
|
|
283
280
|
(importData.kind !== 'import-statement' &&
|
|
284
281
|
importData.kind !== 'dynamic-import' &&
|
|
285
282
|
importData.kind !== 'require-call')) {
|
|
@@ -295,13 +292,24 @@ class BundlerContext {
|
|
|
295
292
|
if (!/\.([cm]?js|css|wasm)(\.map)?$/i.test(file.path)) {
|
|
296
293
|
fileType = BuildOutputFileType.Media;
|
|
297
294
|
}
|
|
295
|
+
else if (this.#platformIsServer) {
|
|
296
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
297
|
+
fileType = result.metafile['ng-ssr-entry-bundle']
|
|
298
|
+
? BuildOutputFileType.ServerRoot
|
|
299
|
+
: BuildOutputFileType.ServerApplication;
|
|
300
|
+
}
|
|
298
301
|
else {
|
|
299
|
-
fileType =
|
|
300
|
-
? BuildOutputFileType.Server
|
|
301
|
-
: BuildOutputFileType.Browser;
|
|
302
|
+
fileType = BuildOutputFileType.Browser;
|
|
302
303
|
}
|
|
303
304
|
return (0, utils_1.convertOutputFile)(file, fileType);
|
|
304
305
|
});
|
|
306
|
+
let externalConfiguration = this.#esbuildOptions.external;
|
|
307
|
+
if (this.#platformIsServer && externalConfiguration) {
|
|
308
|
+
externalConfiguration = externalConfiguration.filter((dep) => !utils_1.SERVER_GENERATED_EXTERNALS.has(dep));
|
|
309
|
+
if (!externalConfiguration.length) {
|
|
310
|
+
externalConfiguration = undefined;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
305
313
|
// Return the successful build results
|
|
306
314
|
return {
|
|
307
315
|
...result,
|
|
@@ -310,7 +318,7 @@ class BundlerContext {
|
|
|
310
318
|
externalImports: {
|
|
311
319
|
[this.#platformIsServer ? 'server' : 'browser']: externalImports,
|
|
312
320
|
},
|
|
313
|
-
externalConfiguration
|
|
321
|
+
externalConfiguration,
|
|
314
322
|
errors: undefined,
|
|
315
323
|
};
|
|
316
324
|
}
|
|
@@ -24,6 +24,9 @@ export interface ExternalResultMetadata {
|
|
|
24
24
|
implicitServer: string[];
|
|
25
25
|
explicit: string[];
|
|
26
26
|
}
|
|
27
|
+
export type PrerenderedRoutesRecord = Record<string, {
|
|
28
|
+
headers?: Record<string, string>;
|
|
29
|
+
}>;
|
|
27
30
|
/**
|
|
28
31
|
* Represents the result of a single builder execute call.
|
|
29
32
|
*/
|
|
@@ -33,7 +36,7 @@ export declare class ExecutionResult {
|
|
|
33
36
|
outputFiles: BuildOutputFile[];
|
|
34
37
|
assetFiles: BuildOutputAsset[];
|
|
35
38
|
errors: (Message | PartialMessage)[];
|
|
36
|
-
prerenderedRoutes:
|
|
39
|
+
prerenderedRoutes: PrerenderedRoutesRecord;
|
|
37
40
|
warnings: (Message | PartialMessage)[];
|
|
38
41
|
logs: string[];
|
|
39
42
|
externalMetadata?: ExternalResultMetadata;
|
|
@@ -46,7 +49,7 @@ export declare class ExecutionResult {
|
|
|
46
49
|
addLog(value: string): void;
|
|
47
50
|
addError(error: PartialMessage | string): void;
|
|
48
51
|
addErrors(errors: (PartialMessage | string)[]): void;
|
|
49
|
-
addPrerenderedRoutes(routes:
|
|
52
|
+
addPrerenderedRoutes(routes: PrerenderedRoutesRecord): void;
|
|
50
53
|
addWarning(error: PartialMessage | string): void;
|
|
51
54
|
addWarnings(errors: (PartialMessage | string)[]): void;
|
|
52
55
|
/**
|
|
@@ -19,7 +19,7 @@ class ExecutionResult {
|
|
|
19
19
|
outputFiles = [];
|
|
20
20
|
assetFiles = [];
|
|
21
21
|
errors = [];
|
|
22
|
-
prerenderedRoutes =
|
|
22
|
+
prerenderedRoutes = {};
|
|
23
23
|
warnings = [];
|
|
24
24
|
logs = [];
|
|
25
25
|
externalMetadata;
|
|
@@ -53,9 +53,13 @@ class ExecutionResult {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
addPrerenderedRoutes(routes) {
|
|
56
|
-
this.prerenderedRoutes
|
|
56
|
+
Object.assign(this.prerenderedRoutes, routes);
|
|
57
57
|
// Sort the prerendered routes.
|
|
58
|
-
|
|
58
|
+
const sortedObj = {};
|
|
59
|
+
for (const key of Object.keys(this.prerenderedRoutes).sort()) {
|
|
60
|
+
sortedObj[key] = this.prerenderedRoutes[key];
|
|
61
|
+
}
|
|
62
|
+
this.prerenderedRoutes = sortedObj;
|
|
59
63
|
}
|
|
60
64
|
addWarning(error) {
|
|
61
65
|
if (typeof error === 'string') {
|
|
@@ -84,5 +84,10 @@ export declare class MemoryCache<V> extends Cache<V, Map<string, V>> {
|
|
|
84
84
|
* Provides all the values currently present in the cache instance.
|
|
85
85
|
* @returns An iterable of all values in the cache.
|
|
86
86
|
*/
|
|
87
|
-
values():
|
|
87
|
+
values(): MapIterator<V>;
|
|
88
|
+
/**
|
|
89
|
+
* Provides all the keys/values currently present in the cache instance.
|
|
90
|
+
* @returns An iterable of all key/value pairs in the cache.
|
|
91
|
+
*/
|
|
92
|
+
entries(): MapIterator<[string, V]>;
|
|
88
93
|
}
|
|
@@ -88,5 +88,12 @@ class MemoryCache extends Cache {
|
|
|
88
88
|
values() {
|
|
89
89
|
return this.store.values();
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Provides all the keys/values currently present in the cache instance.
|
|
93
|
+
* @returns An iterable of all key/value pairs in the cache.
|
|
94
|
+
*/
|
|
95
|
+
entries() {
|
|
96
|
+
return this.store.entries();
|
|
97
|
+
}
|
|
91
98
|
}
|
|
92
99
|
exports.MemoryCache = MemoryCache;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.createCompilerPluginOptions = createCompilerPluginOptions;
|
|
11
11
|
function createCompilerPluginOptions(options, target, sourceFileCache) {
|
|
12
|
-
const { workspaceRoot, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, inlineStyleLanguage, jit, cacheOptions, tailwindConfiguration, postcssConfiguration, publicPath, } = options;
|
|
12
|
+
const { workspaceRoot, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, inlineStyleLanguage, jit, cacheOptions, tailwindConfiguration, postcssConfiguration, publicPath, externalRuntimeStyles, instrumentForCoverage, } = options;
|
|
13
13
|
return {
|
|
14
14
|
// JS/TS options
|
|
15
15
|
pluginOptions: {
|
|
@@ -22,6 +22,8 @@ function createCompilerPluginOptions(options, target, sourceFileCache) {
|
|
|
22
22
|
sourceFileCache,
|
|
23
23
|
loadResultCache: sourceFileCache?.loadResultCache,
|
|
24
24
|
incremental: !!options.watch,
|
|
25
|
+
externalRuntimeStyles,
|
|
26
|
+
instrumentForCoverage,
|
|
25
27
|
},
|
|
26
28
|
// Component stylesheet options
|
|
27
29
|
styleOptions: {
|
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.I18nInliner = void 0;
|
|
14
14
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
|
-
const
|
|
15
|
+
const worker_pool_1 = require("../../utils/worker-pool");
|
|
16
16
|
const bundler_context_1 = require("./bundler-context");
|
|
17
17
|
const utils_1 = require("./utils");
|
|
18
18
|
/**
|
|
@@ -36,7 +36,8 @@ class I18nInliner {
|
|
|
36
36
|
const files = new Map();
|
|
37
37
|
const pendingMaps = [];
|
|
38
38
|
for (const file of options.outputFiles) {
|
|
39
|
-
if (file.type === bundler_context_1.BuildOutputFileType.Root) {
|
|
39
|
+
if (file.type === bundler_context_1.BuildOutputFileType.Root || file.type === bundler_context_1.BuildOutputFileType.ServerRoot) {
|
|
40
|
+
// Skip also the server entry-point.
|
|
40
41
|
// Skip stats and similar files.
|
|
41
42
|
continue;
|
|
42
43
|
}
|
|
@@ -74,7 +75,7 @@ class I18nInliner {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
this.#localizeFiles = files;
|
|
77
|
-
this.#workerPool = new
|
|
78
|
+
this.#workerPool = new worker_pool_1.WorkerPool({
|
|
78
79
|
filename: require.resolve('./i18n-inliner-worker'),
|
|
79
80
|
maxThreads,
|
|
80
81
|
// Extract options to ensure only the named options are serialized and sent to the worker
|
|
@@ -83,7 +84,6 @@ class I18nInliner {
|
|
|
83
84
|
shouldOptimize: options.shouldOptimize,
|
|
84
85
|
files,
|
|
85
86
|
},
|
|
86
|
-
recordTiming: false,
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
@@ -14,6 +14,7 @@ interface JavaScriptTransformRequest {
|
|
|
14
14
|
skipLinker?: boolean;
|
|
15
15
|
sideEffects?: boolean;
|
|
16
16
|
jit: boolean;
|
|
17
|
+
instrumentForCoverage?: boolean;
|
|
17
18
|
}
|
|
18
19
|
export default function transformJavaScript(request: JavaScriptTransformRequest): Promise<unknown>;
|
|
19
20
|
export {};
|
|
@@ -63,8 +63,12 @@ async function transformWithBabel(filename, data, options) {
|
|
|
63
63
|
// @ts-expect-error Import attribute syntax plugin does not currently have type definitions
|
|
64
64
|
const { default: importAttributePlugin } = await Promise.resolve().then(() => __importStar(require('@babel/plugin-syntax-import-attributes')));
|
|
65
65
|
const plugins = [importAttributePlugin];
|
|
66
|
-
|
|
66
|
+
if (options.instrumentForCoverage) {
|
|
67
|
+
const { default: coveragePlugin } = await Promise.resolve().then(() => __importStar(require('../babel/plugins/add-code-coverage.js')));
|
|
68
|
+
plugins.push(coveragePlugin);
|
|
69
|
+
}
|
|
67
70
|
if (shouldLink) {
|
|
71
|
+
// Lazy load the linker plugin only when linking is required
|
|
68
72
|
const linkerPlugin = await createLinkerPlugin(options);
|
|
69
73
|
plugins.push(linkerPlugin);
|
|
70
74
|
}
|
|
@@ -35,7 +35,7 @@ export declare class JavaScriptTransformer {
|
|
|
35
35
|
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
36
36
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
37
37
|
*/
|
|
38
|
-
transformFile(filename: string, skipLinker?: boolean, sideEffects?: boolean): Promise<Uint8Array>;
|
|
38
|
+
transformFile(filename: string, skipLinker?: boolean, sideEffects?: boolean, instrumentForCoverage?: boolean): Promise<Uint8Array>;
|
|
39
39
|
/**
|
|
40
40
|
* Performs JavaScript transformations on the provided data of a file. The file does not need
|
|
41
41
|
* to exist on the filesystem.
|
|
@@ -45,7 +45,7 @@ export declare class JavaScriptTransformer {
|
|
|
45
45
|
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
46
46
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
47
47
|
*/
|
|
48
|
-
transformData(filename: string, data: string, skipLinker: boolean, sideEffects?: boolean): Promise<Uint8Array>;
|
|
48
|
+
transformData(filename: string, data: string, skipLinker: boolean, sideEffects?: boolean, instrumentForCoverage?: boolean): Promise<Uint8Array>;
|
|
49
49
|
/**
|
|
50
50
|
* Stops all active transformation tasks and shuts down all workers.
|
|
51
51
|
* @returns A void promise that resolves when closing is complete.
|
|
@@ -6,14 +6,11 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.dev/license
|
|
8
8
|
*/
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
10
|
exports.JavaScriptTransformer = void 0;
|
|
14
11
|
const node_crypto_1 = require("node:crypto");
|
|
15
12
|
const promises_1 = require("node:fs/promises");
|
|
16
|
-
const
|
|
13
|
+
const worker_pool_1 = require("../../utils/worker-pool");
|
|
17
14
|
/**
|
|
18
15
|
* A class that performs transformation of JavaScript files and raw data.
|
|
19
16
|
* A worker pool is used to distribute the transformation actions and allow
|
|
@@ -41,13 +38,9 @@ class JavaScriptTransformer {
|
|
|
41
38
|
this.#fileCacheKeyBase = Buffer.from(JSON.stringify(this.#commonOptions), 'utf-8');
|
|
42
39
|
}
|
|
43
40
|
#ensureWorkerPool() {
|
|
44
|
-
this.#workerPool ??= new
|
|
41
|
+
this.#workerPool ??= new worker_pool_1.WorkerPool({
|
|
45
42
|
filename: require.resolve('./javascript-transformer-worker'),
|
|
46
|
-
minThreads: 1,
|
|
47
43
|
maxThreads: this.maxThreads,
|
|
48
|
-
// Shutdown idle threads after 1 second of inactivity
|
|
49
|
-
idleTimeout: 1000,
|
|
50
|
-
recordTiming: false,
|
|
51
44
|
});
|
|
52
45
|
return this.#workerPool;
|
|
53
46
|
}
|
|
@@ -59,7 +52,7 @@ class JavaScriptTransformer {
|
|
|
59
52
|
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
60
53
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
61
54
|
*/
|
|
62
|
-
async transformFile(filename, skipLinker, sideEffects) {
|
|
55
|
+
async transformFile(filename, skipLinker, sideEffects, instrumentForCoverage) {
|
|
63
56
|
const data = await (0, promises_1.readFile)(filename);
|
|
64
57
|
let result;
|
|
65
58
|
let cacheKey;
|
|
@@ -86,6 +79,7 @@ class JavaScriptTransformer {
|
|
|
86
79
|
data,
|
|
87
80
|
skipLinker,
|
|
88
81
|
sideEffects,
|
|
82
|
+
instrumentForCoverage,
|
|
89
83
|
...this.#commonOptions,
|
|
90
84
|
}, {
|
|
91
85
|
// The below is disable as with Yarn PNP this causes build failures with the below message
|
|
@@ -113,10 +107,10 @@ class JavaScriptTransformer {
|
|
|
113
107
|
* @param sideEffects If false, and `advancedOptimizations` is enabled tslib decorators are wrapped.
|
|
114
108
|
* @returns A promise that resolves to a UTF-8 encoded Uint8Array containing the result.
|
|
115
109
|
*/
|
|
116
|
-
async transformData(filename, data, skipLinker, sideEffects) {
|
|
110
|
+
async transformData(filename, data, skipLinker, sideEffects, instrumentForCoverage) {
|
|
117
111
|
// Perform a quick test to determine if the data needs any transformations.
|
|
118
112
|
// This allows directly returning the data without the worker communication overhead.
|
|
119
|
-
if (skipLinker && !this.#commonOptions.advancedOptimizations) {
|
|
113
|
+
if (skipLinker && !this.#commonOptions.advancedOptimizations && !instrumentForCoverage) {
|
|
120
114
|
const keepSourcemap = this.#commonOptions.sourcemap &&
|
|
121
115
|
(!!this.#commonOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename));
|
|
122
116
|
return Buffer.from(keepSourcemap ? data : data.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, ''), 'utf-8');
|
|
@@ -126,6 +120,7 @@ class JavaScriptTransformer {
|
|
|
126
120
|
data,
|
|
127
121
|
skipLinker,
|
|
128
122
|
sideEffects,
|
|
123
|
+
instrumentForCoverage,
|
|
129
124
|
...this.#commonOptions,
|
|
130
125
|
});
|
|
131
126
|
}
|
|
@@ -47,3 +47,12 @@ export declare function logMessages(logger: BuilderContext['logger'], executionR
|
|
|
47
47
|
*/
|
|
48
48
|
export declare function isZonelessApp(polyfills: string[] | undefined): boolean;
|
|
49
49
|
export declare function getEntryPointName(entryPoint: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* A set of server-generated dependencies that are treated as external.
|
|
52
|
+
*
|
|
53
|
+
* These dependencies are marked as external because they are produced by a
|
|
54
|
+
* separate bundling process and are not included in the primary bundle. This
|
|
55
|
+
* ensures that these generated files are resolved from an external source rather
|
|
56
|
+
* than being part of the main bundle.
|
|
57
|
+
*/
|
|
58
|
+
export declare const SERVER_GENERATED_EXTERNALS: Set<string>;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.dev/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SERVER_GENERATED_EXTERNALS = void 0;
|
|
10
11
|
exports.logBuildStats = logBuildStats;
|
|
11
12
|
exports.getChunkNameFromMetafile = getChunkNameFromMetafile;
|
|
12
13
|
exports.calculateEstimatedTransferSizes = calculateEstimatedTransferSizes;
|
|
@@ -29,6 +30,8 @@ const node_path_1 = require("node:path");
|
|
|
29
30
|
const node_url_1 = require("node:url");
|
|
30
31
|
const node_zlib_1 = require("node:zlib");
|
|
31
32
|
const semver_1 = require("semver");
|
|
33
|
+
const schema_1 = require("../../builders/application/schema");
|
|
34
|
+
const manifest_1 = require("../../utils/server-rendering/manifest");
|
|
32
35
|
const stats_table_1 = require("../../utils/stats-table");
|
|
33
36
|
const bundler_context_1 = require("./bundler-context");
|
|
34
37
|
function logBuildStats(metafile, outputFiles, initial, budgetFailures, colors, changedFiles, estimatedTransferSizes, ssrOutputEnabled, verbose) {
|
|
@@ -45,7 +48,7 @@ function logBuildStats(metafile, outputFiles, initial, budgetFailures, colors, c
|
|
|
45
48
|
++unchangedCount;
|
|
46
49
|
continue;
|
|
47
50
|
}
|
|
48
|
-
const isPlatformServer = type === bundler_context_1.BuildOutputFileType.
|
|
51
|
+
const isPlatformServer = type === bundler_context_1.BuildOutputFileType.ServerApplication || type === bundler_context_1.BuildOutputFileType.ServerRoot;
|
|
49
52
|
if (isPlatformServer && !ssrOutputEnabled) {
|
|
50
53
|
// Only log server build stats when SSR is enabled.
|
|
51
54
|
continue;
|
|
@@ -340,7 +343,7 @@ function getSupportedNodeTargets() {
|
|
|
340
343
|
return SUPPORTED_NODE_VERSIONS.split('||').map((v) => 'node' + (0, semver_1.coerce)(v)?.version);
|
|
341
344
|
}
|
|
342
345
|
async function createJsonBuildManifest(result, normalizedOptions) {
|
|
343
|
-
const { colors: color, outputOptions: { base, server, browser }, ssrOptions, } = normalizedOptions;
|
|
346
|
+
const { colors: color, outputOptions: { base, server, browser }, ssrOptions, outputMode, } = normalizedOptions;
|
|
344
347
|
const { warnings, errors, prerenderedRoutes } = result;
|
|
345
348
|
const manifest = {
|
|
346
349
|
errors: errors.length ? await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color }) : [],
|
|
@@ -348,7 +351,9 @@ async function createJsonBuildManifest(result, normalizedOptions) {
|
|
|
348
351
|
outputPaths: {
|
|
349
352
|
root: (0, node_url_1.pathToFileURL)(base),
|
|
350
353
|
browser: (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, browser)),
|
|
351
|
-
server:
|
|
354
|
+
server: outputMode !== schema_1.OutputMode.Static && ssrOptions
|
|
355
|
+
? (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, server))
|
|
356
|
+
: undefined,
|
|
352
357
|
},
|
|
353
358
|
prerenderedRoutes,
|
|
354
359
|
};
|
|
@@ -385,3 +390,16 @@ function getEntryPointName(entryPoint) {
|
|
|
385
390
|
.replace(/\.[cm]?[jt]s$/, '')
|
|
386
391
|
.replace(/[\\/.]/g, '-');
|
|
387
392
|
}
|
|
393
|
+
/**
|
|
394
|
+
* A set of server-generated dependencies that are treated as external.
|
|
395
|
+
*
|
|
396
|
+
* These dependencies are marked as external because they are produced by a
|
|
397
|
+
* separate bundling process and are not included in the primary bundle. This
|
|
398
|
+
* ensures that these generated files are resolved from an external source rather
|
|
399
|
+
* than being part of the main bundle.
|
|
400
|
+
*/
|
|
401
|
+
exports.SERVER_GENERATED_EXTERNALS = new Set([
|
|
402
|
+
'./polyfills.server.mjs',
|
|
403
|
+
'./' + manifest_1.SERVER_APP_MANIFEST_FILENAME,
|
|
404
|
+
'./' + manifest_1.SERVER_APP_ENGINE_MANIFEST_FILENAME,
|
|
405
|
+
]);
|
|
@@ -34,17 +34,22 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
34
34
|
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
35
35
|
env.hasError = true;
|
|
36
36
|
}
|
|
37
|
+
var r, s = 0;
|
|
37
38
|
function next() {
|
|
38
|
-
while (env.stack.
|
|
39
|
-
var rec = env.stack.pop();
|
|
39
|
+
while (r = env.stack.pop()) {
|
|
40
40
|
try {
|
|
41
|
-
|
|
42
|
-
if (
|
|
41
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
42
|
+
if (r.dispose) {
|
|
43
|
+
var result = r.dispose.call(r.value);
|
|
44
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
45
|
+
}
|
|
46
|
+
else s |= 1;
|
|
43
47
|
}
|
|
44
48
|
catch (e) {
|
|
45
49
|
fail(e);
|
|
46
50
|
}
|
|
47
51
|
}
|
|
52
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
48
53
|
if (env.hasError) throw env.error;
|
|
49
54
|
}
|
|
50
55
|
return next();
|
|
@@ -61,8 +66,8 @@ exports.SassWorkerImplementation = void 0;
|
|
|
61
66
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
62
67
|
const node_url_1 = require("node:url");
|
|
63
68
|
const node_worker_threads_1 = require("node:worker_threads");
|
|
64
|
-
const piscina_1 = require("piscina");
|
|
65
69
|
const environment_options_1 = require("../../utils/environment-options");
|
|
70
|
+
const worker_pool_1 = require("../../utils/worker-pool");
|
|
66
71
|
// Polyfill Symbol.dispose if not present
|
|
67
72
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
73
|
Symbol.dispose ??= Symbol('Symbol Dispose');
|
|
@@ -85,16 +90,9 @@ class SassWorkerImplementation {
|
|
|
85
90
|
this.maxThreads = maxThreads;
|
|
86
91
|
}
|
|
87
92
|
#ensureWorkerPool() {
|
|
88
|
-
this.#workerPool ??= new
|
|
93
|
+
this.#workerPool ??= new worker_pool_1.WorkerPool({
|
|
89
94
|
filename: require.resolve('./worker'),
|
|
90
|
-
minThreads: 1,
|
|
91
95
|
maxThreads: this.maxThreads,
|
|
92
|
-
// Web containers do not support transferable objects with receiveOnMessagePort which
|
|
93
|
-
// is used when the Atomics based wait loop is enable.
|
|
94
|
-
useAtomics: !process.versions.webcontainer,
|
|
95
|
-
// Shutdown idle threads after 1 second of inactivity
|
|
96
|
-
idleTimeout: 1000,
|
|
97
|
-
recordTiming: false,
|
|
98
96
|
});
|
|
99
97
|
return this.#workerPool;
|
|
100
98
|
}
|
|
@@ -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 { RawSourceMap } from '@ampproject/remapping';
|
|
8
9
|
import { MessagePort } from 'node:worker_threads';
|
|
9
10
|
import { SourceSpan, StringOptions } from 'sass';
|
|
10
11
|
import type { SerializableWarningMessage } from './sass-service';
|
|
@@ -38,45 +39,25 @@ interface RenderRequestMessage {
|
|
|
38
39
|
*/
|
|
39
40
|
rebase: boolean;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
interface RenderResult {
|
|
42
43
|
warnings: SerializableWarningMessage[] | undefined;
|
|
43
44
|
result: {
|
|
44
|
-
loadedUrls: string[];
|
|
45
45
|
css: string;
|
|
46
|
-
|
|
46
|
+
loadedUrls: string[];
|
|
47
|
+
sourceMap?: RawSourceMap;
|
|
47
48
|
};
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
}
|
|
50
|
+
interface RenderError {
|
|
50
51
|
warnings: SerializableWarningMessage[] | undefined;
|
|
51
52
|
error: {
|
|
52
|
-
|
|
53
|
+
message: string;
|
|
54
|
+
stack?: string;
|
|
55
|
+
span?: Omit<SourceSpan, 'url'> & {
|
|
53
56
|
url?: string;
|
|
54
57
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sassMessage: string;
|
|
58
|
-
sassStack: string;
|
|
59
|
-
};
|
|
60
|
-
result?: undefined;
|
|
61
|
-
} | {
|
|
62
|
-
warnings: SerializableWarningMessage[] | undefined;
|
|
63
|
-
error: {
|
|
64
|
-
message: string;
|
|
65
|
-
stack: string | undefined;
|
|
66
|
-
span?: undefined;
|
|
67
|
-
sassMessage?: undefined;
|
|
68
|
-
sassStack?: undefined;
|
|
58
|
+
sassMessage?: string;
|
|
59
|
+
sassStack?: string;
|
|
69
60
|
};
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
warnings: SerializableWarningMessage[] | undefined;
|
|
73
|
-
error: {
|
|
74
|
-
message: string;
|
|
75
|
-
span?: undefined;
|
|
76
|
-
stack?: undefined;
|
|
77
|
-
sassMessage?: undefined;
|
|
78
|
-
sassStack?: undefined;
|
|
79
|
-
};
|
|
80
|
-
result?: undefined;
|
|
81
|
-
}>;
|
|
61
|
+
}
|
|
62
|
+
export default function renderSassStylesheet(request: RenderRequestMessage): Promise<RenderResult | RenderError>;
|
|
82
63
|
export {};
|
package/src/tools/sass/worker.js
CHANGED
|
@@ -95,6 +95,7 @@ async function renderSassStylesheet(request) {
|
|
|
95
95
|
warnings,
|
|
96
96
|
result: {
|
|
97
97
|
...result,
|
|
98
|
+
sourceMap: result.sourceMap,
|
|
98
99
|
// URL is not serializable so to convert to string here and back to URL in the parent.
|
|
99
100
|
loadedUrls: result.loadedUrls.map((p) => (0, node_url_1.fileURLToPath)(p)),
|
|
100
101
|
},
|
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Connect, ViteDevServer } from 'vite';
|
|
9
9
|
import { AngularMemoryOutputFiles } from '../utils';
|
|
10
|
-
export declare function createAngularAssetsMiddleware(server: ViteDevServer, assets: Map<string, string>, outputFiles: AngularMemoryOutputFiles): Connect.NextHandleFunction;
|
|
10
|
+
export declare function createAngularAssetsMiddleware(server: ViteDevServer, assets: Map<string, string>, outputFiles: AngularMemoryOutputFiles, usedComponentStyles: Map<string, string[]>): Connect.NextHandleFunction;
|
|
@@ -10,9 +10,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.createAngularAssetsMiddleware = createAngularAssetsMiddleware;
|
|
11
11
|
const mrmime_1 = require("mrmime");
|
|
12
12
|
const node_path_1 = require("node:path");
|
|
13
|
+
const load_esm_1 = require("../../../utils/load-esm");
|
|
13
14
|
const utils_1 = require("../utils");
|
|
14
|
-
function createAngularAssetsMiddleware(server, assets, outputFiles) {
|
|
15
|
-
return function (req, res, next) {
|
|
15
|
+
function createAngularAssetsMiddleware(server, assets, outputFiles, usedComponentStyles) {
|
|
16
|
+
return function angularAssetsMiddleware(req, res, next) {
|
|
16
17
|
if (req.url === undefined || res.writableEnded) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
@@ -47,19 +48,57 @@ function createAngularAssetsMiddleware(server, assets, outputFiles) {
|
|
|
47
48
|
next();
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
51
|
+
// Support HTTP HEAD requests for the virtual output files from the Angular build
|
|
52
|
+
if (req.method === 'HEAD' && outputFiles.get(pathname)?.servable) {
|
|
53
|
+
// While a GET will also generate content, the rest of the response is equivalent
|
|
54
|
+
req.method = 'GET';
|
|
55
|
+
}
|
|
50
56
|
// Resource files are handled directly.
|
|
51
57
|
// Global stylesheets (CSS files) are currently considered resources to workaround
|
|
52
58
|
// dev server sourcemap issues with stylesheets.
|
|
53
59
|
if (extension !== '.js' && extension !== '.html') {
|
|
54
60
|
const outputFile = outputFiles.get(pathname);
|
|
55
61
|
if (outputFile?.servable) {
|
|
62
|
+
const data = outputFile.contents;
|
|
63
|
+
if (extension === '.css') {
|
|
64
|
+
// Inject component ID for view encapsulation if requested
|
|
65
|
+
const componentId = new URL(req.url, 'http://localhost').searchParams.get('ngcomp');
|
|
66
|
+
if (componentId !== null) {
|
|
67
|
+
// Record the component style usage for HMR updates
|
|
68
|
+
const usedIds = usedComponentStyles.get(pathname);
|
|
69
|
+
if (usedIds === undefined) {
|
|
70
|
+
usedComponentStyles.set(pathname, [componentId]);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
usedIds.push(componentId);
|
|
74
|
+
}
|
|
75
|
+
// Shim the stylesheet if a component ID is provided
|
|
76
|
+
if (componentId.length > 0) {
|
|
77
|
+
// Validate component ID
|
|
78
|
+
if (/^[_.\-\p{Letter}\d]+-c\d{9}$/u.test(componentId)) {
|
|
79
|
+
(0, load_esm_1.loadEsmModule)('@angular/compiler')
|
|
80
|
+
.then((compilerModule) => {
|
|
81
|
+
const encapsulatedData = compilerModule.encapsulateStyle(new TextDecoder().decode(data), componentId);
|
|
82
|
+
res.setHeader('Content-Type', 'text/css');
|
|
83
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
84
|
+
res.end(encapsulatedData);
|
|
85
|
+
})
|
|
86
|
+
.catch((e) => next(e));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// eslint-disable-next-line no-console
|
|
91
|
+
console.error('Invalid component stylesheet ID request: ' + componentId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
56
96
|
const mimeType = (0, mrmime_1.lookup)(extension);
|
|
57
97
|
if (mimeType) {
|
|
58
98
|
res.setHeader('Content-Type', mimeType);
|
|
59
99
|
}
|
|
60
100
|
res.setHeader('Cache-Control', 'no-cache');
|
|
61
|
-
|
|
62
|
-
res.end(outputFile.contents);
|
|
101
|
+
res.end(data);
|
|
63
102
|
return;
|
|
64
103
|
}
|
|
65
104
|
}
|