@angular/build 19.0.0-next.2 → 19.0.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -10
- package/src/builders/application/execute-post-bundle.js +29 -18
- package/src/builders/application/i18n.js +2 -11
- package/src/builders/application/options.d.ts +11 -0
- package/src/builders/application/options.js +23 -1
- package/src/builders/application/setup-bundling.js +7 -7
- 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 +2 -1
- package/src/builders/dev-server/vite-server.js +13 -2
- package/src/tools/esbuild/angular/file-reference-tracker.d.ts +1 -1
- package/src/tools/esbuild/application-code-bundle.d.ts +1 -6
- package/src/tools/esbuild/application-code-bundle.js +105 -70
- package/src/tools/esbuild/bundler-context.js +14 -10
- package/src/tools/esbuild/cache.d.ts +1 -1
- package/src/tools/esbuild/utils.d.ts +9 -0
- package/src/tools/esbuild/utils.js +14 -0
- package/src/tools/sass/sass-service.js +9 -4
- package/src/tools/vite/angular-memory-plugin.js +2 -2
- package/src/tools/vite/middlewares/ssr-middleware.d.ts +1 -4
- package/src/tools/vite/middlewares/ssr-middleware.js +25 -38
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/fetch-patch.js +4 -5
- package/src/utils/server-rendering/load-esm-from-memory.d.ts +12 -2
- package/src/utils/server-rendering/manifest.d.ts +44 -0
- package/src/utils/server-rendering/manifest.js +88 -0
- package/src/utils/server-rendering/prerender.d.ts +22 -2
- package/src/utils/server-rendering/prerender.js +51 -40
- package/src/utils/server-rendering/render-worker.d.ts +7 -8
- package/src/utils/server-rendering/render-worker.js +10 -13
- package/src/utils/server-rendering/routes-extractor-worker.d.ts +2 -6
- package/src/utils/server-rendering/routes-extractor-worker.js +3 -34
- package/src/utils/server-rendering/main-bundle-exports.d.ts +0 -27
- package/src/utils/server-rendering/main-bundle-exports.js +0 -9
- package/src/utils/server-rendering/render-page.d.ts +0 -26
- package/src/utils/server-rendering/render-page.js +0 -114
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "19.0.0-next.
|
|
3
|
+
"version": "19.0.0-next.3",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"builders": "builders.json",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ampproject/remapping": "2.3.0",
|
|
26
|
-
"@angular-devkit/architect": "0.1900.0-next.
|
|
26
|
+
"@angular-devkit/architect": "0.1900.0-next.3",
|
|
27
27
|
"@babel/core": "7.25.2",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.24.7",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
30
|
-
"@babel/plugin-syntax-import-attributes": "7.
|
|
31
|
-
"@inquirer/confirm": "3.
|
|
30
|
+
"@babel/plugin-syntax-import-attributes": "7.25.6",
|
|
31
|
+
"@inquirer/confirm": "3.2.0",
|
|
32
32
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
33
33
|
"browserslist": "^4.23.0",
|
|
34
34
|
"critters": "0.0.24",
|
|
@@ -36,16 +36,16 @@
|
|
|
36
36
|
"fast-glob": "3.3.2",
|
|
37
37
|
"https-proxy-agent": "7.0.5",
|
|
38
38
|
"listr2": "8.2.4",
|
|
39
|
-
"lmdb": "3.0
|
|
39
|
+
"lmdb": "3.1.0",
|
|
40
40
|
"magic-string": "0.30.11",
|
|
41
41
|
"mrmime": "2.0.0",
|
|
42
42
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
43
43
|
"picomatch": "4.0.2",
|
|
44
44
|
"piscina": "4.6.1",
|
|
45
|
-
"rollup": "4.21.
|
|
46
|
-
"sass": "1.
|
|
45
|
+
"rollup": "4.21.2",
|
|
46
|
+
"sass": "1.78.0",
|
|
47
47
|
"semver": "7.6.3",
|
|
48
|
-
"vite": "5.4.
|
|
48
|
+
"vite": "5.4.3",
|
|
49
49
|
"watchpack": "2.4.2"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"@angular/localize": "^19.0.0-next.0",
|
|
54
54
|
"@angular/platform-server": "^19.0.0-next.0",
|
|
55
55
|
"@angular/service-worker": "^19.0.0-next.0",
|
|
56
|
-
"@angular/ssr": "^19.0.0-next.
|
|
56
|
+
"@angular/ssr": "^19.0.0-next.3",
|
|
57
57
|
"less": "^4.2.0",
|
|
58
58
|
"postcss": "^8.4.0",
|
|
59
59
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
60
|
-
"typescript": ">=5.
|
|
60
|
+
"typescript": ">=5.5 <5.7"
|
|
61
61
|
},
|
|
62
62
|
"peerDependenciesMeta": {
|
|
63
63
|
"@angular/localize": {
|
|
@@ -16,8 +16,10 @@ const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
|
16
16
|
const index_html_generator_1 = require("../../tools/esbuild/index-html-generator");
|
|
17
17
|
const utils_1 = require("../../tools/esbuild/utils");
|
|
18
18
|
const environment_options_1 = require("../../utils/environment-options");
|
|
19
|
+
const manifest_1 = require("../../utils/server-rendering/manifest");
|
|
19
20
|
const prerender_1 = require("../../utils/server-rendering/prerender");
|
|
20
21
|
const service_worker_1 = require("../../utils/service-worker");
|
|
22
|
+
const options_1 = require("./options");
|
|
21
23
|
/**
|
|
22
24
|
* Run additional builds steps including SSG, AppShell, Index HTML file and Service worker generation.
|
|
23
25
|
* @param options The normalized application builder options used to create the build.
|
|
@@ -32,15 +34,11 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
|
|
|
32
34
|
const allErrors = [];
|
|
33
35
|
const allWarnings = [];
|
|
34
36
|
const prerenderedRoutes = [];
|
|
35
|
-
const { serviceWorker, indexHtmlOptions, optimizationOptions, sourcemapOptions, prerenderOptions, appShellOptions, workspaceRoot, verbose, } = options;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*/
|
|
41
|
-
let ssrIndexContent;
|
|
42
|
-
// When using prerender/app-shell the index HTML file can be regenerated.
|
|
43
|
-
// Thus, we use a Map so that we do not generate 2 files with the same filename.
|
|
37
|
+
const { baseHref = '/', serviceWorker, indexHtmlOptions, optimizationOptions, sourcemapOptions, ssrOptions, prerenderOptions, appShellOptions, workspaceRoot, verbose, } = options;
|
|
38
|
+
// Index HTML content without CSS inlining to be used for server rendering (AppShell, SSG and SSR).
|
|
39
|
+
// NOTE: Critical CSS inlining is deliberately omitted here, as it will be handled during server rendering.
|
|
40
|
+
// Additionally, when using prerendering or AppShell, the index HTML file may be regenerated.
|
|
41
|
+
// To prevent generating duplicate files with the same filename, a `Map` is used to store and manage the files.
|
|
44
42
|
const additionalHtmlOutputFiles = new Map();
|
|
45
43
|
// Generate index HTML file
|
|
46
44
|
// If localization is enabled, index generation is handled in the inlining process.
|
|
@@ -50,21 +48,34 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
|
|
|
50
48
|
allWarnings.push(...warnings);
|
|
51
49
|
additionalHtmlOutputFiles.set(indexHtmlOptions.output, (0, utils_1.createOutputFile)(indexHtmlOptions.output, csrContent, bundler_context_1.BuildOutputFileType.Browser));
|
|
52
50
|
if (ssrContent) {
|
|
53
|
-
|
|
54
|
-
additionalHtmlOutputFiles.set(serverIndexHtmlFilename, (0, utils_1.createOutputFile)(serverIndexHtmlFilename, ssrContent, bundler_context_1.BuildOutputFileType.Server));
|
|
55
|
-
ssrIndexContent = ssrContent;
|
|
51
|
+
additionalHtmlOutputFiles.set(options_1.INDEX_HTML_SERVER, (0, utils_1.createOutputFile)(options_1.INDEX_HTML_SERVER, ssrContent, bundler_context_1.BuildOutputFileType.Server));
|
|
56
52
|
}
|
|
57
53
|
}
|
|
54
|
+
// Create server manifest
|
|
55
|
+
if (prerenderOptions || appShellOptions || ssrOptions) {
|
|
56
|
+
additionalOutputFiles.push((0, utils_1.createOutputFile)(manifest_1.SERVER_APP_MANIFEST_FILENAME, (0, manifest_1.generateAngularServerAppManifest)(additionalHtmlOutputFiles, outputFiles, optimizationOptions.styles.inlineCritical ?? false, undefined), bundler_context_1.BuildOutputFileType.Server));
|
|
57
|
+
}
|
|
58
58
|
// Pre-render (SSG) and App-shell
|
|
59
59
|
// If localization is enabled, prerendering is handled in the inlining process.
|
|
60
|
-
if (prerenderOptions || appShellOptions) {
|
|
61
|
-
(0, node_assert_1.default)(
|
|
62
|
-
const { output, warnings, errors, prerenderedRoutes: generatedRoutes, } = await (0, prerender_1.prerenderPages)(workspaceRoot, appShellOptions, prerenderOptions, outputFiles,
|
|
60
|
+
if ((prerenderOptions || appShellOptions) && !allErrors.length) {
|
|
61
|
+
(0, node_assert_1.default)(indexHtmlOptions, 'The "index" option is required when using the "ssg" or "appShell" options.');
|
|
62
|
+
const { output, warnings, errors, prerenderedRoutes: generatedRoutes, serializableRouteTreeNode, } = await (0, prerender_1.prerenderPages)(workspaceRoot, baseHref, appShellOptions, prerenderOptions, [...outputFiles, ...additionalOutputFiles], assetFiles, sourcemapOptions.scripts, environment_options_1.maxWorkers, verbose);
|
|
63
63
|
allErrors.push(...errors);
|
|
64
64
|
allWarnings.push(...warnings);
|
|
65
65
|
prerenderedRoutes.push(...Array.from(generatedRoutes));
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
const indexHasBeenPrerendered = generatedRoutes.has(indexHtmlOptions.output);
|
|
67
|
+
for (const [path, { content, appShellRoute }] of Object.entries(output)) {
|
|
68
|
+
// Update the index contents with the app shell under these conditions:
|
|
69
|
+
// - Replace 'index.html' with the app shell only if it hasn't been prerendered yet.
|
|
70
|
+
// - Always replace 'index.csr.html' with the app shell.
|
|
71
|
+
const filePath = appShellRoute && !indexHasBeenPrerendered ? indexHtmlOptions.output : path;
|
|
72
|
+
additionalHtmlOutputFiles.set(filePath, (0, utils_1.createOutputFile)(filePath, content, bundler_context_1.BuildOutputFileType.Browser));
|
|
73
|
+
}
|
|
74
|
+
if (ssrOptions) {
|
|
75
|
+
// Regenerate the manifest to append route tree. This is only needed if SSR is enabled.
|
|
76
|
+
const manifest = additionalOutputFiles.find((f) => f.path === manifest_1.SERVER_APP_MANIFEST_FILENAME);
|
|
77
|
+
(0, node_assert_1.default)(manifest, `${manifest_1.SERVER_APP_MANIFEST_FILENAME} was not found in output files.`);
|
|
78
|
+
manifest.contents = new TextEncoder().encode((0, manifest_1.generateAngularServerAppManifest)(additionalHtmlOutputFiles, outputFiles, optimizationOptions.styles.inlineCritical ?? false, serializableRouteTreeNode));
|
|
68
79
|
}
|
|
69
80
|
}
|
|
70
81
|
additionalOutputFiles.push(...additionalHtmlOutputFiles.values());
|
|
@@ -72,7 +83,7 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
|
|
|
72
83
|
// If localization is enabled, service worker is handled in the inlining process.
|
|
73
84
|
if (serviceWorker) {
|
|
74
85
|
try {
|
|
75
|
-
const serviceWorkerResult = await (0, service_worker_1.augmentAppWithServiceWorkerEsbuild)(workspaceRoot, serviceWorker,
|
|
86
|
+
const serviceWorkerResult = await (0, service_worker_1.augmentAppWithServiceWorkerEsbuild)(workspaceRoot, serviceWorker, baseHref, options.indexHtmlOptions?.output,
|
|
76
87
|
// Ensure additional files recently added are used
|
|
77
88
|
[...outputFiles, ...additionalOutputFiles], assetFiles);
|
|
78
89
|
additionalOutputFiles.push((0, utils_1.createOutputFile)('ngsw.json', serviceWorkerResult.manifest, bundler_context_1.BuildOutputFileType.Browser));
|
|
@@ -15,8 +15,8 @@ const i18n_inliner_1 = require("../../tools/esbuild/i18n-inliner");
|
|
|
15
15
|
const environment_options_1 = require("../../utils/environment-options");
|
|
16
16
|
const i18n_options_1 = require("../../utils/i18n-options");
|
|
17
17
|
const load_translations_1 = require("../../utils/load-translations");
|
|
18
|
-
const url_1 = require("../../utils/url");
|
|
19
18
|
const execute_post_bundle_1 = require("./execute-post-bundle");
|
|
19
|
+
const options_1 = require("./options");
|
|
20
20
|
/**
|
|
21
21
|
* Inlines all active locales as specified by the application build options into all
|
|
22
22
|
* application JavaScript files created during the build.
|
|
@@ -46,7 +46,7 @@ async function inlineI18n(options, executionResult, initialFiles) {
|
|
|
46
46
|
const localeOutputFiles = localeInlineResult.outputFiles;
|
|
47
47
|
inlineResult.errors.push(...localeInlineResult.errors);
|
|
48
48
|
inlineResult.warnings.push(...localeInlineResult.warnings);
|
|
49
|
-
const baseHref = getLocaleBaseHref(options.baseHref, options.i18nOptions, locale) ?? options.baseHref;
|
|
49
|
+
const baseHref = (0, options_1.getLocaleBaseHref)(options.baseHref, options.i18nOptions, locale) ?? options.baseHref;
|
|
50
50
|
const { errors, warnings, additionalAssets, additionalOutputFiles, prerenderedRoutes: generatedRoutes, } = await (0, execute_post_bundle_1.executePostBundleSteps)({
|
|
51
51
|
...options,
|
|
52
52
|
baseHref,
|
|
@@ -90,15 +90,6 @@ async function inlineI18n(options, executionResult, initialFiles) {
|
|
|
90
90
|
}
|
|
91
91
|
return inlineResult;
|
|
92
92
|
}
|
|
93
|
-
function getLocaleBaseHref(baseHref, i18n, locale) {
|
|
94
|
-
if (i18n.flatOutput) {
|
|
95
|
-
return undefined;
|
|
96
|
-
}
|
|
97
|
-
if (i18n.locales[locale] && i18n.locales[locale].baseHref !== '') {
|
|
98
|
-
return (0, url_1.urlJoin)(baseHref || '', i18n.locales[locale].baseHref ?? `/${locale}/`);
|
|
99
|
-
}
|
|
100
|
-
return undefined;
|
|
101
|
-
}
|
|
102
93
|
/**
|
|
103
94
|
* Loads all active translations using the translation loaders from the `@angular/localize` package.
|
|
104
95
|
* @param context The architect builder context for the current build.
|
|
@@ -10,6 +10,16 @@ import type { Plugin } from 'esbuild';
|
|
|
10
10
|
import { I18nOptions } from '../../utils/i18n-options';
|
|
11
11
|
import { IndexHtmlTransform } from '../../utils/index-file/index-html-generator';
|
|
12
12
|
import { Schema as ApplicationBuilderOptions, I18NTranslation, OutputPathClass } from './schema';
|
|
13
|
+
/**
|
|
14
|
+
* The filename for the client-side rendered HTML template.
|
|
15
|
+
* This template is used for client-side rendering (CSR) in a web application.
|
|
16
|
+
*/
|
|
17
|
+
export declare const INDEX_HTML_CSR = "index.csr.html";
|
|
18
|
+
/**
|
|
19
|
+
* The filename for the server-side rendered HTML template.
|
|
20
|
+
* This template is used for server-side rendering (SSR) in a web application.
|
|
21
|
+
*/
|
|
22
|
+
export declare const INDEX_HTML_SERVER = "index.server.html";
|
|
13
23
|
export type NormalizedOutputOptions = Required<OutputPathClass> & {
|
|
14
24
|
clean: boolean;
|
|
15
25
|
ignoreServer: boolean;
|
|
@@ -148,4 +158,5 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
|
|
|
148
158
|
[key: string]: string;
|
|
149
159
|
} | undefined;
|
|
150
160
|
}>;
|
|
161
|
+
export declare function getLocaleBaseHref(baseHref: string | undefined, i18n: NormalizedApplicationBuildOptions['i18nOptions'], locale: string): string | undefined;
|
|
151
162
|
export {};
|
|
@@ -10,7 +10,9 @@ 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.INDEX_HTML_SERVER = exports.INDEX_HTML_CSR = void 0;
|
|
13
14
|
exports.normalizeOptions = normalizeOptions;
|
|
15
|
+
exports.getLocaleBaseHref = getLocaleBaseHref;
|
|
14
16
|
const node_fs_1 = require("node:fs");
|
|
15
17
|
const promises_1 = require("node:fs/promises");
|
|
16
18
|
const node_module_1 = require("node:module");
|
|
@@ -21,7 +23,18 @@ const environment_options_1 = require("../../utils/environment-options");
|
|
|
21
23
|
const i18n_options_1 = require("../../utils/i18n-options");
|
|
22
24
|
const normalize_cache_1 = require("../../utils/normalize-cache");
|
|
23
25
|
const postcss_configuration_1 = require("../../utils/postcss-configuration");
|
|
26
|
+
const url_1 = require("../../utils/url");
|
|
24
27
|
const schema_1 = require("./schema");
|
|
28
|
+
/**
|
|
29
|
+
* The filename for the client-side rendered HTML template.
|
|
30
|
+
* This template is used for client-side rendering (CSR) in a web application.
|
|
31
|
+
*/
|
|
32
|
+
exports.INDEX_HTML_CSR = 'index.csr.html';
|
|
33
|
+
/**
|
|
34
|
+
* The filename for the server-side rendered HTML template.
|
|
35
|
+
* This template is used for server-side rendering (SSR) in a web application.
|
|
36
|
+
*/
|
|
37
|
+
exports.INDEX_HTML_SERVER = 'index.server.html';
|
|
25
38
|
/**
|
|
26
39
|
* Normalize the user provided options by creating full paths for all path based options
|
|
27
40
|
* and converting multi-form options into a single form that can be directly used
|
|
@@ -164,7 +177,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
|
|
|
164
177
|
* For instance, accessing `foo.com/` would lead to `foo.com/index.html` being served instead of hitting the server.
|
|
165
178
|
*/
|
|
166
179
|
const indexBaseName = node_path_1.default.basename(options.index);
|
|
167
|
-
indexOutput = ssrOptions && indexBaseName === 'index.html' ?
|
|
180
|
+
indexOutput = ssrOptions && indexBaseName === 'index.html' ? exports.INDEX_HTML_CSR : indexBaseName;
|
|
168
181
|
}
|
|
169
182
|
else {
|
|
170
183
|
indexOutput = options.index.output || 'index.html';
|
|
@@ -369,3 +382,12 @@ function normalizeGlobalEntries(rawEntries, defaultName) {
|
|
|
369
382
|
}
|
|
370
383
|
return [...bundles.values()];
|
|
371
384
|
}
|
|
385
|
+
function getLocaleBaseHref(baseHref, i18n, locale) {
|
|
386
|
+
if (i18n.flatOutput) {
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
if (i18n.locales[locale] && i18n.locales[locale].baseHref !== '') {
|
|
390
|
+
return (0, url_1.urlJoin)(baseHref || '', i18n.locales[locale].baseHref ?? `/${locale}/`);
|
|
391
|
+
}
|
|
392
|
+
return undefined;
|
|
393
|
+
}
|
|
@@ -22,22 +22,22 @@ const utils_1 = require("../../tools/esbuild/utils");
|
|
|
22
22
|
* @returns An array of BundlerContext objects.
|
|
23
23
|
*/
|
|
24
24
|
function setupBundlerContexts(options, browsers, codeBundleCache) {
|
|
25
|
-
const { appShellOptions, prerenderOptions, serverEntryPoint, ssrOptions, workspaceRoot } = options;
|
|
25
|
+
const { appShellOptions, prerenderOptions, serverEntryPoint, ssrOptions, workspaceRoot, watch = false, } = options;
|
|
26
26
|
const target = (0, utils_1.transformSupportedBrowsersToTargets)(browsers);
|
|
27
27
|
const bundlerContexts = [];
|
|
28
28
|
// Browser application code
|
|
29
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot,
|
|
29
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createBrowserCodeBundleOptions)(options, target, codeBundleCache)));
|
|
30
30
|
// Browser polyfills code
|
|
31
31
|
const browserPolyfillBundleOptions = (0, application_code_bundle_1.createBrowserPolyfillBundleOptions)(options, target, codeBundleCache);
|
|
32
32
|
if (browserPolyfillBundleOptions) {
|
|
33
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot,
|
|
33
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, browserPolyfillBundleOptions));
|
|
34
34
|
}
|
|
35
35
|
// Global Stylesheets
|
|
36
36
|
if (options.globalStyles.length > 0) {
|
|
37
37
|
for (const initial of [true, false]) {
|
|
38
38
|
const bundleOptions = (0, global_styles_1.createGlobalStylesBundleOptions)(options, target, initial);
|
|
39
39
|
if (bundleOptions) {
|
|
40
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot,
|
|
40
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, bundleOptions, () => initial));
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -46,7 +46,7 @@ function setupBundlerContexts(options, browsers, codeBundleCache) {
|
|
|
46
46
|
for (const initial of [true, false]) {
|
|
47
47
|
const bundleOptions = (0, global_scripts_1.createGlobalScriptsBundleOptions)(options, target, initial);
|
|
48
48
|
if (bundleOptions) {
|
|
49
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot,
|
|
49
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, bundleOptions, () => initial));
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -54,11 +54,11 @@ function setupBundlerContexts(options, browsers, codeBundleCache) {
|
|
|
54
54
|
if (serverEntryPoint && (prerenderOptions || appShellOptions || ssrOptions)) {
|
|
55
55
|
const nodeTargets = [...target, ...(0, utils_1.getSupportedNodeTargets)()];
|
|
56
56
|
// Server application code
|
|
57
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot,
|
|
57
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, (0, application_code_bundle_1.createServerMainCodeBundleOptions)(options, nodeTargets, codeBundleCache)));
|
|
58
58
|
// Server polyfills code
|
|
59
59
|
const serverPolyfillBundleOptions = (0, application_code_bundle_1.createServerPolyfillBundleOptions)(options, nodeTargets, codeBundleCache);
|
|
60
60
|
if (serverPolyfillBundleOptions) {
|
|
61
|
-
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot,
|
|
61
|
+
bundlerContexts.push(new bundler_context_1.BundlerContext(workspaceRoot, watch, serverPolyfillBundleOptions));
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
return bundlerContexts;
|
|
@@ -9,7 +9,6 @@ export { type BuildOutputFile, BuildOutputFileType } from '@angular/build';
|
|
|
9
9
|
export { createRxjsEsmResolutionPlugin } from '../../tools/esbuild/rxjs-esm-resolution-plugin';
|
|
10
10
|
export { JavaScriptTransformer } from '../../tools/esbuild/javascript-transformer';
|
|
11
11
|
export { getFeatureSupport, isZonelessApp } from '../../tools/esbuild/utils';
|
|
12
|
-
export { renderPage } from '../../utils/server-rendering/render-page';
|
|
13
12
|
export { type IndexHtmlTransform } from '../../utils/index-file/index-html-generator';
|
|
14
13
|
export { purgeStaleBuildCache } from '../../utils/purge-cache';
|
|
15
14
|
export { getSupportedBrowsers } from '../../utils/supported-browsers';
|
|
@@ -7,7 +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.buildApplicationInternal = exports.transformSupportedBrowsersToTargets = exports.getSupportedBrowsers = exports.purgeStaleBuildCache = exports.
|
|
10
|
+
exports.buildApplicationInternal = exports.transformSupportedBrowsersToTargets = exports.getSupportedBrowsers = exports.purgeStaleBuildCache = exports.isZonelessApp = exports.getFeatureSupport = exports.JavaScriptTransformer = exports.createRxjsEsmResolutionPlugin = exports.BuildOutputFileType = void 0;
|
|
11
11
|
var build_1 = require("@angular/build");
|
|
12
12
|
Object.defineProperty(exports, "BuildOutputFileType", { enumerable: true, get: function () { return build_1.BuildOutputFileType; } });
|
|
13
13
|
var rxjs_esm_resolution_plugin_1 = require("../../tools/esbuild/rxjs-esm-resolution-plugin");
|
|
@@ -17,8 +17,6 @@ Object.defineProperty(exports, "JavaScriptTransformer", { enumerable: true, get:
|
|
|
17
17
|
var utils_1 = require("../../tools/esbuild/utils");
|
|
18
18
|
Object.defineProperty(exports, "getFeatureSupport", { enumerable: true, get: function () { return utils_1.getFeatureSupport; } });
|
|
19
19
|
Object.defineProperty(exports, "isZonelessApp", { enumerable: true, get: function () { return utils_1.isZonelessApp; } });
|
|
20
|
-
var render_page_1 = require("../../utils/server-rendering/render-page");
|
|
21
|
-
Object.defineProperty(exports, "renderPage", { enumerable: true, get: function () { return render_page_1.renderPage; } });
|
|
22
20
|
var purge_cache_1 = require("../../utils/purge-cache");
|
|
23
21
|
Object.defineProperty(exports, "purgeStaleBuildCache", { enumerable: true, get: function () { return purge_cache_1.purgeStaleBuildCache; } });
|
|
24
22
|
var supported_browsers_1 = require("../../utils/supported-browsers");
|
|
@@ -9,7 +9,7 @@ import type { BuilderContext } from '@angular-devkit/architect';
|
|
|
9
9
|
import type { Plugin } from 'esbuild';
|
|
10
10
|
import type { Connect, DepOptimizationConfig, InlineConfig } from 'vite';
|
|
11
11
|
import { Result } from '../application/results';
|
|
12
|
-
import { type ApplicationBuilderInternalOptions, type ExternalResultMetadata, JavaScriptTransformer } from './internal';
|
|
12
|
+
import { type ApplicationBuilderInternalOptions, BuildOutputFileType, type ExternalResultMetadata, JavaScriptTransformer } from './internal';
|
|
13
13
|
import type { NormalizedDevServerOptions } from './options';
|
|
14
14
|
import type { DevServerBuilderOutput } from './output';
|
|
15
15
|
interface OutputFileRecord {
|
|
@@ -18,6 +18,7 @@ interface OutputFileRecord {
|
|
|
18
18
|
hash?: string;
|
|
19
19
|
updated: boolean;
|
|
20
20
|
servable: boolean;
|
|
21
|
+
type: BuildOutputFileType;
|
|
21
22
|
}
|
|
22
23
|
export type BuilderAction = (options: ApplicationBuilderInternalOptions, context: BuilderContext, plugins?: Plugin[]) => AsyncIterable<Result>;
|
|
23
24
|
export declare function serveWithVite(serverOptions: NormalizedDevServerOptions, builderName: string, builderAction: BuilderAction, context: BuilderContext, transformers?: {
|
|
@@ -204,12 +204,14 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
204
204
|
server.config.server.fs.allow = [
|
|
205
205
|
...new Set([...server.config.server.fs.allow, ...assetFiles.values()]),
|
|
206
206
|
];
|
|
207
|
-
handleUpdate(normalizePath, generatedFiles, server, serverOptions, context.logger);
|
|
208
207
|
if (requiresServerRestart) {
|
|
209
208
|
// Restart the server to force SSR dep re-optimization when a dependency has been added.
|
|
210
209
|
// This is a workaround for: https://github.com/vitejs/vite/issues/14896
|
|
211
210
|
await server.restart();
|
|
212
211
|
}
|
|
212
|
+
else {
|
|
213
|
+
await handleUpdate(normalizePath, generatedFiles, server, serverOptions, context.logger);
|
|
214
|
+
}
|
|
213
215
|
}
|
|
214
216
|
else {
|
|
215
217
|
const projectName = context.target?.project;
|
|
@@ -271,12 +273,14 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
271
273
|
}
|
|
272
274
|
await new Promise((resolve) => (deferred = resolve));
|
|
273
275
|
}
|
|
274
|
-
function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logger) {
|
|
276
|
+
async function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logger) {
|
|
275
277
|
const updatedFiles = [];
|
|
278
|
+
let isServerFileUpdated = false;
|
|
276
279
|
// Invalidate any updated files
|
|
277
280
|
for (const [file, record] of generatedFiles) {
|
|
278
281
|
if (record.updated) {
|
|
279
282
|
updatedFiles.push(file);
|
|
283
|
+
isServerFileUpdated ||= record.type === internal_1.BuildOutputFileType.Server;
|
|
280
284
|
const updatedModules = server.moduleGraph.getModulesByFile(normalizePath((0, node_path_1.join)(server.config.root, file)));
|
|
281
285
|
updatedModules?.forEach((m) => server?.moduleGraph.invalidateModule(m));
|
|
282
286
|
}
|
|
@@ -284,6 +288,11 @@ function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logg
|
|
|
284
288
|
if (!updatedFiles.length) {
|
|
285
289
|
return;
|
|
286
290
|
}
|
|
291
|
+
// clean server apps cache
|
|
292
|
+
if (isServerFileUpdated) {
|
|
293
|
+
const { ɵdestroyAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs'));
|
|
294
|
+
ɵdestroyAngularServerApp();
|
|
295
|
+
}
|
|
287
296
|
if (serverOptions.liveReload || serverOptions.hmr) {
|
|
288
297
|
if (updatedFiles.every((f) => f.endsWith('.css'))) {
|
|
289
298
|
const timestamp = Date.now();
|
|
@@ -334,6 +343,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
334
343
|
contents: file.contents,
|
|
335
344
|
servable,
|
|
336
345
|
size: file.contents.byteLength,
|
|
346
|
+
type: file.type,
|
|
337
347
|
updated: false,
|
|
338
348
|
});
|
|
339
349
|
continue;
|
|
@@ -352,6 +362,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
352
362
|
size: file.contents.byteLength,
|
|
353
363
|
hash: file.hash,
|
|
354
364
|
updated: true,
|
|
365
|
+
type: file.type,
|
|
355
366
|
servable,
|
|
356
367
|
});
|
|
357
368
|
}
|
|
@@ -11,10 +11,5 @@ import { SourceFileCache } from './angular/source-file-cache';
|
|
|
11
11
|
import { BundlerOptionsFactory } from './bundler-context';
|
|
12
12
|
export declare function createBrowserCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache?: SourceFileCache): BuildOptions;
|
|
13
13
|
export declare function createBrowserPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache?: SourceFileCache): BuildOptions | BundlerOptionsFactory | undefined;
|
|
14
|
-
/**
|
|
15
|
-
* Create an esbuild 'build' options object for the server bundle.
|
|
16
|
-
* @param options The builder's user-provider normalized options.
|
|
17
|
-
* @returns An esbuild BuildOptions object.
|
|
18
|
-
*/
|
|
19
|
-
export declare function createServerCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache): BuildOptions;
|
|
20
14
|
export declare function createServerPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache?: SourceFileCache): BundlerOptionsFactory | undefined;
|
|
15
|
+
export declare function createServerMainCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache): BuildOptions;
|