@angular/build 19.0.0-next.7 → 19.0.0-next.8
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 +9 -9
- package/src/builders/application/execute-build.js +19 -2
- package/src/builders/application/execute-post-bundle.d.ts +2 -2
- package/src/builders/application/execute-post-bundle.js +30 -11
- package/src/builders/application/i18n.d.ts +2 -2
- package/src/builders/application/i18n.js +4 -5
- package/src/builders/application/index.js +8 -5
- package/src/builders/application/options.d.ts +18 -1
- package/src/builders/application/options.js +30 -2
- package/src/builders/application/schema.d.ts +15 -0
- package/src/builders/application/schema.js +11 -1
- package/src/builders/application/schema.json +5 -0
- package/src/builders/application/setup-bundling.js +6 -3
- package/src/builders/dev-server/vite-server.d.ts +2 -1
- package/src/builders/dev-server/vite-server.js +64 -47
- package/src/builders/extract-i18n/application-extraction.js +3 -3
- package/src/tools/angular/angular-host.d.ts +2 -1
- package/src/tools/angular/angular-host.js +20 -1
- package/src/tools/angular/compilation/angular-compilation.d.ts +1 -0
- package/src/tools/angular/compilation/aot-compilation.d.ts +1 -0
- package/src/tools/angular/compilation/aot-compilation.js +9 -1
- package/src/tools/angular/compilation/parallel-compilation.d.ts +1 -0
- package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
- package/src/tools/angular/compilation/parallel-worker.js +2 -1
- package/src/tools/esbuild/angular/compiler-plugin.d.ts +1 -0
- package/src/tools/esbuild/angular/compiler-plugin.js +42 -3
- package/src/tools/esbuild/angular/component-stylesheets.d.ts +8 -3
- package/src/tools/esbuild/angular/component-stylesheets.js +46 -11
- package/src/tools/esbuild/application-code-bundle.d.ts +1 -0
- package/src/tools/esbuild/application-code-bundle.js +109 -2
- package/src/tools/esbuild/budget-stats.js +1 -1
- package/src/tools/esbuild/bundler-context.d.ts +4 -3
- package/src/tools/esbuild/bundler-context.js +8 -4
- package/src/tools/esbuild/bundler-execution-result.d.ts +5 -2
- package/src/tools/esbuild/bundler-execution-result.js +7 -3
- package/src/tools/esbuild/cache.d.ts +5 -0
- package/src/tools/esbuild/cache.js +7 -0
- package/src/tools/esbuild/compiler-plugin-options.js +2 -1
- package/src/tools/esbuild/i18n-inliner.js +2 -1
- package/src/tools/esbuild/utils.js +7 -3
- package/src/tools/vite/middlewares/assets-middleware.js +2 -5
- package/src/tools/vite/middlewares/html-fallback-middleware.js +22 -6
- package/src/tools/vite/middlewares/index.d.ts +1 -1
- package/src/tools/vite/middlewares/index.js +3 -2
- package/src/tools/vite/middlewares/ssr-middleware.d.ts +2 -1
- package/src/tools/vite/middlewares/ssr-middleware.js +61 -15
- package/src/tools/vite/plugins/angular-memory-plugin.d.ts +16 -0
- package/src/tools/vite/{angular-memory-plugin.js → plugins/angular-memory-plugin.js} +19 -41
- package/src/tools/vite/{i18n-locale-plugin.d.ts → plugins/i18n-locale-plugin.d.ts} +0 -4
- package/src/tools/vite/{i18n-locale-plugin.js → plugins/i18n-locale-plugin.js} +2 -3
- package/src/tools/vite/plugins/index.d.ts +12 -0
- package/src/tools/vite/plugins/index.js +21 -0
- package/src/tools/vite/plugins/setup-middlewares-plugin.d.ts +41 -0
- package/src/tools/vite/plugins/setup-middlewares-plugin.js +62 -0
- package/src/tools/vite/plugins/ssr-transform-plugin.d.ts +9 -0
- package/src/tools/vite/plugins/ssr-transform-plugin.js +38 -0
- package/src/utils/environment-options.d.ts +2 -0
- package/src/utils/environment-options.js +5 -1
- package/src/utils/index-file/valid-self-closing-tags.js +1 -0
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/manifest.d.ts +8 -2
- package/src/utils/server-rendering/manifest.js +61 -12
- package/src/utils/server-rendering/models.d.ts +27 -0
- package/src/utils/server-rendering/models.js +22 -0
- package/src/utils/server-rendering/prerender.d.ts +6 -10
- package/src/utils/server-rendering/prerender.js +100 -63
- package/src/utils/server-rendering/routes-extractor-worker.d.ts +5 -10
- package/src/utils/server-rendering/routes-extractor-worker.js +3 -4
- package/src/tools/vite/angular-memory-plugin.d.ts +0 -22
- /package/src/tools/vite/{id-prefix-plugin.d.ts → plugins/id-prefix-plugin.d.ts} +0 -0
- /package/src/tools/vite/{id-prefix-plugin.js → plugins/id-prefix-plugin.js} +0 -0
|
@@ -39,10 +39,9 @@ const node_assert_1 = __importDefault(require("node:assert"));
|
|
|
39
39
|
const promises_1 = require("node:fs/promises");
|
|
40
40
|
const node_module_1 = require("node:module");
|
|
41
41
|
const node_path_1 = require("node:path");
|
|
42
|
-
const
|
|
43
|
-
const i18n_locale_plugin_1 = require("../../tools/vite/i18n-locale-plugin");
|
|
44
|
-
const id_prefix_plugin_1 = require("../../tools/vite/id-prefix-plugin");
|
|
42
|
+
const plugins_1 = require("../../tools/vite/plugins");
|
|
45
43
|
const utils_1 = require("../../utils");
|
|
44
|
+
const environment_options_1 = require("../../utils/environment-options");
|
|
46
45
|
const load_esm_1 = require("../../utils/load-esm");
|
|
47
46
|
const results_1 = require("../application/results");
|
|
48
47
|
const internal_1 = require("./internal");
|
|
@@ -66,17 +65,16 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
66
65
|
}
|
|
67
66
|
// TODO: Adjust architect to not force a JsonObject derived return type
|
|
68
67
|
const browserOptions = (await context.validateOptions(rawBrowserOptions, builderName));
|
|
69
|
-
if (browserOptions.prerender
|
|
68
|
+
if (browserOptions.prerender) {
|
|
70
69
|
// Disable prerendering if enabled and force SSR.
|
|
71
70
|
// This is so instead of prerendering all the routes for every change, the page is "prerendered" when it is requested.
|
|
72
71
|
browserOptions.prerender = false;
|
|
73
|
-
// Avoid bundling and processing the ssr entry-point as this is not used by the dev-server.
|
|
74
|
-
browserOptions.ssr = true;
|
|
75
|
-
// https://nodejs.org/api/process.html#processsetsourcemapsenabledval
|
|
76
|
-
process.setSourceMapsEnabled(true);
|
|
77
72
|
}
|
|
78
73
|
// Set all packages as external to support Vite's prebundle caching
|
|
79
74
|
browserOptions.externalPackages = serverOptions.prebundle;
|
|
75
|
+
// Disable generating a full manifest with routes.
|
|
76
|
+
// This is done during runtime when using the dev-server.
|
|
77
|
+
browserOptions.partialSSRBuild = true;
|
|
80
78
|
// The development server currently only supports a single locale when localizing.
|
|
81
79
|
// This matches the behavior of the Webpack-based development server but could be expanded in the future.
|
|
82
80
|
if (browserOptions.localize === true ||
|
|
@@ -88,7 +86,13 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
88
86
|
// When localization is enabled with a single locale, force a flat path to maintain behavior with the existing Webpack-based dev server.
|
|
89
87
|
browserOptions.forceI18nFlatOutput = true;
|
|
90
88
|
}
|
|
91
|
-
const { vendor: thirdPartySourcemaps } = (0, utils_1.normalizeSourceMaps)(browserOptions.sourceMap ?? false);
|
|
89
|
+
const { vendor: thirdPartySourcemaps, scripts: scriptsSourcemaps } = (0, utils_1.normalizeSourceMaps)(browserOptions.sourceMap ?? false);
|
|
90
|
+
if (scriptsSourcemaps && browserOptions.server) {
|
|
91
|
+
// https://nodejs.org/api/process.html#processsetsourcemapsenabledval
|
|
92
|
+
process.setSourceMapsEnabled(true);
|
|
93
|
+
}
|
|
94
|
+
// TODO: Enable by default once full support across CLI and FW is integrated
|
|
95
|
+
browserOptions.externalRuntimeStyles = environment_options_1.useComponentStyleHmr;
|
|
92
96
|
// Setup the prebundling transformer that will be shared across Vite prebundling requests
|
|
93
97
|
const prebundleTransformer = new internal_1.JavaScriptTransformer(
|
|
94
98
|
// Always enable JIT linking to support applications built with and without AOT.
|
|
@@ -180,8 +184,8 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
180
184
|
let requiresServerRestart = false;
|
|
181
185
|
if (result.detail?.['externalMetadata']) {
|
|
182
186
|
const { implicitBrowser, implicitServer, explicit } = result.detail['externalMetadata'];
|
|
183
|
-
const implicitServerFiltered = implicitServer.filter((m) =>
|
|
184
|
-
const implicitBrowserFiltered = implicitBrowser.filter(
|
|
187
|
+
const implicitServerFiltered = implicitServer.filter((m) => !(0, node_module_1.isBuiltin)(m) && !isAbsoluteUrl(m));
|
|
188
|
+
const implicitBrowserFiltered = implicitBrowser.filter((m) => !isAbsoluteUrl(m));
|
|
185
189
|
if (browserOptions.ssr && serverOptions.prebundle !== false) {
|
|
186
190
|
const previousImplicitServer = new Set(externalMetadata.implicitServer);
|
|
187
191
|
// Restart the server to force SSR dep re-optimization when a dependency has been added.
|
|
@@ -194,7 +198,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
194
198
|
externalMetadata.implicitServer.length = 0;
|
|
195
199
|
externalMetadata.implicitBrowser.length = 0;
|
|
196
200
|
externalMetadata.explicitBrowser.push(...explicit);
|
|
197
|
-
externalMetadata.explicitServer.push(...explicit, ...
|
|
201
|
+
externalMetadata.explicitServer.push(...explicit, ...node_module_1.builtinModules);
|
|
198
202
|
externalMetadata.implicitServer.push(...implicitServerFiltered);
|
|
199
203
|
externalMetadata.implicitBrowser.push(...implicitBrowserFiltered);
|
|
200
204
|
// The below needs to be sorted as Vite uses these options are part of the hashing invalidation algorithm.
|
|
@@ -238,15 +242,19 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
238
242
|
const polyfills = Array.isArray((browserOptions.polyfills ??= []))
|
|
239
243
|
? browserOptions.polyfills
|
|
240
244
|
: [browserOptions.polyfills];
|
|
245
|
+
let ssrMode = plugins_1.ServerSsrMode.NoSsr;
|
|
246
|
+
if (browserOptions.outputMode &&
|
|
247
|
+
typeof browserOptions.ssr === 'object' &&
|
|
248
|
+
browserOptions.ssr.entry) {
|
|
249
|
+
ssrMode = plugins_1.ServerSsrMode.ExternalSsrMiddleware;
|
|
250
|
+
}
|
|
251
|
+
else if (browserOptions.server) {
|
|
252
|
+
ssrMode = plugins_1.ServerSsrMode.InternalSsrMiddleware;
|
|
253
|
+
}
|
|
241
254
|
// Setup server and start listening
|
|
242
|
-
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata,
|
|
255
|
+
const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), usedComponentStyles, browserOptions.loader, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
|
|
243
256
|
server = await createServer(serverConfiguration);
|
|
244
257
|
await server.listen();
|
|
245
|
-
if (browserOptions.ssr && serverOptions.prebundle !== false) {
|
|
246
|
-
// Warm up the SSR request and begin optimizing dependencies.
|
|
247
|
-
// Without this, Vite will only start optimizing SSR modules when the first request is made.
|
|
248
|
-
void server.warmupRequest('./main.server.mjs', { ssr: true });
|
|
249
|
-
}
|
|
250
258
|
const urls = server.resolvedUrls;
|
|
251
259
|
if (urls && (urls.local.length || urls.network.length)) {
|
|
252
260
|
serverUrl = new URL(urls.local[0] ?? urls.network[0]);
|
|
@@ -280,24 +288,26 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
|
|
|
280
288
|
}
|
|
281
289
|
async function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logger, usedComponentStyles) {
|
|
282
290
|
const updatedFiles = [];
|
|
283
|
-
let
|
|
291
|
+
let destroyAngularServerAppCalled = false;
|
|
284
292
|
// Invalidate any updated files
|
|
285
|
-
for (const [file,
|
|
286
|
-
if (
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
293
|
+
for (const [file, { updated, type }] of generatedFiles) {
|
|
294
|
+
if (!updated) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
if (type === internal_1.BuildOutputFileType.ServerApplication && !destroyAngularServerAppCalled) {
|
|
298
|
+
// Clear the server app cache
|
|
299
|
+
// This must be done before module invalidation.
|
|
300
|
+
const { ɵdestroyAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs'));
|
|
301
|
+
ɵdestroyAngularServerApp();
|
|
302
|
+
destroyAngularServerAppCalled = true;
|
|
291
303
|
}
|
|
304
|
+
updatedFiles.push(file);
|
|
305
|
+
const updatedModules = server.moduleGraph.getModulesByFile(normalizePath((0, node_path_1.join)(server.config.root, file)));
|
|
306
|
+
updatedModules?.forEach((m) => server.moduleGraph.invalidateModule(m));
|
|
292
307
|
}
|
|
293
308
|
if (!updatedFiles.length) {
|
|
294
309
|
return;
|
|
295
310
|
}
|
|
296
|
-
// clean server apps cache
|
|
297
|
-
if (isServerFileUpdated) {
|
|
298
|
-
const { ɵdestroyAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs'));
|
|
299
|
-
ɵdestroyAngularServerApp();
|
|
300
|
-
}
|
|
301
311
|
if (serverOptions.liveReload || serverOptions.hmr) {
|
|
302
312
|
if (updatedFiles.every((f) => f.endsWith('.css'))) {
|
|
303
313
|
const timestamp = Date.now();
|
|
@@ -392,7 +402,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
|
|
|
392
402
|
}
|
|
393
403
|
}
|
|
394
404
|
}
|
|
395
|
-
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata,
|
|
405
|
+
async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, zoneless, usedComponentStyles, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
|
|
396
406
|
const proxy = await (0, utils_1.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig);
|
|
397
407
|
// dynamically import Vite for ESM compatibility
|
|
398
408
|
const { normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
|
|
@@ -427,6 +437,9 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
427
437
|
preserveSymlinks,
|
|
428
438
|
},
|
|
429
439
|
server: {
|
|
440
|
+
warmup: {
|
|
441
|
+
ssrFiles: ['./main.server.mjs', './server.mjs'],
|
|
442
|
+
},
|
|
430
443
|
port: serverOptions.port,
|
|
431
444
|
strictPort: true,
|
|
432
445
|
host: serverOptions.host,
|
|
@@ -475,20 +488,22 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
|
|
|
475
488
|
}),
|
|
476
489
|
},
|
|
477
490
|
plugins: [
|
|
478
|
-
(0,
|
|
479
|
-
(0,
|
|
480
|
-
workspaceRoot: serverOptions.workspaceRoot,
|
|
481
|
-
virtualProjectRoot,
|
|
491
|
+
(0, plugins_1.createAngularLocaleDataPlugin)(),
|
|
492
|
+
(0, plugins_1.createAngularSetupMiddlewaresPlugin)({
|
|
482
493
|
outputFiles,
|
|
483
494
|
assets,
|
|
484
|
-
ssr,
|
|
485
|
-
external: externalMetadata.explicitBrowser,
|
|
486
495
|
indexHtmlTransformer,
|
|
487
496
|
extensionMiddleware,
|
|
488
|
-
normalizePath,
|
|
489
497
|
usedComponentStyles,
|
|
498
|
+
ssrMode,
|
|
499
|
+
}),
|
|
500
|
+
(0, plugins_1.createRemoveIdPrefixPlugin)(externalMetadata.explicitBrowser),
|
|
501
|
+
await (0, plugins_1.createAngularSsrTransformPlugin)(serverOptions.workspaceRoot),
|
|
502
|
+
await (0, plugins_1.createAngularMemoryPlugin)({
|
|
503
|
+
virtualProjectRoot,
|
|
504
|
+
outputFiles,
|
|
505
|
+
external: externalMetadata.explicitBrowser,
|
|
490
506
|
}),
|
|
491
|
-
(0, id_prefix_plugin_1.createRemoveIdPrefixPlugin)(externalMetadata.explicitBrowser),
|
|
492
507
|
],
|
|
493
508
|
// Browser only optimizeDeps. (This does not run for SSR dependencies).
|
|
494
509
|
optimizeDeps: getDepOptimizationConfig({
|
|
@@ -556,12 +571,14 @@ function getDepOptimizationConfig({ disabled, exclude, include, target, zoneless
|
|
|
556
571
|
},
|
|
557
572
|
};
|
|
558
573
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
574
|
+
/**
|
|
575
|
+
* Checks if the given value is an absolute URL.
|
|
576
|
+
*
|
|
577
|
+
* This function helps in avoiding Vite's prebundling from processing absolute URLs (http://, https://, //) as files.
|
|
578
|
+
*
|
|
579
|
+
* @param value - The URL or path to check.
|
|
580
|
+
* @returns `true` if the value is not an absolute URL; otherwise, `false`.
|
|
581
|
+
*/
|
|
582
|
+
function isAbsoluteUrl(value) {
|
|
583
|
+
return /^(?:https?:)?\/\//.test(value);
|
|
567
584
|
}
|
|
@@ -15,6 +15,7 @@ const node_fs_1 = require("node:fs");
|
|
|
15
15
|
const node_path_1 = __importDefault(require("node:path"));
|
|
16
16
|
const application_1 = require("../application");
|
|
17
17
|
const results_1 = require("../application/results");
|
|
18
|
+
const schema_1 = require("../application/schema");
|
|
18
19
|
async function extractMessages(options, builderName, context, extractorConstructor, extensions) {
|
|
19
20
|
const messages = [];
|
|
20
21
|
// Setup the build options for the application based on the buildTarget option
|
|
@@ -25,9 +26,8 @@ async function extractMessages(options, builderName, context, extractorConstruct
|
|
|
25
26
|
buildOptions.budgets = undefined;
|
|
26
27
|
buildOptions.index = false;
|
|
27
28
|
buildOptions.serviceWorker = false;
|
|
28
|
-
buildOptions.
|
|
29
|
-
buildOptions.
|
|
30
|
-
buildOptions.prerender = false;
|
|
29
|
+
buildOptions.outputMode = schema_1.OutputMode.Static;
|
|
30
|
+
buildOptions.server = undefined;
|
|
31
31
|
// Build the application with the build options
|
|
32
32
|
const builderResult = await first((0, application_1.buildApplicationInternal)(buildOptions, context, extensions));
|
|
33
33
|
let success = false;
|
|
@@ -13,7 +13,8 @@ export interface AngularHostOptions {
|
|
|
13
13
|
fileReplacements?: Record<string, string>;
|
|
14
14
|
sourceFileCache?: Map<string, ts.SourceFile>;
|
|
15
15
|
modifiedFiles?: Set<string>;
|
|
16
|
-
|
|
16
|
+
externalStylesheets?: Map<string, string>;
|
|
17
|
+
transformStylesheet(data: string, containingFile: string, stylesheetFile?: string, order?: number): Promise<string | null>;
|
|
17
18
|
processWebWorker(workerFile: string, containingFile: string): string;
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.ensureSourceFileVersions = ensureSourceFileVersions;
|
|
14
14
|
exports.createAngularCompilerHost = createAngularCompilerHost;
|
|
15
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
16
|
const node_crypto_1 = require("node:crypto");
|
|
16
17
|
const node_path_1 = __importDefault(require("node:path"));
|
|
17
18
|
/**
|
|
@@ -107,13 +108,31 @@ function createAngularCompilerHost(typescript, compilerOptions, hostOptions) {
|
|
|
107
108
|
if (context.type !== 'style') {
|
|
108
109
|
return null;
|
|
109
110
|
}
|
|
111
|
+
(0, node_assert_1.default)(!context.resourceFile || !hostOptions.externalStylesheets?.has(context.resourceFile), 'External runtime stylesheets should not be transformed: ' + context.resourceFile);
|
|
110
112
|
// No transformation required if the resource is empty
|
|
111
113
|
if (data.trim().length === 0) {
|
|
112
114
|
return { content: '' };
|
|
113
115
|
}
|
|
114
|
-
const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined
|
|
116
|
+
const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined,
|
|
117
|
+
// TODO: Remove once available in compiler-cli types
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
+
context.order);
|
|
115
120
|
return typeof result === 'string' ? { content: result } : null;
|
|
116
121
|
};
|
|
122
|
+
host.resourceNameToFileName = function (resourceName, containingFile) {
|
|
123
|
+
const resolvedPath = node_path_1.default.join(node_path_1.default.dirname(containingFile), resourceName);
|
|
124
|
+
// All resource names that have HTML file extensions are assumed to be templates
|
|
125
|
+
if (resourceName.endsWith('.html') || !hostOptions.externalStylesheets) {
|
|
126
|
+
return resolvedPath;
|
|
127
|
+
}
|
|
128
|
+
// For external stylesheets, create a unique identifier and store the mapping
|
|
129
|
+
let externalId = hostOptions.externalStylesheets.get(resolvedPath);
|
|
130
|
+
if (externalId === undefined) {
|
|
131
|
+
externalId = (0, node_crypto_1.createHash)('sha256').update(resolvedPath).digest('hex');
|
|
132
|
+
hostOptions.externalStylesheets.set(resolvedPath, externalId);
|
|
133
|
+
}
|
|
134
|
+
return externalId + '.css';
|
|
135
|
+
};
|
|
117
136
|
// Allow the AOT compiler to request the set of changed templates and styles
|
|
118
137
|
host.getModifiedResourceFiles = function () {
|
|
119
138
|
return hostOptions.modifiedFiles;
|
|
@@ -30,6 +30,7 @@ export declare abstract class AngularCompilation {
|
|
|
30
30
|
affectedFiles: ReadonlySet<ts.SourceFile>;
|
|
31
31
|
compilerOptions: ng.CompilerOptions;
|
|
32
32
|
referencedFiles: readonly string[];
|
|
33
|
+
externalStylesheets?: ReadonlyMap<string, string>;
|
|
33
34
|
}>;
|
|
34
35
|
abstract emitAffectedFiles(): Iterable<EmitFileResult> | Promise<Iterable<EmitFileResult>>;
|
|
35
36
|
protected abstract collectDiagnostics(modes: DiagnosticModes): Iterable<ts.Diagnostic> | Promise<Iterable<ts.Diagnostic>>;
|
|
@@ -15,6 +15,7 @@ export declare class AotCompilation extends AngularCompilation {
|
|
|
15
15
|
affectedFiles: ReadonlySet<ts.SourceFile>;
|
|
16
16
|
compilerOptions: ng.CompilerOptions;
|
|
17
17
|
referencedFiles: readonly string[];
|
|
18
|
+
externalStylesheets?: ReadonlyMap<string, string>;
|
|
18
19
|
}>;
|
|
19
20
|
collectDiagnostics(modes: DiagnosticModes): Iterable<ts.Diagnostic>;
|
|
20
21
|
emitAffectedFiles(): Iterable<EmitFileResult>;
|
|
@@ -47,6 +47,9 @@ class AotCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
47
47
|
// Load the compiler configuration and transform as needed
|
|
48
48
|
const { options: originalCompilerOptions, rootNames, errors: configurationDiagnostics, } = await this.loadConfiguration(tsconfig);
|
|
49
49
|
const compilerOptions = compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions;
|
|
50
|
+
if (compilerOptions.externalRuntimeStyles) {
|
|
51
|
+
hostOptions.externalStylesheets ??= new Map();
|
|
52
|
+
}
|
|
50
53
|
// Create Angular compiler host
|
|
51
54
|
const host = (0, angular_host_1.createAngularCompilerHost)(typescript_1.default, compilerOptions, hostOptions);
|
|
52
55
|
// Create the Angular specific program that contains the Angular compiler
|
|
@@ -82,7 +85,12 @@ class AotCompilation extends angular_compilation_1.AngularCompilation {
|
|
|
82
85
|
return [sourceFile.fileName, ...resourceDependencies];
|
|
83
86
|
});
|
|
84
87
|
this.#state = new AngularCompilationState(angularProgram, host, typeScriptProgram, affectedFiles, affectedFiles.size === 1 ? OptimizeFor.SingleFile : OptimizeFor.WholeProgram, (0, web_worker_transformer_1.createWorkerTransformer)(hostOptions.processWebWorker.bind(hostOptions)), this.#state?.diagnosticCache);
|
|
85
|
-
return {
|
|
88
|
+
return {
|
|
89
|
+
affectedFiles,
|
|
90
|
+
compilerOptions,
|
|
91
|
+
referencedFiles,
|
|
92
|
+
externalStylesheets: hostOptions.externalStylesheets,
|
|
93
|
+
};
|
|
86
94
|
}
|
|
87
95
|
*collectDiagnostics(modes) {
|
|
88
96
|
(0, node_assert_1.default)(this.#state, 'Angular compilation must be initialized prior to collecting diagnostics.');
|
|
@@ -26,6 +26,7 @@ export declare class ParallelCompilation extends AngularCompilation {
|
|
|
26
26
|
affectedFiles: ReadonlySet<SourceFile>;
|
|
27
27
|
compilerOptions: CompilerOptions;
|
|
28
28
|
referencedFiles: readonly string[];
|
|
29
|
+
externalStylesheets?: ReadonlyMap<string, string>;
|
|
29
30
|
}>;
|
|
30
31
|
/**
|
|
31
32
|
* This is not needed with this compilation type since the worker will already send a response
|
|
@@ -19,6 +19,7 @@ export interface InitRequest {
|
|
|
19
19
|
webWorkerSignal: Int32Array;
|
|
20
20
|
}
|
|
21
21
|
export declare function initialize(request: InitRequest): Promise<{
|
|
22
|
+
externalStylesheets: ReadonlyMap<string, string> | undefined;
|
|
22
23
|
referencedFiles: readonly string[];
|
|
23
24
|
compilerOptions: {
|
|
24
25
|
allowJs: boolean | undefined;
|
|
@@ -33,7 +33,7 @@ async function initialize(request) {
|
|
|
33
33
|
stylesheetRequests.get(requestId)?.[0](value);
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
-
const { compilerOptions, referencedFiles } = await compilation.initialize(request.tsconfig, {
|
|
36
|
+
const { compilerOptions, referencedFiles, externalStylesheets } = await compilation.initialize(request.tsconfig, {
|
|
37
37
|
fileReplacements: request.fileReplacements,
|
|
38
38
|
sourceFileCache,
|
|
39
39
|
modifiedFiles: sourceFileCache.modifiedFiles,
|
|
@@ -69,6 +69,7 @@ async function initialize(request) {
|
|
|
69
69
|
return result?.transformedOptions ?? compilerOptions;
|
|
70
70
|
});
|
|
71
71
|
return {
|
|
72
|
+
externalStylesheets,
|
|
72
73
|
referencedFiles,
|
|
73
74
|
// TODO: Expand? `allowJs`, `isolatedModules`, `sourceMap`, `inlineSourceMap` are the only fields needed currently.
|
|
74
75
|
compilerOptions: {
|
|
@@ -21,6 +21,7 @@ export interface CompilerPluginOptions {
|
|
|
21
21
|
sourceFileCache?: SourceFileCache;
|
|
22
22
|
loadResultCache?: LoadResultCache;
|
|
23
23
|
incremental: boolean;
|
|
24
|
+
externalRuntimeStyles?: boolean;
|
|
24
25
|
}
|
|
25
26
|
export declare function createCompilerPlugin(pluginOptions: CompilerPluginOptions, styleOptions: BundleStylesheetOptions & {
|
|
26
27
|
inlineStyleLanguage: string;
|
|
@@ -35,6 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.createCompilerPlugin = createCompilerPlugin;
|
|
37
37
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
38
|
+
const node_crypto_1 = require("node:crypto");
|
|
38
39
|
const path = __importStar(require("node:path"));
|
|
39
40
|
const environment_options_1 = require("../../../utils/environment-options");
|
|
40
41
|
const compilation_1 = require("../../angular/compilation");
|
|
@@ -120,13 +121,14 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
120
121
|
// Angular compiler which does not have direct knowledge of transitive resource
|
|
121
122
|
// dependencies or web worker processing.
|
|
122
123
|
let modifiedFiles;
|
|
124
|
+
let invalidatedStylesheetEntries;
|
|
123
125
|
if (pluginOptions.sourceFileCache?.modifiedFiles.size &&
|
|
124
126
|
referencedFileTracker &&
|
|
125
127
|
!pluginOptions.noopTypeScriptCompilation) {
|
|
126
128
|
// TODO: Differentiate between changed input files and stale output files
|
|
127
129
|
modifiedFiles = referencedFileTracker.update(pluginOptions.sourceFileCache.modifiedFiles);
|
|
128
130
|
pluginOptions.sourceFileCache.invalidate(modifiedFiles);
|
|
129
|
-
stylesheetBundler.invalidate(modifiedFiles);
|
|
131
|
+
invalidatedStylesheetEntries = stylesheetBundler.invalidate(modifiedFiles);
|
|
130
132
|
}
|
|
131
133
|
if (!pluginOptions.noopTypeScriptCompilation &&
|
|
132
134
|
compilation.update &&
|
|
@@ -138,7 +140,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
138
140
|
fileReplacements: pluginOptions.fileReplacements,
|
|
139
141
|
modifiedFiles,
|
|
140
142
|
sourceFileCache: pluginOptions.sourceFileCache,
|
|
141
|
-
async transformStylesheet(data, containingFile, stylesheetFile) {
|
|
143
|
+
async transformStylesheet(data, containingFile, stylesheetFile, order) {
|
|
142
144
|
let stylesheetResult;
|
|
143
145
|
// Stylesheet file only exists for external stylesheets
|
|
144
146
|
if (stylesheetFile) {
|
|
@@ -147,7 +149,17 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
147
149
|
else {
|
|
148
150
|
stylesheetResult = await stylesheetBundler.bundleInline(data, containingFile,
|
|
149
151
|
// Inline stylesheets from a template style element are always CSS
|
|
150
|
-
containingFile.endsWith('.html') ? 'css' : styleOptions.inlineStyleLanguage
|
|
152
|
+
containingFile.endsWith('.html') ? 'css' : styleOptions.inlineStyleLanguage,
|
|
153
|
+
// When external runtime styles are enabled, an identifier for the style that does not change
|
|
154
|
+
// based on the content is required to avoid emitted JS code changes. Any JS code changes will
|
|
155
|
+
// invalid the output and force a full page reload for HMR cases. The containing file and order
|
|
156
|
+
// of the style within the containing file is used.
|
|
157
|
+
pluginOptions.externalRuntimeStyles
|
|
158
|
+
? (0, node_crypto_1.createHash)('sha-256')
|
|
159
|
+
.update(containingFile)
|
|
160
|
+
.update((order ?? 0).toString())
|
|
161
|
+
.digest('hex')
|
|
162
|
+
: undefined);
|
|
151
163
|
}
|
|
152
164
|
const { contents, outputFiles, metafile, referencedFiles, errors, warnings } = stylesheetResult;
|
|
153
165
|
if (errors) {
|
|
@@ -201,6 +213,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
201
213
|
// Initialize the Angular compilation for the current build.
|
|
202
214
|
// In watch mode, previous build state will be reused.
|
|
203
215
|
let referencedFiles;
|
|
216
|
+
let externalStylesheets;
|
|
204
217
|
try {
|
|
205
218
|
const initializationResult = await compilation.initialize(pluginOptions.tsconfig, hostOptions, createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks));
|
|
206
219
|
shouldTsIgnoreJs = !initializationResult.compilerOptions.allowJs;
|
|
@@ -211,6 +224,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
211
224
|
!!initializationResult.compilerOptions.sourceMap ||
|
|
212
225
|
!!initializationResult.compilerOptions.inlineSourceMap;
|
|
213
226
|
referencedFiles = initializationResult.referencedFiles;
|
|
227
|
+
externalStylesheets = initializationResult.externalStylesheets;
|
|
214
228
|
}
|
|
215
229
|
catch (error) {
|
|
216
230
|
(result.errors ??= []).push({
|
|
@@ -231,6 +245,19 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
231
245
|
hasCompilationErrors = await sharedTSCompilationState.waitUntilReady;
|
|
232
246
|
return result;
|
|
233
247
|
}
|
|
248
|
+
if (externalStylesheets) {
|
|
249
|
+
// Process any new external stylesheets
|
|
250
|
+
for (const [stylesheetFile, externalId] of externalStylesheets) {
|
|
251
|
+
await bundleExternalStylesheet(stylesheetBundler, stylesheetFile, externalId, result, additionalResults);
|
|
252
|
+
}
|
|
253
|
+
// Process any updated stylesheets
|
|
254
|
+
if (invalidatedStylesheetEntries) {
|
|
255
|
+
for (const stylesheetFile of invalidatedStylesheetEntries) {
|
|
256
|
+
// externalId is already linked in the bundler context so only enabling is required here
|
|
257
|
+
await bundleExternalStylesheet(stylesheetBundler, stylesheetFile, true, result, additionalResults);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
234
261
|
// Update TypeScript file output cache for all affected files
|
|
235
262
|
try {
|
|
236
263
|
await (0, profiling_1.profileAsync)('NG_EMIT_TS', async () => {
|
|
@@ -376,6 +403,17 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
|
|
|
376
403
|
},
|
|
377
404
|
};
|
|
378
405
|
}
|
|
406
|
+
async function bundleExternalStylesheet(stylesheetBundler, stylesheetFile, externalId, result, additionalResults) {
|
|
407
|
+
const { outputFiles, metafile, errors, warnings } = await stylesheetBundler.bundleFile(stylesheetFile, externalId);
|
|
408
|
+
if (errors) {
|
|
409
|
+
(result.errors ??= []).push(...errors);
|
|
410
|
+
}
|
|
411
|
+
(result.warnings ??= []).push(...warnings);
|
|
412
|
+
additionalResults.set(stylesheetFile, {
|
|
413
|
+
outputFiles,
|
|
414
|
+
metafile,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
379
417
|
function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks) {
|
|
380
418
|
return (compilerOptions) => {
|
|
381
419
|
// target of 9 is ES2022 (using the number avoids an expensive import of typescript just for an enum)
|
|
@@ -433,6 +471,7 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
|
|
|
433
471
|
mapRoot: undefined,
|
|
434
472
|
sourceRoot: undefined,
|
|
435
473
|
preserveSymlinks,
|
|
474
|
+
externalRuntimeStyles: pluginOptions.externalRuntimeStyles,
|
|
436
475
|
};
|
|
437
476
|
};
|
|
438
477
|
}
|
|
@@ -22,7 +22,7 @@ export declare class ComponentStylesheetBundler {
|
|
|
22
22
|
* @param cache A load result cache to use when bundling.
|
|
23
23
|
*/
|
|
24
24
|
constructor(options: BundleStylesheetOptions, incremental: boolean);
|
|
25
|
-
bundleFile(entry: string): Promise<{
|
|
25
|
+
bundleFile(entry: string, externalId?: string | boolean): Promise<{
|
|
26
26
|
errors: import("esbuild").Message[] | undefined;
|
|
27
27
|
warnings: import("esbuild").Message[];
|
|
28
28
|
contents: string;
|
|
@@ -30,7 +30,7 @@ export declare class ComponentStylesheetBundler {
|
|
|
30
30
|
metafile: import("esbuild").Metafile | undefined;
|
|
31
31
|
referencedFiles: Set<string> | undefined;
|
|
32
32
|
}>;
|
|
33
|
-
bundleInline(data: string, filename: string, language: string): Promise<{
|
|
33
|
+
bundleInline(data: string, filename: string, language: string, externalId?: string): Promise<{
|
|
34
34
|
errors: import("esbuild").Message[] | undefined;
|
|
35
35
|
warnings: import("esbuild").Message[];
|
|
36
36
|
contents: string;
|
|
@@ -38,7 +38,12 @@ export declare class ComponentStylesheetBundler {
|
|
|
38
38
|
metafile: import("esbuild").Metafile | undefined;
|
|
39
39
|
referencedFiles: Set<string> | undefined;
|
|
40
40
|
}>;
|
|
41
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Invalidates both file and inline based component style bundling state for a set of modified files.
|
|
43
|
+
* @param files The group of files that have been modified
|
|
44
|
+
* @returns An array of file based stylesheet entries if any were invalidated; otherwise, undefined.
|
|
45
|
+
*/
|
|
46
|
+
invalidate(files: Iterable<string>): string[] | undefined;
|
|
42
47
|
dispose(): Promise<void>;
|
|
43
48
|
private extractResult;
|
|
44
49
|
}
|
|
@@ -11,6 +11,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.ComponentStylesheetBundler = void 0;
|
|
14
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
14
15
|
const node_crypto_1 = require("node:crypto");
|
|
15
16
|
const node_path_1 = __importDefault(require("node:path"));
|
|
16
17
|
const bundler_context_1 = require("../bundler-context");
|
|
@@ -35,21 +36,31 @@ class ComponentStylesheetBundler {
|
|
|
35
36
|
this.options = options;
|
|
36
37
|
this.incremental = incremental;
|
|
37
38
|
}
|
|
38
|
-
async bundleFile(entry) {
|
|
39
|
+
async bundleFile(entry, externalId) {
|
|
39
40
|
const bundlerContext = await this.#fileContexts.getOrCreate(entry, () => {
|
|
40
41
|
return new bundler_context_1.BundlerContext(this.options.workspaceRoot, this.incremental, (loadCache) => {
|
|
41
42
|
const buildOptions = (0, bundle_options_1.createStylesheetBundleOptions)(this.options, loadCache);
|
|
42
|
-
|
|
43
|
+
if (externalId) {
|
|
44
|
+
(0, node_assert_1.default)(typeof externalId === 'string', 'Initial external component stylesheets must have a string identifier');
|
|
45
|
+
buildOptions.entryPoints = { [externalId]: entry };
|
|
46
|
+
delete buildOptions.publicPath;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
buildOptions.entryPoints = [entry];
|
|
50
|
+
}
|
|
43
51
|
return buildOptions;
|
|
44
52
|
});
|
|
45
53
|
});
|
|
46
|
-
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles);
|
|
54
|
+
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles, !!externalId);
|
|
47
55
|
}
|
|
48
|
-
async bundleInline(data, filename, language) {
|
|
56
|
+
async bundleInline(data, filename, language, externalId) {
|
|
49
57
|
// Use a hash of the inline stylesheet content to ensure a consistent identifier. External stylesheets will resolve
|
|
50
58
|
// to the actual stylesheet file path.
|
|
51
59
|
// TODO: Consider xxhash instead for hashing
|
|
52
|
-
const id = (0, node_crypto_1.createHash)('sha256')
|
|
60
|
+
const id = (0, node_crypto_1.createHash)('sha256')
|
|
61
|
+
.update(data)
|
|
62
|
+
.update(externalId ?? '')
|
|
63
|
+
.digest('hex');
|
|
53
64
|
const entry = [language, id, filename].join(';');
|
|
54
65
|
const bundlerContext = await this.#inlineContexts.getOrCreate(entry, () => {
|
|
55
66
|
const namespace = 'angular:styles/component';
|
|
@@ -57,7 +68,13 @@ class ComponentStylesheetBundler {
|
|
|
57
68
|
const buildOptions = (0, bundle_options_1.createStylesheetBundleOptions)(this.options, loadCache, {
|
|
58
69
|
[entry]: data,
|
|
59
70
|
});
|
|
60
|
-
|
|
71
|
+
if (externalId) {
|
|
72
|
+
buildOptions.entryPoints = { [externalId]: `${namespace};${entry}` };
|
|
73
|
+
delete buildOptions.publicPath;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
buildOptions.entryPoints = [`${namespace};${entry}`];
|
|
77
|
+
}
|
|
61
78
|
buildOptions.plugins.push({
|
|
62
79
|
name: 'angular-component-styles',
|
|
63
80
|
setup(build) {
|
|
@@ -83,19 +100,29 @@ class ComponentStylesheetBundler {
|
|
|
83
100
|
});
|
|
84
101
|
});
|
|
85
102
|
// Extract the result of the bundling from the output files
|
|
86
|
-
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles);
|
|
103
|
+
return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles, !!externalId);
|
|
87
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Invalidates both file and inline based component style bundling state for a set of modified files.
|
|
107
|
+
* @param files The group of files that have been modified
|
|
108
|
+
* @returns An array of file based stylesheet entries if any were invalidated; otherwise, undefined.
|
|
109
|
+
*/
|
|
88
110
|
invalidate(files) {
|
|
89
111
|
if (!this.incremental) {
|
|
90
112
|
return;
|
|
91
113
|
}
|
|
92
114
|
const normalizedFiles = [...files].map(node_path_1.default.normalize);
|
|
93
|
-
|
|
94
|
-
|
|
115
|
+
let entries;
|
|
116
|
+
for (const [entry, bundler] of this.#fileContexts.entries()) {
|
|
117
|
+
if (bundler.invalidate(normalizedFiles)) {
|
|
118
|
+
entries ??= [];
|
|
119
|
+
entries.push(entry);
|
|
120
|
+
}
|
|
95
121
|
}
|
|
96
122
|
for (const bundler of this.#inlineContexts.values()) {
|
|
97
123
|
bundler.invalidate(normalizedFiles);
|
|
98
124
|
}
|
|
125
|
+
return entries;
|
|
99
126
|
}
|
|
100
127
|
async dispose() {
|
|
101
128
|
const contexts = [...this.#fileContexts.values(), ...this.#inlineContexts.values()];
|
|
@@ -103,7 +130,7 @@ class ComponentStylesheetBundler {
|
|
|
103
130
|
this.#inlineContexts.clear();
|
|
104
131
|
await Promise.allSettled(contexts.map((context) => context.dispose()));
|
|
105
132
|
}
|
|
106
|
-
extractResult(result, referencedFiles) {
|
|
133
|
+
extractResult(result, referencedFiles, external) {
|
|
107
134
|
let contents = '';
|
|
108
135
|
let metafile;
|
|
109
136
|
const outputFiles = [];
|
|
@@ -122,7 +149,15 @@ class ComponentStylesheetBundler {
|
|
|
122
149
|
outputFiles.push(clonedOutputFile);
|
|
123
150
|
}
|
|
124
151
|
else if (filename.endsWith('.css')) {
|
|
125
|
-
|
|
152
|
+
if (external) {
|
|
153
|
+
const clonedOutputFile = outputFile.clone();
|
|
154
|
+
clonedOutputFile.path = node_path_1.default.join(this.options.workspaceRoot, outputFile.path);
|
|
155
|
+
outputFiles.push(clonedOutputFile);
|
|
156
|
+
contents = node_path_1.default.posix.join(this.options.publicPath ?? '', filename);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
contents = outputFile.text;
|
|
160
|
+
}
|
|
126
161
|
}
|
|
127
162
|
else {
|
|
128
163
|
throw new Error(`Unexpected non CSS/Media file "${filename}" outputted during component stylesheet processing.`);
|
|
@@ -13,3 +13,4 @@ export declare function createBrowserCodeBundleOptions(options: NormalizedApplic
|
|
|
13
13
|
export declare function createBrowserPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache?: SourceFileCache): BuildOptions | BundlerOptionsFactory | undefined;
|
|
14
14
|
export declare function createServerPolyfillBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache?: SourceFileCache): BundlerOptionsFactory | undefined;
|
|
15
15
|
export declare function createServerMainCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache): BuildOptions;
|
|
16
|
+
export declare function createSsrEntryCodeBundleOptions(options: NormalizedApplicationBuildOptions, target: string[], sourceFileCache: SourceFileCache): BuildOptions;
|