@angular/build 19.0.0-rc.1 → 19.0.0-rc.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 +8 -8
- package/src/builders/application/execute-post-bundle.js +3 -15
- package/src/builders/application/options.js +2 -2
- package/src/tools/esbuild/angular/compiler-plugin.js +19 -4
- package/src/tools/sass/rebasing-importer.js +1 -1
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/models.d.ts +1 -0
- package/src/utils/server-rendering/models.js +3 -4
- package/src/utils/server-rendering/prerender.js +18 -18
- package/src/utils/server-rendering/routes-extractor-worker.js +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/build",
|
|
3
|
-
"version": "19.0.0-rc.
|
|
3
|
+
"version": "19.0.0-rc.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-rc.
|
|
26
|
+
"@angular-devkit/architect": "0.1900.0-rc.3",
|
|
27
27
|
"@babel/core": "7.26.0",
|
|
28
28
|
"@babel/helper-annotate-as-pure": "7.25.9",
|
|
29
29
|
"@babel/helper-split-export-declaration": "7.24.7",
|
|
30
30
|
"@babel/plugin-syntax-import-attributes": "7.26.0",
|
|
31
|
-
"@inquirer/confirm": "5.0.
|
|
31
|
+
"@inquirer/confirm": "5.0.2",
|
|
32
32
|
"@vitejs/plugin-basic-ssl": "1.1.0",
|
|
33
33
|
"beasties": "0.1.0",
|
|
34
34
|
"browserslist": "^4.23.0",
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"parse5-html-rewriting-stream": "7.0.0",
|
|
43
43
|
"picomatch": "4.0.2",
|
|
44
44
|
"piscina": "4.7.0",
|
|
45
|
-
"rollup": "4.
|
|
46
|
-
"sass": "1.80.
|
|
45
|
+
"rollup": "4.26.0",
|
|
46
|
+
"sass": "1.80.7",
|
|
47
47
|
"semver": "7.6.3",
|
|
48
|
-
"vite": "5.4.
|
|
48
|
+
"vite": "5.4.11",
|
|
49
49
|
"watchpack": "2.4.2"
|
|
50
50
|
},
|
|
51
51
|
"optionalDependencies": {
|
|
52
|
-
"lmdb": "3.1.
|
|
52
|
+
"lmdb": "3.1.5"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@angular/compiler": "^19.0.0-next.9",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@angular/localize": "^19.0.0-next.9",
|
|
58
58
|
"@angular/platform-server": "^19.0.0-next.9",
|
|
59
59
|
"@angular/service-worker": "^19.0.0-next.9",
|
|
60
|
-
"@angular/ssr": "^19.0.0-rc.
|
|
60
|
+
"@angular/ssr": "^19.0.0-rc.3",
|
|
61
61
|
"less": "^4.2.0",
|
|
62
62
|
"postcss": "^8.4.0",
|
|
63
63
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
@@ -86,21 +86,9 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
|
|
|
86
86
|
}
|
|
87
87
|
const serializableRouteTreeNodeForManifest = [];
|
|
88
88
|
for (const metadata of serializableRouteTreeNode) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!metadata.redirectTo) {
|
|
93
|
-
serializableRouteTreeNodeForManifest.push(metadata);
|
|
94
|
-
if (!metadata.route.includes('*')) {
|
|
95
|
-
prerenderedRoutes[metadata.route] = { headers: metadata.headers };
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
case models_1.RouteRenderMode.Server:
|
|
101
|
-
case models_1.RouteRenderMode.Client:
|
|
102
|
-
serializableRouteTreeNodeForManifest.push(metadata);
|
|
103
|
-
break;
|
|
89
|
+
serializableRouteTreeNodeForManifest.push(metadata);
|
|
90
|
+
if (metadata.renderMode === models_1.RouteRenderMode.Prerender && !metadata.route.includes('*')) {
|
|
91
|
+
prerenderedRoutes[metadata.route] = { headers: metadata.headers };
|
|
104
92
|
}
|
|
105
93
|
}
|
|
106
94
|
if (outputMode === schema_1.OutputMode.Server) {
|
|
@@ -236,7 +236,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
|
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
238
|
// Initial options to keep
|
|
239
|
-
const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, outputMode, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, namedChunks, budgets, deployUrl, clearScreen, define, partialSSRBuild = false, externalRuntimeStyles, instrumentForCoverage, security, } = options;
|
|
239
|
+
const { allowedCommonJsDependencies, aot = true, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, outputMode, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, namedChunks, budgets, deployUrl, clearScreen, define, partialSSRBuild = false, externalRuntimeStyles, instrumentForCoverage, security, } = options;
|
|
240
240
|
// Return all the normalized options
|
|
241
241
|
return {
|
|
242
242
|
advancedOptimizations: !!aot && optimizationOptions.scripts,
|
|
@@ -293,7 +293,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
|
|
|
293
293
|
clearScreen,
|
|
294
294
|
define,
|
|
295
295
|
partialSSRBuild: environment_options_1.usePartialSsrBuild || partialSSRBuild,
|
|
296
|
-
externalRuntimeStyles,
|
|
296
|
+
externalRuntimeStyles: aot && externalRuntimeStyles,
|
|
297
297
|
instrumentForCoverage,
|
|
298
298
|
security,
|
|
299
299
|
templateUpdates: !!options.templateUpdates,
|
|
@@ -119,7 +119,6 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
119
119
|
// dependencies or web worker processing.
|
|
120
120
|
let modifiedFiles;
|
|
121
121
|
if (pluginOptions.sourceFileCache?.modifiedFiles.size &&
|
|
122
|
-
referencedFileTracker &&
|
|
123
122
|
!pluginOptions.noopTypeScriptCompilation) {
|
|
124
123
|
// TODO: Differentiate between changed input files and stale output files
|
|
125
124
|
modifiedFiles = referencedFileTracker.update(pluginOptions.sourceFileCache.modifiedFiles);
|
|
@@ -129,6 +128,8 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
129
128
|
if (!pluginOptions.externalRuntimeStyles) {
|
|
130
129
|
stylesheetBundler.invalidate(modifiedFiles);
|
|
131
130
|
}
|
|
131
|
+
// Remove any stale additional results based on modified files
|
|
132
|
+
modifiedFiles.forEach((file) => additionalResults.delete(file));
|
|
132
133
|
}
|
|
133
134
|
if (!pluginOptions.noopTypeScriptCompilation &&
|
|
134
135
|
compilation.update &&
|
|
@@ -142,6 +143,7 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
142
143
|
sourceFileCache: pluginOptions.sourceFileCache,
|
|
143
144
|
async transformStylesheet(data, containingFile, stylesheetFile, order, className) {
|
|
144
145
|
let stylesheetResult;
|
|
146
|
+
let resultSource = stylesheetFile ?? containingFile;
|
|
145
147
|
// Stylesheet file only exists for external stylesheets
|
|
146
148
|
if (stylesheetFile) {
|
|
147
149
|
stylesheetResult = await stylesheetBundler.bundleFile(stylesheetFile);
|
|
@@ -161,6 +163,11 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
161
163
|
.update(className ?? '')
|
|
162
164
|
.digest('hex')
|
|
163
165
|
: undefined);
|
|
166
|
+
// Adjust result source for inline styles.
|
|
167
|
+
// There may be multiple inline styles with the same containing file and to ensure that the results
|
|
168
|
+
// do not overwrite each other the result source identifier needs to be unique for each. The class
|
|
169
|
+
// name and order fields can be used for this. The structure is arbitrary as long as it is unique.
|
|
170
|
+
resultSource += `?class=${className}&order=${order}`;
|
|
164
171
|
}
|
|
165
172
|
(result.warnings ??= []).push(...stylesheetResult.warnings);
|
|
166
173
|
if (stylesheetResult.errors) {
|
|
@@ -168,7 +175,7 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
168
175
|
return '';
|
|
169
176
|
}
|
|
170
177
|
const { contents, outputFiles, metafile, referencedFiles } = stylesheetResult;
|
|
171
|
-
additionalResults.set(
|
|
178
|
+
additionalResults.set(resultSource, {
|
|
172
179
|
outputFiles,
|
|
173
180
|
metafile,
|
|
174
181
|
});
|
|
@@ -362,12 +369,20 @@ function createCompilerPlugin(pluginOptions, stylesheetBundler) {
|
|
|
362
369
|
};
|
|
363
370
|
});
|
|
364
371
|
build.onLoad({ filter: /\.[cm]?js$/ }, (0, load_result_cache_1.createCachedLoad)(pluginOptions.loadResultCache, async (args) => {
|
|
372
|
+
let request = args.path;
|
|
373
|
+
if (pluginOptions.fileReplacements) {
|
|
374
|
+
const replacement = pluginOptions.fileReplacements[path.normalize(args.path)];
|
|
375
|
+
if (replacement) {
|
|
376
|
+
request = path.normalize(replacement);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
365
379
|
return (0, profiling_1.profileAsync)('NG_EMIT_JS*', async () => {
|
|
366
|
-
const sideEffects = await hasSideEffects(
|
|
367
|
-
const contents = await javascriptTransformer.transformFile(
|
|
380
|
+
const sideEffects = await hasSideEffects(request);
|
|
381
|
+
const contents = await javascriptTransformer.transformFile(request, pluginOptions.jit, sideEffects);
|
|
368
382
|
return {
|
|
369
383
|
contents,
|
|
370
384
|
loader: 'js',
|
|
385
|
+
watchFiles: request !== args.path ? [request] : undefined,
|
|
371
386
|
};
|
|
372
387
|
}, true);
|
|
373
388
|
}));
|
|
@@ -65,7 +65,7 @@ class UrlRebasingImporter {
|
|
|
65
65
|
continue;
|
|
66
66
|
}
|
|
67
67
|
// Sass variable usage either starts with a `$` or contains a namespace and a `.$`
|
|
68
|
-
const valueNormalized = value[0] === '$' || /^\w
|
|
68
|
+
const valueNormalized = value[0] === '$' || /^\w[\w_-]*\.\$/.test(value) ? `#{${value}}` : value;
|
|
69
69
|
const rebasedPath = (0, node_path_1.relative)(this.entryDirectory, stylesheetDirectory);
|
|
70
70
|
// Normalize path separators and escape characters
|
|
71
71
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/url#syntax
|
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.normalizeCacheOptions = normalizeCacheOptions;
|
|
11
11
|
const node_path_1 = require("node:path");
|
|
12
12
|
/** Version placeholder is replaced during the build process with actual package version */
|
|
13
|
-
const VERSION = '19.0.0-rc.
|
|
13
|
+
const VERSION = '19.0.0-rc.3';
|
|
14
14
|
function hasCacheMetadata(value) {
|
|
15
15
|
return (!!value &&
|
|
16
16
|
typeof value === 'object' &&
|
|
@@ -15,6 +15,7 @@ export type SerializableRouteTreeNode = ReturnType<Awaited<ReturnType<typeof ɵe
|
|
|
15
15
|
export type WritableSerializableRouteTreeNode = Writeable<SerializableRouteTreeNode>;
|
|
16
16
|
export interface RoutersExtractorWorkerResult {
|
|
17
17
|
serializedRouteTree: SerializableRouteTreeNode;
|
|
18
|
+
appShellRoute?: string;
|
|
18
19
|
errors: string[];
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
@@ -15,8 +15,7 @@ exports.RouteRenderMode = void 0;
|
|
|
15
15
|
* It maps `RenderMode` enum values to their corresponding numeric identifiers.
|
|
16
16
|
*/
|
|
17
17
|
exports.RouteRenderMode = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Prerender: 3,
|
|
18
|
+
Server: 0,
|
|
19
|
+
Client: 1,
|
|
20
|
+
Prerender: 2,
|
|
22
21
|
};
|
|
@@ -51,12 +51,11 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
|
|
|
51
51
|
assetsReversed[addLeadingSlash(destination.replace(/\\/g, node_path_1.posix.sep))] = source;
|
|
52
52
|
}
|
|
53
53
|
// Get routes to prerender
|
|
54
|
-
const { errors: extractionErrors, serializedRouteTree: serializableRouteTreeNode } = await getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, assetsReversed, appShellOptions, prerenderOptions, sourcemap, outputMode).catch((err) => {
|
|
54
|
+
const { errors: extractionErrors, serializedRouteTree: serializableRouteTreeNode, appShellRoute, } = await getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, assetsReversed, appShellOptions, prerenderOptions, sourcemap, outputMode).catch((err) => {
|
|
55
55
|
return {
|
|
56
|
-
errors: [
|
|
57
|
-
`An error occurred while extracting routes.\n\n${err.stack ?? err.message ?? err}`,
|
|
58
|
-
],
|
|
56
|
+
errors: [`An error occurred while extracting routes.\n\n${err.stack ?? err.message ?? err}`],
|
|
59
57
|
serializedRouteTree: [],
|
|
58
|
+
appShellRoute: undefined,
|
|
60
59
|
};
|
|
61
60
|
});
|
|
62
61
|
errors.push(...extractionErrors);
|
|
@@ -73,7 +72,6 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
|
|
|
73
72
|
switch (metadata.renderMode) {
|
|
74
73
|
case undefined: /* Legacy building mode */
|
|
75
74
|
case models_1.RouteRenderMode.Prerender:
|
|
76
|
-
case models_1.RouteRenderMode.AppShell:
|
|
77
75
|
serializableRouteTreeNodeForPrerender.push(metadata);
|
|
78
76
|
break;
|
|
79
77
|
case models_1.RouteRenderMode.Server:
|
|
@@ -92,7 +90,7 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
|
|
|
92
90
|
};
|
|
93
91
|
}
|
|
94
92
|
// Render routes
|
|
95
|
-
const { errors: renderingErrors, output } = await renderPages(baseHref, sourcemap, serializableRouteTreeNodeForPrerender, maxThreads, workspaceRoot, outputFilesForWorker, assetsReversed, appShellOptions, outputMode);
|
|
93
|
+
const { errors: renderingErrors, output } = await renderPages(baseHref, sourcemap, serializableRouteTreeNodeForPrerender, maxThreads, workspaceRoot, outputFilesForWorker, assetsReversed, appShellOptions, outputMode, appShellRoute ?? appShellOptions?.route);
|
|
96
94
|
errors.push(...renderingErrors);
|
|
97
95
|
return {
|
|
98
96
|
errors,
|
|
@@ -101,7 +99,7 @@ async function prerenderPages(workspaceRoot, baseHref, appShellOptions, prerende
|
|
|
101
99
|
serializableRouteTreeNode,
|
|
102
100
|
};
|
|
103
101
|
}
|
|
104
|
-
async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxThreads, workspaceRoot, outputFilesForWorker, assetFilesForWorker, appShellOptions, outputMode) {
|
|
102
|
+
async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxThreads, workspaceRoot, outputFilesForWorker, assetFilesForWorker, appShellOptions, outputMode, appShellRoute) {
|
|
105
103
|
const output = {};
|
|
106
104
|
const errors = [];
|
|
107
105
|
const workerExecArgv = [utils_1.IMPORT_EXEC_ARGV];
|
|
@@ -122,7 +120,7 @@ async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxTh
|
|
|
122
120
|
});
|
|
123
121
|
try {
|
|
124
122
|
const renderingPromises = [];
|
|
125
|
-
const
|
|
123
|
+
const appShellRouteWithLeadingSlash = appShellRoute && addLeadingSlash(appShellRoute);
|
|
126
124
|
const baseHrefWithLeadingSlash = addLeadingSlash(baseHref);
|
|
127
125
|
for (const { route, redirectTo, renderMode } of serializableRouteTreeNode) {
|
|
128
126
|
// Remove the base href from the file output path.
|
|
@@ -134,14 +132,14 @@ async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxTh
|
|
|
134
132
|
output[outPath] = { content: generateRedirectStaticPage(redirectTo), appShellRoute: false };
|
|
135
133
|
continue;
|
|
136
134
|
}
|
|
137
|
-
const
|
|
138
|
-
// Legacy handling
|
|
139
|
-
(renderMode === undefined && appShellRoute === routeWithoutBaseHref);
|
|
140
|
-
const render = renderWorker.run({ url: route, isAppShellRoute });
|
|
135
|
+
const render = renderWorker.run({ url: route });
|
|
141
136
|
const renderResult = render
|
|
142
137
|
.then((content) => {
|
|
143
138
|
if (content !== null) {
|
|
144
|
-
output[outPath] = {
|
|
139
|
+
output[outPath] = {
|
|
140
|
+
content,
|
|
141
|
+
appShellRoute: appShellRouteWithLeadingSlash === routeWithoutBaseHref,
|
|
142
|
+
};
|
|
145
143
|
}
|
|
146
144
|
})
|
|
147
145
|
.catch((err) => {
|
|
@@ -163,10 +161,12 @@ async function renderPages(baseHref, sourcemap, serializableRouteTreeNode, maxTh
|
|
|
163
161
|
async function getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, assetFilesForWorker, appShellOptions, prerenderOptions, sourcemap, outputMode) {
|
|
164
162
|
const { routesFile, discoverRoutes } = prerenderOptions ?? {};
|
|
165
163
|
const routes = [];
|
|
164
|
+
let appShellRoute;
|
|
166
165
|
if (appShellOptions) {
|
|
166
|
+
appShellRoute = (0, url_1.urlJoin)(baseHref, appShellOptions.route);
|
|
167
167
|
routes.push({
|
|
168
|
-
renderMode: models_1.RouteRenderMode.
|
|
169
|
-
route:
|
|
168
|
+
renderMode: models_1.RouteRenderMode.Prerender,
|
|
169
|
+
route: appShellRoute,
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
if (routesFile) {
|
|
@@ -179,7 +179,7 @@ async function getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, asset
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
if (!discoverRoutes) {
|
|
182
|
-
return { errors: [], serializedRouteTree: routes };
|
|
182
|
+
return { errors: [], appShellRoute, serializedRouteTree: routes };
|
|
183
183
|
}
|
|
184
184
|
const workerExecArgv = [utils_1.IMPORT_EXEC_ARGV];
|
|
185
185
|
if (sourcemap) {
|
|
@@ -198,9 +198,9 @@ async function getAllRoutes(workspaceRoot, baseHref, outputFilesForWorker, asset
|
|
|
198
198
|
execArgv: workerExecArgv,
|
|
199
199
|
});
|
|
200
200
|
try {
|
|
201
|
-
const { serializedRouteTree, errors } = await renderWorker.run({});
|
|
201
|
+
const { serializedRouteTree, appShellRoute, errors } = await renderWorker.run({});
|
|
202
202
|
if (!routes.length) {
|
|
203
|
-
return { errors, serializedRouteTree };
|
|
203
|
+
return { errors, appShellRoute, serializedRouteTree };
|
|
204
204
|
}
|
|
205
205
|
// Merge the routing trees
|
|
206
206
|
const uniqueRoutes = new Map();
|
|
@@ -20,9 +20,10 @@ let serverURL = launch_server_1.DEFAULT_URL;
|
|
|
20
20
|
/** Renders an application based on a provided options. */
|
|
21
21
|
async function extractRoutes() {
|
|
22
22
|
const { ɵextractRoutesAndCreateRouteTree: extractRoutesAndCreateRouteTree } = await (0, load_esm_from_memory_1.loadEsmModuleFromMemory)('./main.server.mjs');
|
|
23
|
-
const { routeTree, errors } = await extractRoutesAndCreateRouteTree(serverURL, undefined /** manifest */, true /** invokeGetPrerenderParams */, outputMode === schema_1.OutputMode.Server /** includePrerenderFallbackRoutes */);
|
|
23
|
+
const { routeTree, appShellRoute, errors } = await extractRoutesAndCreateRouteTree(serverURL, undefined /** manifest */, true /** invokeGetPrerenderParams */, outputMode === schema_1.OutputMode.Server /** includePrerenderFallbackRoutes */);
|
|
24
24
|
return {
|
|
25
25
|
errors,
|
|
26
|
+
appShellRoute,
|
|
26
27
|
serializedRouteTree: routeTree.toObject(),
|
|
27
28
|
};
|
|
28
29
|
}
|