@angular-devkit/build-angular 17.3.0-rc.0 → 17.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -13
- package/src/builders/application/build-action.d.ts +6 -2
- package/src/builders/application/build-action.js +22 -24
- package/src/builders/application/execute-build.js +1 -1
- package/src/builders/application/index.js +9 -6
- package/src/builders/application/options.js +4 -1
- package/src/builders/dev-server/builder.js +13 -4
- package/src/builders/dev-server/schema.d.ts +6 -3
- package/src/builders/dev-server/schema.json +3 -3
- package/src/builders/dev-server/vite-server.js +0 -1
- package/src/tools/esbuild/angular/angular-host.js +4 -0
- package/src/tools/esbuild/angular/compiler-plugin.js +5 -2
- package/src/tools/esbuild/application-code-bundle.js +1 -1
- package/src/tools/esbuild/bundler-context.js +2 -2
- package/src/tools/esbuild/bundler-execution-result.d.ts +2 -0
- package/src/tools/esbuild/bundler-execution-result.js +4 -0
- package/src/tools/esbuild/utils.d.ts +3 -2
- package/src/tools/esbuild/utils.js +27 -25
- 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/render-page.js +2 -2
- package/src/utils/server-rendering/render-worker.js +0 -2
- package/src/utils/server-rendering/routes-extractor-worker.js +3 -3
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "17.3.
|
|
3
|
+
"version": "17.3.1",
|
|
4
4
|
"description": "Angular Webpack Build Facade",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
7
7
|
"builders": "builders.json",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@ampproject/remapping": "2.3.0",
|
|
10
|
-
"@angular-devkit/architect": "0.1703.
|
|
11
|
-
"@angular-devkit/build-webpack": "0.1703.
|
|
12
|
-
"@angular-devkit/core": "17.3.
|
|
10
|
+
"@angular-devkit/architect": "0.1703.1",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1703.1",
|
|
12
|
+
"@angular-devkit/core": "17.3.1",
|
|
13
13
|
"@babel/core": "7.24.0",
|
|
14
14
|
"@babel/generator": "7.23.6",
|
|
15
15
|
"@babel/helper-annotate-as-pure": "7.22.5",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@babel/preset-env": "7.24.0",
|
|
21
21
|
"@babel/runtime": "7.24.0",
|
|
22
22
|
"@discoveryjs/json-ext": "0.5.7",
|
|
23
|
-
"@ngtools/webpack": "17.3.
|
|
23
|
+
"@ngtools/webpack": "17.3.1",
|
|
24
24
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
25
25
|
"ansi-colors": "4.1.3",
|
|
26
26
|
"autoprefixer": "10.4.18",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"babel-plugin-istanbul": "6.1.1",
|
|
29
29
|
"browserslist": "^4.21.5",
|
|
30
30
|
"copy-webpack-plugin": "11.0.0",
|
|
31
|
-
"critters": "0.0.
|
|
31
|
+
"critters": "0.0.22",
|
|
32
32
|
"css-loader": "6.10.0",
|
|
33
33
|
"esbuild-wasm": "0.20.1",
|
|
34
34
|
"fast-glob": "3.3.2",
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"semver": "7.6.0",
|
|
59
59
|
"source-map-loader": "5.0.0",
|
|
60
60
|
"source-map-support": "0.5.21",
|
|
61
|
-
"terser": "5.
|
|
61
|
+
"terser": "5.29.1",
|
|
62
62
|
"tree-kill": "1.2.2",
|
|
63
63
|
"tslib": "2.6.2",
|
|
64
|
-
"undici": "6.7.
|
|
64
|
+
"undici": "6.7.1",
|
|
65
65
|
"vite": "5.1.5",
|
|
66
66
|
"watchpack": "2.4.0",
|
|
67
67
|
"webpack": "5.90.3",
|
|
@@ -74,16 +74,16 @@
|
|
|
74
74
|
"esbuild": "0.20.1"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"@angular/compiler-cli": "^17.0.0
|
|
78
|
-
"@angular/localize": "^17.0.0
|
|
79
|
-
"@angular/platform-server": "^17.0.0
|
|
80
|
-
"@angular/service-worker": "^17.0.0
|
|
77
|
+
"@angular/compiler-cli": "^17.0.0",
|
|
78
|
+
"@angular/localize": "^17.0.0",
|
|
79
|
+
"@angular/platform-server": "^17.0.0",
|
|
80
|
+
"@angular/service-worker": "^17.0.0",
|
|
81
81
|
"@web/test-runner": "^0.18.0",
|
|
82
82
|
"browser-sync": "^3.0.2",
|
|
83
83
|
"jest": "^29.5.0",
|
|
84
84
|
"jest-environment-jsdom": "^29.5.0",
|
|
85
85
|
"karma": "^6.3.0",
|
|
86
|
-
"ng-packagr": "^17.0.0
|
|
86
|
+
"ng-packagr": "^17.0.0",
|
|
87
87
|
"protractor": "^7.0.0",
|
|
88
88
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
89
89
|
"typescript": ">=5.2 <5.5"
|
|
@@ -11,7 +11,8 @@ import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
|
|
|
11
11
|
import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result';
|
|
12
12
|
import { NormalizedCachedOptions } from '../../utils/normalize-cache';
|
|
13
13
|
import { NormalizedOutputOptions } from './options';
|
|
14
|
-
|
|
14
|
+
type BuildActionOutput = (ExecutionResult['outputWithFiles'] | ExecutionResult['output']) & BuilderOutput;
|
|
15
|
+
export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildState) => Promise<ExecutionResult>, options: {
|
|
15
16
|
workspaceRoot: string;
|
|
16
17
|
projectRoot: string;
|
|
17
18
|
outputOptions: NormalizedOutputOptions;
|
|
@@ -27,4 +28,7 @@ export declare function runEsBuildBuildAction(action: (rebuildState?: RebuildSta
|
|
|
27
28
|
signal?: AbortSignal;
|
|
28
29
|
preserveSymlinks?: boolean;
|
|
29
30
|
clearScreen?: boolean;
|
|
30
|
-
|
|
31
|
+
colors?: boolean;
|
|
32
|
+
jsonLogs?: boolean;
|
|
33
|
+
}): AsyncIterable<BuildActionOutput>;
|
|
34
|
+
export {};
|
|
@@ -54,7 +54,7 @@ const packageWatchFiles = [
|
|
|
54
54
|
'.pnp.data.json',
|
|
55
55
|
];
|
|
56
56
|
async function* runEsBuildBuildAction(action, options) {
|
|
57
|
-
const { writeToFileSystemFilter, writeToFileSystem, watch, poll, clearScreen, logger, deleteOutputPath, cacheOptions, outputOptions, verbose, projectRoot, workspaceRoot, progress, preserveSymlinks, } = options;
|
|
57
|
+
const { writeToFileSystemFilter, writeToFileSystem, watch, poll, clearScreen, logger, deleteOutputPath, cacheOptions, outputOptions, verbose, projectRoot, workspaceRoot, progress, preserveSymlinks, colors, jsonLogs, } = options;
|
|
58
58
|
if (deleteOutputPath && writeToFileSystem) {
|
|
59
59
|
await (0, delete_output_dir_1.deleteOutputDir)(workspaceRoot, outputOptions.base, [
|
|
60
60
|
outputOptions.browser,
|
|
@@ -67,6 +67,8 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
67
67
|
try {
|
|
68
68
|
// Perform the build action
|
|
69
69
|
result = await withProgress('Building...', () => action());
|
|
70
|
+
// Log all diagnostic (error/warning/logs) messages
|
|
71
|
+
await (0, utils_1.logMessages)(logger, result, colors, jsonLogs);
|
|
70
72
|
}
|
|
71
73
|
finally {
|
|
72
74
|
// Ensure Sass workers are shutdown if not watching
|
|
@@ -115,16 +117,7 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
115
117
|
// Output the first build results after setting up the watcher to ensure that any code executed
|
|
116
118
|
// higher in the iterator call stack will trigger the watcher. This is particularly relevant for
|
|
117
119
|
// unit tests which execute the builder and modify the file system programmatically.
|
|
118
|
-
|
|
119
|
-
// Write output files
|
|
120
|
-
await (0, utils_1.writeResultFiles)(result.outputFiles, result.assetFiles, outputOptions);
|
|
121
|
-
yield result.output;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
|
|
125
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
126
|
-
yield result.outputWithFiles;
|
|
127
|
-
}
|
|
120
|
+
yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);
|
|
128
121
|
// Finish if watch mode is not enabled
|
|
129
122
|
if (!watcher) {
|
|
130
123
|
return;
|
|
@@ -144,6 +137,8 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
144
137
|
logger.info(changes.toDebugString());
|
|
145
138
|
}
|
|
146
139
|
result = await withProgress('Changes detected. Rebuilding...', () => action(result.createRebuildState(changes)));
|
|
140
|
+
// Log all diagnostic (error/warning/logs) messages
|
|
141
|
+
await (0, utils_1.logMessages)(logger, result, colors, jsonLogs);
|
|
147
142
|
// Update watched locations provided by the new build result.
|
|
148
143
|
// Keep watching all previous files if there are any errors; otherwise consider all
|
|
149
144
|
// files stale until confirmed present in the new result's watch files.
|
|
@@ -161,19 +156,7 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
161
156
|
if (staleWatchFiles?.size) {
|
|
162
157
|
watcher.remove([...staleWatchFiles]);
|
|
163
158
|
}
|
|
164
|
-
|
|
165
|
-
// Write output files
|
|
166
|
-
const filesToWrite = writeToFileSystemFilter
|
|
167
|
-
? result.outputFiles.filter(writeToFileSystemFilter)
|
|
168
|
-
: result.outputFiles;
|
|
169
|
-
await (0, utils_1.writeResultFiles)(filesToWrite, result.assetFiles, outputOptions);
|
|
170
|
-
yield result.output;
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
|
|
174
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
175
|
-
yield result.outputWithFiles;
|
|
176
|
-
}
|
|
159
|
+
yield await writeAndEmitOutput(writeToFileSystem, result, outputOptions, writeToFileSystemFilter);
|
|
177
160
|
}
|
|
178
161
|
}
|
|
179
162
|
finally {
|
|
@@ -183,3 +166,18 @@ async function* runEsBuildBuildAction(action, options) {
|
|
|
183
166
|
}
|
|
184
167
|
}
|
|
185
168
|
exports.runEsBuildBuildAction = runEsBuildBuildAction;
|
|
169
|
+
async function writeAndEmitOutput(writeToFileSystem, { outputFiles, output, outputWithFiles, assetFiles }, outputOptions, writeToFileSystemFilter) {
|
|
170
|
+
if (writeToFileSystem) {
|
|
171
|
+
// Write output files
|
|
172
|
+
const outputFilesToWrite = writeToFileSystemFilter
|
|
173
|
+
? outputFiles.filter(writeToFileSystemFilter)
|
|
174
|
+
: outputFiles;
|
|
175
|
+
await (0, utils_1.writeResultFiles)(outputFilesToWrite, assetFiles, outputOptions);
|
|
176
|
+
return output;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
// Requires casting due to unneeded `JsonObject` requirement. Remove once fixed.
|
|
180
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
181
|
+
return outputWithFiles;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -120,7 +120,7 @@ async function executeBuild(options, context, rebuildState) {
|
|
|
120
120
|
executionResult.addOutputFile('stats.json', JSON.stringify(metafile, null, 2), bundler_context_1.BuildOutputFileType.Root);
|
|
121
121
|
}
|
|
122
122
|
if (!jsonLogs) {
|
|
123
|
-
|
|
123
|
+
executionResult.addLog((0, utils_1.logBuildStats)(metafile, initialFiles, budgetFailures, colors, changedFiles, estimatedTransferSizes, !!ssrOptions, verbose));
|
|
124
124
|
}
|
|
125
125
|
return executionResult;
|
|
126
126
|
}
|
|
@@ -62,22 +62,23 @@ context, infrastructureSettings, extensions) {
|
|
|
62
62
|
const { prerenderOptions, outputOptions, jsonLogs } = normalizedOptions;
|
|
63
63
|
const startTime = process.hrtime.bigint();
|
|
64
64
|
const result = await (0, execute_build_1.executeBuild)(normalizedOptions, context, rebuildState);
|
|
65
|
-
if (
|
|
65
|
+
if (jsonLogs) {
|
|
66
|
+
result.addLog(await (0, utils_1.createJsonBuildManifest)(result, normalizedOptions));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
66
69
|
if (prerenderOptions) {
|
|
67
70
|
const prerenderedRoutesLength = result.prerenderedRoutes.length;
|
|
68
71
|
let prerenderMsg = `Prerendered ${prerenderedRoutesLength} static route`;
|
|
69
72
|
prerenderMsg += prerenderedRoutesLength !== 1 ? 's.' : '.';
|
|
70
|
-
|
|
73
|
+
result.addLog(color_1.colors.magenta(prerenderMsg));
|
|
71
74
|
}
|
|
72
75
|
const buildTime = Number(process.hrtime.bigint() - startTime) / 10 ** 9;
|
|
73
76
|
const hasError = result.errors.length > 0;
|
|
74
77
|
if (writeToFileSystem && !hasError) {
|
|
75
|
-
|
|
78
|
+
result.addLog(`Output location: ${outputOptions.base}\n`);
|
|
76
79
|
}
|
|
77
|
-
|
|
80
|
+
result.addLog(`Application bundle generation ${hasError ? 'failed' : 'complete'}. [${buildTime.toFixed(3)} seconds]\n`);
|
|
78
81
|
}
|
|
79
|
-
// Log all diagnostic (error/warning) messages
|
|
80
|
-
await (0, utils_1.logMessages)(logger, result, normalizedOptions);
|
|
81
82
|
return result;
|
|
82
83
|
}, {
|
|
83
84
|
watch: normalizedOptions.watch,
|
|
@@ -91,6 +92,8 @@ context, infrastructureSettings, extensions) {
|
|
|
91
92
|
workspaceRoot: normalizedOptions.workspaceRoot,
|
|
92
93
|
progress: normalizedOptions.progress,
|
|
93
94
|
clearScreen: normalizedOptions.clearScreen,
|
|
95
|
+
colors: normalizedOptions.colors,
|
|
96
|
+
jsonLogs: normalizedOptions.jsonLogs,
|
|
94
97
|
writeToFileSystem,
|
|
95
98
|
// For app-shell and SSG server files are not required by users.
|
|
96
99
|
// Omit these when SSR is not enabled.
|
|
@@ -141,7 +141,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
|
|
|
141
141
|
serverEntryPoint = node_path_1.default.join(workspaceRoot, options.server);
|
|
142
142
|
}
|
|
143
143
|
else if (options.server === '') {
|
|
144
|
-
throw new Error('
|
|
144
|
+
throw new Error('The "server" option cannot be an empty string.');
|
|
145
145
|
}
|
|
146
146
|
let prerenderOptions;
|
|
147
147
|
if (options.prerender) {
|
|
@@ -167,6 +167,9 @@ async function normalizeOptions(context, projectName, options, extensions) {
|
|
|
167
167
|
route: 'shell',
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
|
+
if ((appShellOptions || ssrOptions || prerenderOptions) && !serverEntryPoint) {
|
|
171
|
+
throw new Error('The "server" option is required when enabling "ssr", "prerender" or "app-shell".');
|
|
172
|
+
}
|
|
170
173
|
// Initial options to keep
|
|
171
174
|
const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, deleteOutputPath, namedChunks, budgets, deployUrl, clearScreen, define, } = options;
|
|
172
175
|
// Return all the normalized options
|
|
@@ -54,19 +54,28 @@ function execute(options, context, transforms = {}, extensions) {
|
|
|
54
54
|
// Determine project name from builder context target
|
|
55
55
|
const projectName = context.target?.project;
|
|
56
56
|
if (!projectName) {
|
|
57
|
-
context.logger.error(`The
|
|
57
|
+
context.logger.error(`The "dev-server" builder requires a target to be specified.`);
|
|
58
58
|
return rxjs_1.EMPTY;
|
|
59
59
|
}
|
|
60
60
|
return (0, rxjs_1.defer)(() => initialize(options, projectName, context, extensions?.builderSelector)).pipe((0, rxjs_1.switchMap)(({ builderName, normalizedOptions }) => {
|
|
61
61
|
// Use vite-based development server for esbuild-based builds
|
|
62
62
|
if (isEsbuildBased(builderName)) {
|
|
63
63
|
if (transforms?.logging || transforms?.webpackConfiguration) {
|
|
64
|
-
throw new Error(
|
|
64
|
+
throw new Error(`The "application" and "browser-esbuild" builders do not support Webpack transforms.`);
|
|
65
65
|
}
|
|
66
66
|
// Warn if the initial options provided by the user enable prebundling but caching is disabled
|
|
67
67
|
if (options.prebundle && !normalizedOptions.cacheOptions.enabled) {
|
|
68
68
|
context.logger.warn(`Prebundling has been configured but will not be used because caching has been disabled.`);
|
|
69
69
|
}
|
|
70
|
+
if (options.allowedHosts?.length) {
|
|
71
|
+
context.logger.warn(`The "allowedHosts" option will not be used because it is not supported by the "${builderName}" builder.`);
|
|
72
|
+
}
|
|
73
|
+
if (options.publicHost) {
|
|
74
|
+
context.logger.warn(`The "publicHost" option will not be used because it is not supported by the "${builderName}" builder.`);
|
|
75
|
+
}
|
|
76
|
+
if (options.disableHostCheck) {
|
|
77
|
+
context.logger.warn(`The "disableHostCheck" option will not be used because it is not supported by the "${builderName}" builder.`);
|
|
78
|
+
}
|
|
70
79
|
return (0, rxjs_1.defer)(() => Promise.resolve().then(() => __importStar(require('./vite-server')))).pipe((0, rxjs_1.switchMap)(({ serveWithVite }) => serveWithVite(normalizedOptions, builderName, context, transforms, extensions)));
|
|
71
80
|
}
|
|
72
81
|
// Warn if the initial options provided by the user enable prebundling with Webpack-based builders
|
|
@@ -74,10 +83,10 @@ function execute(options, context, transforms = {}, extensions) {
|
|
|
74
83
|
context.logger.warn(`Prebundling has been configured but will not be used because it is not supported by the "${builderName}" builder.`);
|
|
75
84
|
}
|
|
76
85
|
if (extensions?.buildPlugins?.length) {
|
|
77
|
-
throw new Error('Only the
|
|
86
|
+
throw new Error('Only the "application" and "browser-esbuild" builders support plugins.');
|
|
78
87
|
}
|
|
79
88
|
if (extensions?.middleware?.length) {
|
|
80
|
-
throw new Error('Only the
|
|
89
|
+
throw new Error('Only the "application" and "browser-esbuild" builders support middleware.');
|
|
81
90
|
}
|
|
82
91
|
// Use Webpack for all other browser targets
|
|
83
92
|
return (0, rxjs_1.defer)(() => Promise.resolve().then(() => __importStar(require('./webpack-server')))).pipe((0, rxjs_1.switchMap)(({ serveWebpackBrowser }) => serveWebpackBrowser(normalizedOptions, builderName, context, transforms)));
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export interface Schema {
|
|
5
5
|
/**
|
|
6
|
-
* List of hosts that are allowed to access the dev server.
|
|
6
|
+
* List of hosts that are allowed to access the dev server. This option has no effect when
|
|
7
|
+
* using the 'application' or other esbuild-based builders.
|
|
7
8
|
*/
|
|
8
9
|
allowedHosts?: string[];
|
|
9
10
|
/**
|
|
@@ -20,7 +21,8 @@ export interface Schema {
|
|
|
20
21
|
*/
|
|
21
22
|
buildTarget?: string;
|
|
22
23
|
/**
|
|
23
|
-
* Don't verify connected clients are part of allowed hosts.
|
|
24
|
+
* Don't verify connected clients are part of allowed hosts. This option has no effect when
|
|
25
|
+
* using the 'application' or other esbuild-based builders.
|
|
24
26
|
*/
|
|
25
27
|
disableHostCheck?: boolean;
|
|
26
28
|
/**
|
|
@@ -72,7 +74,8 @@ export interface Schema {
|
|
|
72
74
|
/**
|
|
73
75
|
* The URL that the browser client (or live-reload client, if enabled) should use to connect
|
|
74
76
|
* to the development server. Use for a complex dev server setup, such as one with reverse
|
|
75
|
-
* proxies.
|
|
77
|
+
* proxies. This option has no effect when using the 'application' or other esbuild-based
|
|
78
|
+
* builders.
|
|
76
79
|
*/
|
|
77
80
|
publicHost?: string;
|
|
78
81
|
/**
|
|
@@ -69,11 +69,11 @@
|
|
|
69
69
|
},
|
|
70
70
|
"publicHost": {
|
|
71
71
|
"type": "string",
|
|
72
|
-
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies."
|
|
72
|
+
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies. This option has no effect when using the 'application' or other esbuild-based builders."
|
|
73
73
|
},
|
|
74
74
|
"allowedHosts": {
|
|
75
75
|
"type": "array",
|
|
76
|
-
"description": "List of hosts that are allowed to access the dev server.",
|
|
76
|
+
"description": "List of hosts that are allowed to access the dev server. This option has no effect when using the 'application' or other esbuild-based builders.",
|
|
77
77
|
"default": [],
|
|
78
78
|
"items": {
|
|
79
79
|
"type": "string"
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"disableHostCheck": {
|
|
87
87
|
"type": "boolean",
|
|
88
|
-
"description": "Don't verify connected clients are part of allowed hosts.",
|
|
88
|
+
"description": "Don't verify connected clients are part of allowed hosts. This option has no effect when using the 'application' or other esbuild-based builders.",
|
|
89
89
|
"default": false
|
|
90
90
|
},
|
|
91
91
|
"hmr": {
|
|
@@ -45,6 +45,10 @@ function createAngularCompilerHost(compilerOptions, hostOptions) {
|
|
|
45
45
|
if (context.type !== 'style') {
|
|
46
46
|
return null;
|
|
47
47
|
}
|
|
48
|
+
// No transformation required if the resource is empty
|
|
49
|
+
if (data.trim().length === 0) {
|
|
50
|
+
return { content: '' };
|
|
51
|
+
}
|
|
48
52
|
const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined);
|
|
49
53
|
return typeof result === 'string' ? { content: result } : null;
|
|
50
54
|
};
|
|
@@ -307,8 +307,11 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
307
307
|
}
|
|
308
308
|
// Combine additional metafiles with main metafile
|
|
309
309
|
if (result.metafile && metafile) {
|
|
310
|
-
|
|
311
|
-
|
|
310
|
+
// Append the existing object, by appending to it we prevent unnecessary new objections creations with spread
|
|
311
|
+
// mitigating significant performance overhead for large apps.
|
|
312
|
+
// See: https://bugs.chromium.org/p/v8/issues/detail?id=11536
|
|
313
|
+
Object.assign(result.metafile.inputs, metafile.inputs);
|
|
314
|
+
Object.assign(result.metafile.outputs, metafile.outputs);
|
|
312
315
|
}
|
|
313
316
|
}
|
|
314
317
|
(0, profiling_1.logCumulativeDurations)();
|
|
@@ -111,7 +111,7 @@ exports.createBrowserPolyfillBundleOptions = createBrowserPolyfillBundleOptions;
|
|
|
111
111
|
* @returns An esbuild BuildOptions object.
|
|
112
112
|
*/
|
|
113
113
|
function createServerCodeBundleOptions(options, target, sourceFileCache) {
|
|
114
|
-
const {
|
|
114
|
+
const { serverEntryPoint, workspaceRoot, ssrOptions, watch, externalPackages, prerenderOptions } = options;
|
|
115
115
|
(0, node_assert_1.default)(serverEntryPoint, 'createServerCodeBundleOptions should not be called without a defined serverEntryPoint.');
|
|
116
116
|
const { pluginOptions, styleOptions } = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, target, sourceFileCache);
|
|
117
117
|
const mainServerNamespace = 'angular:server-render-utils';
|
|
@@ -85,8 +85,8 @@ class BundlerContext {
|
|
|
85
85
|
}
|
|
86
86
|
// Combine metafiles used for the stats option as well as bundle budgets and console output
|
|
87
87
|
if (result.metafile) {
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
Object.assign(metafile.inputs, result.metafile.inputs);
|
|
89
|
+
Object.assign(metafile.outputs, result.metafile.outputs);
|
|
90
90
|
}
|
|
91
91
|
result.initialFiles.forEach((value, key) => initialFiles.set(key, value));
|
|
92
92
|
outputFiles.push(...result.outputFiles);
|
|
@@ -35,10 +35,12 @@ export declare class ExecutionResult {
|
|
|
35
35
|
errors: (Message | PartialMessage)[];
|
|
36
36
|
prerenderedRoutes: string[];
|
|
37
37
|
warnings: (Message | PartialMessage)[];
|
|
38
|
+
logs: string[];
|
|
38
39
|
externalMetadata?: ExternalResultMetadata;
|
|
39
40
|
constructor(rebuildContexts: BundlerContext[], codeBundleCache?: SourceFileCache | undefined);
|
|
40
41
|
addOutputFile(path: string, content: string, type: BuildOutputFileType): void;
|
|
41
42
|
addAssets(assets: BuildOutputAsset[]): void;
|
|
43
|
+
addLog(value: string): void;
|
|
42
44
|
addError(error: PartialMessage | string): void;
|
|
43
45
|
addErrors(errors: (PartialMessage | string)[]): void;
|
|
44
46
|
addPrerenderedRoutes(routes: string[]): void;
|
|
@@ -21,6 +21,7 @@ class ExecutionResult {
|
|
|
21
21
|
errors = [];
|
|
22
22
|
prerenderedRoutes = [];
|
|
23
23
|
warnings = [];
|
|
24
|
+
logs = [];
|
|
24
25
|
externalMetadata;
|
|
25
26
|
constructor(rebuildContexts, codeBundleCache) {
|
|
26
27
|
this.rebuildContexts = rebuildContexts;
|
|
@@ -32,6 +33,9 @@ class ExecutionResult {
|
|
|
32
33
|
addAssets(assets) {
|
|
33
34
|
this.assetFiles.push(...assets);
|
|
34
35
|
}
|
|
36
|
+
addLog(value) {
|
|
37
|
+
this.logs.push(value);
|
|
38
|
+
}
|
|
35
39
|
addError(error) {
|
|
36
40
|
if (typeof error === 'string') {
|
|
37
41
|
this.errors.push({ text: error, location: null });
|
|
@@ -22,7 +22,7 @@ export declare function withNoProgress<T>(text: string, action: () => T | Promis
|
|
|
22
22
|
* @returns An object that can be used with the esbuild build `supported` option.
|
|
23
23
|
*/
|
|
24
24
|
export declare function getFeatureSupport(target: string[]): BuildOptions['supported'];
|
|
25
|
-
export declare function writeResultFiles(outputFiles: BuildOutputFile[], assetFiles: BuildOutputAsset[] | undefined, { base, browser,
|
|
25
|
+
export declare function writeResultFiles(outputFiles: BuildOutputFile[], assetFiles: BuildOutputAsset[] | undefined, { base, browser, server }: NormalizedOutputOptions): Promise<void>;
|
|
26
26
|
export declare function emitFilesToDisk<T = BuildOutputAsset | BuildOutputFile>(files: T[], writeFileCallback: (file: T) => Promise<void>): Promise<void>;
|
|
27
27
|
export declare function createOutputFileFromText(path: string, text: string, type: BuildOutputFileType): BuildOutputFile;
|
|
28
28
|
export declare function createOutputFileFromData(path: string, data: Uint8Array, type: BuildOutputFileType): BuildOutputFile;
|
|
@@ -37,4 +37,5 @@ export declare function transformSupportedBrowsersToTargets(supportedBrowsers: s
|
|
|
37
37
|
* @see https://esbuild.github.io/api/#target
|
|
38
38
|
*/
|
|
39
39
|
export declare function getSupportedNodeTargets(): string[];
|
|
40
|
-
export declare function
|
|
40
|
+
export declare function createJsonBuildManifest(result: ExecutionResult, normalizedOptions: NormalizedApplicationBuildOptions): Promise<string>;
|
|
41
|
+
export declare function logMessages(logger: logging.LoggerApi, executionResult: ExecutionResult, color?: boolean, jsonLogs?: boolean): Promise<void>;
|
|
@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.logMessages = exports.getSupportedNodeTargets = exports.transformSupportedBrowsersToTargets = exports.convertOutputFile = exports.createOutputFileFromData = exports.createOutputFileFromText = exports.emitFilesToDisk = exports.writeResultFiles = exports.getFeatureSupport = exports.withNoProgress = exports.withSpinner = exports.calculateEstimatedTransferSizes = exports.logBuildStats = void 0;
|
|
13
|
+
exports.logMessages = exports.createJsonBuildManifest = exports.getSupportedNodeTargets = exports.transformSupportedBrowsersToTargets = exports.convertOutputFile = exports.createOutputFileFromData = exports.createOutputFileFromText = exports.emitFilesToDisk = exports.writeResultFiles = exports.getFeatureSupport = exports.withNoProgress = exports.withSpinner = exports.calculateEstimatedTransferSizes = exports.logBuildStats = void 0;
|
|
14
14
|
const esbuild_1 = require("esbuild");
|
|
15
15
|
const node_crypto_1 = require("node:crypto");
|
|
16
16
|
const node_fs_1 = require("node:fs");
|
|
@@ -179,7 +179,7 @@ function getFeatureSupport(target) {
|
|
|
179
179
|
return supported;
|
|
180
180
|
}
|
|
181
181
|
exports.getFeatureSupport = getFeatureSupport;
|
|
182
|
-
async function writeResultFiles(outputFiles, assetFiles, { base, browser,
|
|
182
|
+
async function writeResultFiles(outputFiles, assetFiles, { base, browser, server }) {
|
|
183
183
|
const directoryExists = new Set();
|
|
184
184
|
const ensureDirectoryExists = async (destPath) => {
|
|
185
185
|
const basePath = (0, node_path_1.dirname)(destPath);
|
|
@@ -344,33 +344,35 @@ function getSupportedNodeTargets() {
|
|
|
344
344
|
return SUPPORTED_NODE_VERSIONS.split('||').map((v) => 'node' + (0, semver_1.coerce)(v)?.version);
|
|
345
345
|
}
|
|
346
346
|
exports.getSupportedNodeTargets = getSupportedNodeTargets;
|
|
347
|
-
async function
|
|
348
|
-
const { outputOptions: { base, server, browser }, ssrOptions,
|
|
349
|
-
const { warnings, errors, prerenderedRoutes } =
|
|
350
|
-
const
|
|
351
|
-
? await (0, esbuild_1.formatMessages)(
|
|
352
|
-
: []
|
|
353
|
-
|
|
347
|
+
async function createJsonBuildManifest(result, normalizedOptions) {
|
|
348
|
+
const { colors: color, outputOptions: { base, server, browser }, ssrOptions, } = normalizedOptions;
|
|
349
|
+
const { warnings, errors, prerenderedRoutes } = result;
|
|
350
|
+
const manifest = {
|
|
351
|
+
errors: errors.length ? await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color }) : [],
|
|
352
|
+
warnings: warnings.length ? await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color }) : [],
|
|
353
|
+
outputPaths: {
|
|
354
|
+
root: (0, node_url_1.pathToFileURL)(base),
|
|
355
|
+
browser: (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, browser)),
|
|
356
|
+
server: ssrOptions ? (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, server)) : undefined,
|
|
357
|
+
},
|
|
358
|
+
prerenderedRoutes,
|
|
359
|
+
};
|
|
360
|
+
return JSON.stringify(manifest, undefined, 2);
|
|
361
|
+
}
|
|
362
|
+
exports.createJsonBuildManifest = createJsonBuildManifest;
|
|
363
|
+
async function logMessages(logger, executionResult, color, jsonLogs) {
|
|
364
|
+
const { warnings, errors, logs } = executionResult;
|
|
365
|
+
if (logs.length) {
|
|
366
|
+
logger.info(logs.join('\n'));
|
|
367
|
+
}
|
|
354
368
|
if (jsonLogs) {
|
|
355
|
-
// JSON format output
|
|
356
|
-
const manifest = {
|
|
357
|
-
errors: errorMessages,
|
|
358
|
-
warnings: warningMessages,
|
|
359
|
-
outputPaths: {
|
|
360
|
-
root: (0, node_url_1.pathToFileURL)(base),
|
|
361
|
-
browser: (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, browser)),
|
|
362
|
-
server: ssrOptions ? (0, node_url_1.pathToFileURL)((0, node_path_1.join)(base, server)) : undefined,
|
|
363
|
-
},
|
|
364
|
-
prerenderedRoutes,
|
|
365
|
-
};
|
|
366
|
-
logger.info(JSON.stringify(manifest, undefined, 2));
|
|
367
369
|
return;
|
|
368
370
|
}
|
|
369
|
-
if (
|
|
370
|
-
logger.warn(
|
|
371
|
+
if (warnings.length) {
|
|
372
|
+
logger.warn((await (0, esbuild_1.formatMessages)(warnings, { kind: 'warning', color })).join('\n'));
|
|
371
373
|
}
|
|
372
|
-
if (
|
|
373
|
-
logger.error(
|
|
374
|
+
if (errors.length) {
|
|
375
|
+
logger.error((await (0, esbuild_1.formatMessages)(errors, { kind: 'error', color })).join('\n'));
|
|
374
376
|
}
|
|
375
377
|
}
|
|
376
378
|
exports.logMessages = logMessages;
|
|
@@ -0,0 +1,10 @@
|
|
|
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 { MainServerBundleExports, RenderUtilsServerBundleExports } from './main-bundle-exports';
|
|
9
|
+
export declare function loadEsmModuleFromMemory(path: './main.server.mjs'): Promise<MainServerBundleExports>;
|
|
10
|
+
export declare function loadEsmModuleFromMemory(path: './render-utils.server.mjs'): Promise<RenderUtilsServerBundleExports>;
|
|
@@ -0,0 +1,26 @@
|
|
|
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.loadEsmModuleFromMemory = void 0;
|
|
11
|
+
const error_1 = require("../error");
|
|
12
|
+
const load_esm_1 = require("../load-esm");
|
|
13
|
+
function loadEsmModuleFromMemory(path) {
|
|
14
|
+
return (0, load_esm_1.loadEsmModule)(new URL(path, 'memory://')).catch((e) => {
|
|
15
|
+
(0, error_1.assertIsError)(e);
|
|
16
|
+
// While the error is an 'instanceof Error', it is extended with non transferable properties
|
|
17
|
+
// and cannot be transferred from a worker when using `--import`. This results in the error object
|
|
18
|
+
// displaying as '[Object object]' when read outside of the worker. Therefore, we reconstruct the error message here.
|
|
19
|
+
const error = new Error(e.message);
|
|
20
|
+
error.stack = e.stack;
|
|
21
|
+
error.name = e.name;
|
|
22
|
+
error.code = e.code;
|
|
23
|
+
throw error;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
exports.loadEsmModuleFromMemory = loadEsmModuleFromMemory;
|
|
@@ -36,11 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.renderPage = void 0;
|
|
37
37
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
38
38
|
const node_path_1 = require("node:path");
|
|
39
|
-
const
|
|
39
|
+
const load_esm_from_memory_1 = require("./load-esm-from-memory");
|
|
40
40
|
/**
|
|
41
41
|
* Renders each route in routes and writes them to <outputPath>/<route>/index.html.
|
|
42
42
|
*/
|
|
43
|
-
async function renderPage({ route, serverContext, document, inlineCriticalCss, outputFiles, loadBundle =
|
|
43
|
+
async function renderPage({ route, serverContext, document, inlineCriticalCss, outputFiles, loadBundle = load_esm_from_memory_1.loadEsmModuleFromMemory, }) {
|
|
44
44
|
const { default: bootstrapAppFnOrModule } = await loadBundle('./main.server.mjs');
|
|
45
45
|
const { ɵSERVER_CONTEXT, renderModule, renderApplication, ɵresetCompiledComponents, ɵConsole } = await loadBundle('./render-utils.server.mjs');
|
|
46
46
|
// Need to clean up GENERATED_COMP_IDS map in `@angular/core`.
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
const node_worker_threads_1 = require("node:worker_threads");
|
|
11
|
-
const load_esm_1 = require("../load-esm");
|
|
12
11
|
const fetch_patch_1 = require("./fetch-patch");
|
|
13
12
|
const render_page_1 = require("./render-page");
|
|
14
13
|
/**
|
|
@@ -22,7 +21,6 @@ function render(options) {
|
|
|
22
21
|
outputFiles,
|
|
23
22
|
document,
|
|
24
23
|
inlineCriticalCss,
|
|
25
|
-
loadBundle: async (path) => await (0, load_esm_1.loadEsmModule)(new URL(path, 'memory://')),
|
|
26
24
|
});
|
|
27
25
|
}
|
|
28
26
|
function initialize() {
|
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
const node_worker_threads_1 = require("node:worker_threads");
|
|
11
|
-
const load_esm_1 = require("../load-esm");
|
|
12
11
|
const fetch_patch_1 = require("./fetch-patch");
|
|
12
|
+
const load_esm_from_memory_1 = require("./load-esm-from-memory");
|
|
13
13
|
/**
|
|
14
14
|
* This is passed as workerData when setting up the worker via the `piscina` package.
|
|
15
15
|
*/
|
|
16
16
|
const { document, verbose } = node_worker_threads_1.workerData;
|
|
17
17
|
/** Renders an application based on a provided options. */
|
|
18
18
|
async function extractRoutes() {
|
|
19
|
-
const { extractRoutes } = await (0,
|
|
20
|
-
const { default: bootstrapAppFnOrModule } = await (0,
|
|
19
|
+
const { extractRoutes } = await (0, load_esm_from_memory_1.loadEsmModuleFromMemory)('./render-utils.server.mjs');
|
|
20
|
+
const { default: bootstrapAppFnOrModule } = await (0, load_esm_from_memory_1.loadEsmModuleFromMemory)('./main.server.mjs');
|
|
21
21
|
const skippedRedirects = [];
|
|
22
22
|
const skippedOthers = [];
|
|
23
23
|
const routes = [];
|