@angular/build 19.0.0-next.4 → 19.0.0-next.5
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 +6 -5
- package/src/builders/dev-server/vite-server.d.ts +1 -1
- package/src/builders/dev-server/vite-server.js +21 -5
- package/src/tools/vite/angular-memory-plugin.d.ts +1 -0
- package/src/tools/vite/angular-memory-plugin.js +2 -2
- package/src/tools/vite/middlewares/assets-middleware.d.ts +1 -1
- package/src/tools/vite/middlewares/assets-middleware.js +41 -2
- package/src/utils/normalize-cache.js +1 -1
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.5",
|
|
4
4
|
"description": "Official build system for Angular",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Angular CLI",
|
|
@@ -23,7 +23,7 @@
|
|
|
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.5",
|
|
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",
|
|
@@ -42,18 +42,19 @@
|
|
|
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.
|
|
45
|
+
"rollup": "4.21.3",
|
|
46
46
|
"sass": "1.78.0",
|
|
47
47
|
"semver": "7.6.3",
|
|
48
|
-
"vite": "5.4.
|
|
48
|
+
"vite": "5.4.4",
|
|
49
49
|
"watchpack": "2.4.2"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
+
"@angular/compiler": "^19.0.0-next.0",
|
|
52
53
|
"@angular/compiler-cli": "^19.0.0-next.0",
|
|
53
54
|
"@angular/localize": "^19.0.0-next.0",
|
|
54
55
|
"@angular/platform-server": "^19.0.0-next.0",
|
|
55
56
|
"@angular/service-worker": "^19.0.0-next.0",
|
|
56
|
-
"@angular/ssr": "^19.0.0-next.
|
|
57
|
+
"@angular/ssr": "^19.0.0-next.5",
|
|
57
58
|
"less": "^4.2.0",
|
|
58
59
|
"postcss": "^8.4.0",
|
|
59
60
|
"tailwindcss": "^2.0.0 || ^3.0.0",
|
|
@@ -31,6 +31,6 @@ export declare function serveWithVite(serverOptions: NormalizedDevServerOptions,
|
|
|
31
31
|
middleware?: Connect.NextHandleFunction[];
|
|
32
32
|
buildPlugins?: Plugin[];
|
|
33
33
|
}): AsyncIterableIterator<DevServerBuilderOutput>;
|
|
34
|
-
export declare function setupServer(serverOptions: NormalizedDevServerOptions, outputFiles: Map<string, OutputFileRecord>, assets: Map<string, string>, preserveSymlinks: boolean | undefined, externalMetadata: DevServerExternalResultMetadata, ssr: boolean, prebundleTransformer: JavaScriptTransformer, target: string[], zoneless: boolean, prebundleLoaderExtensions: EsbuildLoaderOption | undefined, extensionMiddleware?: Connect.NextHandleFunction[], indexHtmlTransformer?: (content: string) => Promise<string>, thirdPartySourcemaps?: boolean): Promise<InlineConfig>;
|
|
34
|
+
export declare function setupServer(serverOptions: NormalizedDevServerOptions, outputFiles: Map<string, OutputFileRecord>, assets: Map<string, string>, preserveSymlinks: boolean | undefined, externalMetadata: DevServerExternalResultMetadata, ssr: boolean, prebundleTransformer: JavaScriptTransformer, target: string[], zoneless: boolean, usedComponentStyles: Map<string, string[]>, prebundleLoaderExtensions: EsbuildLoaderOption | undefined, extensionMiddleware?: Connect.NextHandleFunction[], indexHtmlTransformer?: (content: string) => Promise<string>, thirdPartySourcemaps?: boolean): Promise<InlineConfig>;
|
|
35
35
|
type EsbuildLoaderOption = Exclude<DepOptimizationConfig['esbuildOptions'], undefined>['loader'];
|
|
36
36
|
export {};
|
|
@@ -110,6 +110,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
110
110
|
explicitBrowser: [],
|
|
111
111
|
explicitServer: [],
|
|
112
112
|
};
|
|
113
|
+
const usedComponentStyles = new Map();
|
|
113
114
|
// Add cleanup logic via a builder teardown.
|
|
114
115
|
let deferred;
|
|
115
116
|
context.addTeardown(async () => {
|
|
@@ -214,7 +215,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
214
215
|
await server.restart();
|
|
215
216
|
}
|
|
216
217
|
else {
|
|
217
|
-
await handleUpdate(normalizePath, generatedFiles, server, serverOptions, context.logger);
|
|
218
|
+
await handleUpdate(normalizePath, generatedFiles, server, serverOptions, context.logger, usedComponentStyles);
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
221
|
else {
|
|
@@ -238,7 +239,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
238
239
|
? browserOptions.polyfills
|
|
239
240
|
: [browserOptions.polyfills];
|
|
240
241
|
// Setup server and start listening
|
|
241
|
-
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, !!browserOptions.ssr, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), browserOptions.loader, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
|
|
242
|
+
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, !!browserOptions.ssr, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), usedComponentStyles, browserOptions.loader, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
|
|
242
243
|
server = await createServer(serverConfiguration);
|
|
243
244
|
await server.listen();
|
|
244
245
|
if (browserOptions.ssr && serverOptions.prebundle !== false) {
|
|
@@ -277,7 +278,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
277
278
|
}
|
|
278
279
|
await new Promise((resolve) => (deferred = resolve));
|
|
279
280
|
}
|
|
280
|
-
async function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logger) {
|
|
281
|
+
async function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logger, usedComponentStyles) {
|
|
281
282
|
const updatedFiles = [];
|
|
282
283
|
let isServerFileUpdated = false;
|
|
283
284
|
// Invalidate any updated files
|
|
@@ -302,7 +303,21 @@ async function handleUpdate(normalizePath, generatedFiles, server, serverOptions
|
|
|
302
303
|
const timestamp = Date.now();
|
|
303
304
|
server.hot.send({
|
|
304
305
|
type: 'update',
|
|
305
|
-
updates: updatedFiles.
|
|
306
|
+
updates: updatedFiles.flatMap((filePath) => {
|
|
307
|
+
// For component styles, an HMR update must be sent for each one with the corresponding
|
|
308
|
+
// component identifier search parameter (`ngcomp`). The Vite client code will not keep
|
|
309
|
+
// the existing search parameters when it performs an update and each one must be
|
|
310
|
+
// specified explicitly. Typically, there is only one each though as specific style files
|
|
311
|
+
// are not typically reused across components.
|
|
312
|
+
const componentIds = usedComponentStyles.get(filePath);
|
|
313
|
+
if (componentIds) {
|
|
314
|
+
return componentIds.map((id) => ({
|
|
315
|
+
type: 'css-update',
|
|
316
|
+
timestamp,
|
|
317
|
+
path: `${filePath}?ngcomp` + (id ? `=${id}` : ''),
|
|
318
|
+
acceptedPath: filePath,
|
|
319
|
+
}));
|
|
320
|
+
}
|
|
306
321
|
return {
|
|
307
322
|
type: 'css-update',
|
|
308
323
|
timestamp,
|
|
@@ -377,7 +392,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
377
392
|
}
|
|
378
393
|
}
|
|
379
394
|
}
|
|
380
|
-
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssr, prebundleTransformer, target, zoneless, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
|
|
395
|
+
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssr, prebundleTransformer, target, zoneless, usedComponentStyles, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
|
|
381
396
|
const proxy = await (0, utils_1.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig);
|
|
382
397
|
// dynamically import Vite for ESM compatibility
|
|
383
398
|
const { normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
|
|
@@ -471,6 +486,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
471
486
|
indexHtmlTransformer,
|
|
472
487
|
extensionMiddleware,
|
|
473
488
|
normalizePath,
|
|
489
|
+
usedComponentStyles,
|
|
474
490
|
}),
|
|
475
491
|
(0, id_prefix_plugin_1.createRemoveIdPrefixPlugin)(externalMetadata.explicitBrowser),
|
|
476
492
|
],
|
|
@@ -17,5 +17,6 @@ export interface AngularMemoryPluginOptions {
|
|
|
17
17
|
extensionMiddleware?: Connect.NextHandleFunction[];
|
|
18
18
|
indexHtmlTransformer?: (content: string) => Promise<string>;
|
|
19
19
|
normalizePath: (path: string) => string;
|
|
20
|
+
usedComponentStyles: Map<string, string[]>;
|
|
20
21
|
}
|
|
21
22
|
export declare function createAngularMemoryPlugin(options: AngularMemoryPluginOptions): Plugin;
|
|
@@ -17,7 +17,7 @@ const promises_1 = require("node:fs/promises");
|
|
|
17
17
|
const node_path_1 = require("node:path");
|
|
18
18
|
const middlewares_1 = require("./middlewares");
|
|
19
19
|
function createAngularMemoryPlugin(options) {
|
|
20
|
-
const { workspaceRoot, virtualProjectRoot, outputFiles, assets, external, ssr, extensionMiddleware, indexHtmlTransformer, normalizePath, } = options;
|
|
20
|
+
const { workspaceRoot, virtualProjectRoot, outputFiles, assets, external, ssr, extensionMiddleware, indexHtmlTransformer, normalizePath, usedComponentStyles, } = options;
|
|
21
21
|
return {
|
|
22
22
|
name: 'vite:angular-memory',
|
|
23
23
|
// Ensures plugin hooks run before built-in Vite hooks
|
|
@@ -75,7 +75,7 @@ function createAngularMemoryPlugin(options) {
|
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
77
|
// Assets and resources get handled first
|
|
78
|
-
server.middlewares.use((0, middlewares_1.createAngularAssetsMiddleware)(server, assets, outputFiles));
|
|
78
|
+
server.middlewares.use((0, middlewares_1.createAngularAssetsMiddleware)(server, assets, outputFiles, usedComponentStyles));
|
|
79
79
|
if (extensionMiddleware?.length) {
|
|
80
80
|
extensionMiddleware.forEach((middleware) => server.middlewares.use(middleware));
|
|
81
81
|
}
|
|
@@ -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,8 +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
|
-
|
|
15
|
+
const COMPONENT_REGEX = /%COMP%/g;
|
|
16
|
+
function createAngularAssetsMiddleware(server, assets, outputFiles, usedComponentStyles) {
|
|
15
17
|
return function (req, res, next) {
|
|
16
18
|
if (req.url === undefined || res.writableEnded) {
|
|
17
19
|
return;
|
|
@@ -53,13 +55,50 @@ function createAngularAssetsMiddleware(server, assets, outputFiles) {
|
|
|
53
55
|
if (extension !== '.js' && extension !== '.html') {
|
|
54
56
|
const outputFile = outputFiles.get(pathname);
|
|
55
57
|
if (outputFile?.servable) {
|
|
58
|
+
const data = outputFile.contents;
|
|
59
|
+
if (extension === '.css') {
|
|
60
|
+
// Inject component ID for view encapsulation if requested
|
|
61
|
+
const componentId = new URL(req.url, 'http://localhost').searchParams.get('ngcomp');
|
|
62
|
+
if (componentId !== null) {
|
|
63
|
+
// Record the component style usage for HMR updates
|
|
64
|
+
const usedIds = usedComponentStyles.get(pathname);
|
|
65
|
+
if (usedIds === undefined) {
|
|
66
|
+
usedComponentStyles.set(pathname, [componentId]);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
usedIds.push(componentId);
|
|
70
|
+
}
|
|
71
|
+
// Shim the stylesheet if a component ID is provided
|
|
72
|
+
if (componentId.length > 0) {
|
|
73
|
+
// Validate component ID
|
|
74
|
+
if (/[_.-A-Za-z0-9]+-c\d{9}$/.test(componentId)) {
|
|
75
|
+
(0, load_esm_1.loadEsmModule)('@angular/compiler')
|
|
76
|
+
.then((compilerModule) => {
|
|
77
|
+
const encapsulatedData = compilerModule
|
|
78
|
+
.encapsulateStyle(new TextDecoder().decode(data))
|
|
79
|
+
.replaceAll(COMPONENT_REGEX, componentId);
|
|
80
|
+
res.setHeader('Content-Type', 'text/css');
|
|
81
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
82
|
+
(0, utils_1.appendServerConfiguredHeaders)(server, res);
|
|
83
|
+
res.end(encapsulatedData);
|
|
84
|
+
})
|
|
85
|
+
.catch((e) => next(e));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// eslint-disable-next-line no-console
|
|
90
|
+
console.error('Invalid component stylesheet ID request: ' + componentId);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
56
95
|
const mimeType = (0, mrmime_1.lookup)(extension);
|
|
57
96
|
if (mimeType) {
|
|
58
97
|
res.setHeader('Content-Type', mimeType);
|
|
59
98
|
}
|
|
60
99
|
res.setHeader('Cache-Control', 'no-cache');
|
|
61
100
|
(0, utils_1.appendServerConfiguredHeaders)(server, res);
|
|
62
|
-
res.end(
|
|
101
|
+
res.end(data);
|
|
63
102
|
return;
|
|
64
103
|
}
|
|
65
104
|
}
|
|
@@ -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-next.
|
|
13
|
+
const VERSION = '19.0.0-next.5';
|
|
14
14
|
function hasCacheMetadata(value) {
|
|
15
15
|
return (!!value &&
|
|
16
16
|
typeof value === 'object' &&
|