@angular/build 19.0.0-next.0 → 19.0.0-next.10
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/LICENSE +5 -5
- package/package.json +20 -16
- package/src/builders/application/build-action.js +9 -9
- package/src/builders/application/chunk-optimizer.js +1 -4
- 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 +58 -20
- package/src/builders/application/i18n.d.ts +2 -2
- package/src/builders/application/i18n.js +6 -16
- package/src/builders/application/index.js +8 -5
- package/src/builders/application/options.d.ts +36 -1
- package/src/builders/application/options.js +60 -3
- 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 +12 -9
- 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 +8 -2
- package/src/builders/dev-server/vite-server.js +111 -56
- package/src/builders/extract-i18n/application-extraction.js +7 -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/jit-compilation.js +2 -1
- package/src/tools/angular/compilation/parallel-compilation.d.ts +2 -1
- package/src/tools/angular/compilation/parallel-compilation.js +2 -10
- package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
- package/src/tools/angular/compilation/parallel-worker.js +2 -1
- package/src/tools/babel/plugins/add-code-coverage.d.ts +14 -0
- package/src/tools/babel/plugins/add-code-coverage.js +44 -0
- package/src/tools/babel/plugins/types.d.ts +20 -0
- package/src/tools/esbuild/angular/compiler-plugin.d.ts +2 -0
- package/src/tools/esbuild/angular/compiler-plugin.js +46 -4
- 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/angular/file-reference-tracker.d.ts +1 -1
- package/src/tools/esbuild/application-code-bundle.d.ts +2 -6
- package/src/tools/esbuild/application-code-bundle.js +208 -92
- 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 +21 -13
- 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 +6 -1
- package/src/tools/esbuild/cache.js +7 -0
- package/src/tools/esbuild/compiler-plugin-options.js +3 -1
- package/src/tools/esbuild/i18n-inliner.js +4 -4
- package/src/tools/esbuild/javascript-transformer-worker.d.ts +1 -0
- package/src/tools/esbuild/javascript-transformer-worker.js +5 -1
- package/src/tools/esbuild/javascript-transformer.d.ts +2 -2
- package/src/tools/esbuild/javascript-transformer.js +7 -12
- package/src/tools/esbuild/utils.d.ts +9 -0
- package/src/tools/esbuild/utils.js +21 -3
- package/src/tools/sass/sass-service.js +11 -13
- package/src/tools/sass/worker.d.ts +13 -32
- package/src/tools/sass/worker.js +1 -0
- package/src/tools/vite/middlewares/assets-middleware.d.ts +1 -1
- package/src/tools/vite/middlewares/assets-middleware.js +43 -4
- package/src/tools/vite/middlewares/headers-middleware.d.ts +19 -0
- package/src/tools/vite/middlewares/headers-middleware.js +34 -0
- package/src/tools/vite/middlewares/html-fallback-middleware.d.ts +1 -1
- package/src/tools/vite/middlewares/html-fallback-middleware.js +23 -7
- package/src/tools/vite/middlewares/index-html-middleware.js +1 -2
- package/src/tools/vite/middlewares/index.d.ts +2 -1
- package/src/tools/vite/middlewares/index.js +5 -2
- package/src/tools/vite/middlewares/ssr-middleware.d.ts +2 -4
- package/src/tools/vite/middlewares/ssr-middleware.js +75 -43
- 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 -40
- 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/{utils/server-rendering/main-bundle-exports.js → tools/vite/plugins/ssr-transform-plugin.d.ts} +2 -2
- package/src/tools/vite/plugins/ssr-transform-plugin.js +38 -0
- package/src/tools/vite/utils.d.ts +0 -3
- package/src/tools/vite/utils.js +0 -12
- package/src/typings.d.ts +26 -0
- package/src/utils/environment-options.d.ts +2 -0
- package/src/utils/environment-options.js +5 -1
- package/src/utils/index-file/index-html-generator.js +5 -0
- package/src/utils/index-file/inline-critical-css.js +43 -33
- package/src/utils/index-file/ngcm-attribute.d.ts +15 -0
- package/src/utils/index-file/ngcm-attribute.js +37 -0
- package/src/utils/index-file/valid-self-closing-tags.js +28 -0
- package/src/utils/normalize-cache.js +1 -1
- package/src/utils/server-rendering/fetch-patch.d.ts +1 -1
- package/src/utils/server-rendering/fetch-patch.js +5 -6
- package/src/utils/server-rendering/launch-server.d.ts +14 -0
- package/src/utils/server-rendering/launch-server.js +63 -0
- package/src/utils/server-rendering/load-esm-from-memory.d.ts +18 -2
- package/src/utils/server-rendering/manifest.d.ts +50 -0
- package/src/utils/server-rendering/manifest.js +126 -0
- 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 +26 -10
- package/src/utils/server-rendering/prerender.js +126 -67
- package/src/utils/server-rendering/render-worker.d.ts +9 -8
- package/src/utils/server-rendering/render-worker.js +19 -14
- package/src/utils/server-rendering/routes-extractor-worker.d.ts +6 -10
- package/src/utils/server-rendering/routes-extractor-worker.js +16 -33
- package/src/utils/server-rendering/utils.d.ts +11 -0
- package/src/utils/server-rendering/utils.js +17 -0
- package/src/utils/worker-pool.d.ts +12 -0
- package/src/utils/worker-pool.js +43 -0
- package/src/tools/vite/angular-memory-plugin.d.ts +0 -21
- package/src/utils/server-rendering/main-bundle-exports.d.ts +0 -27
- package/src/utils/server-rendering/render-page.d.ts +0 -26
- package/src/utils/server-rendering/render-page.js +0 -114
- /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
|
@@ -12,12 +12,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.createBrowserCodeBundleOptions = createBrowserCodeBundleOptions;
|
|
14
14
|
exports.createBrowserPolyfillBundleOptions = createBrowserPolyfillBundleOptions;
|
|
15
|
-
exports.createServerCodeBundleOptions = createServerCodeBundleOptions;
|
|
16
15
|
exports.createServerPolyfillBundleOptions = createServerPolyfillBundleOptions;
|
|
16
|
+
exports.createServerMainCodeBundleOptions = createServerMainCodeBundleOptions;
|
|
17
|
+
exports.createSsrEntryCodeBundleOptions = createSsrEntryCodeBundleOptions;
|
|
17
18
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
18
19
|
const node_crypto_1 = require("node:crypto");
|
|
19
20
|
const node_path_1 = require("node:path");
|
|
20
21
|
const environment_options_1 = require("../../utils/environment-options");
|
|
22
|
+
const manifest_1 = require("../../utils/server-rendering/manifest");
|
|
21
23
|
const compiler_plugin_1 = require("./angular/compiler-plugin");
|
|
22
24
|
const compiler_plugin_options_1 = require("./compiler-plugin-options");
|
|
23
25
|
const external_packages_plugin_1 = require("./external-packages-plugin");
|
|
@@ -110,29 +112,28 @@ function createBrowserPolyfillBundleOptions(options, target, sourceFileCache) {
|
|
|
110
112
|
// cannot be used with fully incremental bundling yet.
|
|
111
113
|
return hasTypeScriptEntries ? buildOptions : () => buildOptions;
|
|
112
114
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
115
|
+
function createServerPolyfillBundleOptions(options, target, sourceFileCache) {
|
|
116
|
+
const serverPolyfills = [];
|
|
117
|
+
const polyfillsFromConfig = new Set(options.polyfills);
|
|
118
|
+
if (!(0, utils_1.isZonelessApp)(options.polyfills)) {
|
|
119
|
+
serverPolyfills.push('zone.js/node');
|
|
120
|
+
}
|
|
121
|
+
if (polyfillsFromConfig.has('@angular/localize') ||
|
|
122
|
+
polyfillsFromConfig.has('@angular/localize/init')) {
|
|
123
|
+
serverPolyfills.push('@angular/localize/init');
|
|
124
|
+
}
|
|
125
|
+
serverPolyfills.push('@angular/platform-server/init');
|
|
126
|
+
const namespace = 'angular:polyfills-server';
|
|
127
|
+
const polyfillBundleOptions = getEsBuildCommonPolyfillsOptions({
|
|
128
|
+
...options,
|
|
129
|
+
polyfills: serverPolyfills,
|
|
130
|
+
}, namespace, false, sourceFileCache);
|
|
131
|
+
if (!polyfillBundleOptions) {
|
|
132
|
+
return;
|
|
130
133
|
}
|
|
131
|
-
const zoneless = (0, utils_1.isZonelessApp)(polyfills);
|
|
132
134
|
const buildOptions = {
|
|
133
|
-
...
|
|
135
|
+
...polyfillBundleOptions,
|
|
134
136
|
platform: 'node',
|
|
135
|
-
splitting: true,
|
|
136
137
|
outExtension: { '.js': '.mjs' },
|
|
137
138
|
// Note: `es2015` is needed for RxJS v6. If not specified, `module` would
|
|
138
139
|
// match and the ES5 distribution would be bundled and ends up breaking at
|
|
@@ -140,14 +141,46 @@ function createServerCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
140
141
|
// More details: https://github.com/angular/angular-cli/issues/25405.
|
|
141
142
|
mainFields: ['es2020', 'es2015', 'module', 'main'],
|
|
142
143
|
entryNames: '[name]',
|
|
143
|
-
target,
|
|
144
144
|
banner: {
|
|
145
|
-
js:
|
|
145
|
+
js: [
|
|
146
|
+
// Note: Needed as esbuild does not provide require shims / proxy from ESModules.
|
|
147
|
+
// See: https://github.com/evanw/esbuild/issues/1921.
|
|
148
|
+
`import { createRequire } from 'node:module';`,
|
|
149
|
+
`globalThis['require'] ??= createRequire(import.meta.url);`,
|
|
150
|
+
].join('\n'),
|
|
146
151
|
},
|
|
152
|
+
target,
|
|
153
|
+
entryPoints: {
|
|
154
|
+
'polyfills.server': namespace,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
return () => buildOptions;
|
|
158
|
+
}
|
|
159
|
+
function createServerMainCodeBundleOptions(options, target, sourceFileCache) {
|
|
160
|
+
const { serverEntryPoint: mainServerEntryPoint, workspaceRoot, outputMode, externalPackages, ssrOptions, polyfills, } = options;
|
|
161
|
+
(0, node_assert_1.default)(mainServerEntryPoint, 'createServerCodeBundleOptions should not be called without a defined serverEntryPoint.');
|
|
162
|
+
const { pluginOptions, styleOptions } = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, target, sourceFileCache);
|
|
163
|
+
const mainServerNamespace = 'angular:main-server';
|
|
164
|
+
const mainServerInjectPolyfillsNamespace = 'angular:main-server-inject-polyfills';
|
|
165
|
+
const mainServerInjectManifestNamespace = 'angular:main-server-inject-manifest';
|
|
166
|
+
const zoneless = (0, utils_1.isZonelessApp)(polyfills);
|
|
167
|
+
const entryPoints = {
|
|
168
|
+
'main.server': mainServerNamespace,
|
|
169
|
+
};
|
|
170
|
+
const ssrEntryPoint = ssrOptions?.entry;
|
|
171
|
+
const isOldBehaviour = !outputMode;
|
|
172
|
+
if (ssrEntryPoint && isOldBehaviour) {
|
|
173
|
+
// Old behavior: 'server.ts' was bundled together with the SSR (Server-Side Rendering) code.
|
|
174
|
+
// This approach combined server-side logic and rendering into a single bundle.
|
|
175
|
+
entryPoints['server'] = ssrEntryPoint;
|
|
176
|
+
}
|
|
177
|
+
const buildOptions = {
|
|
178
|
+
...getEsBuildServerCommonOptions(options),
|
|
179
|
+
target,
|
|
180
|
+
inject: [mainServerInjectPolyfillsNamespace, mainServerInjectManifestNamespace],
|
|
147
181
|
entryPoints,
|
|
148
182
|
supported: (0, utils_1.getFeatureSupport)(target, zoneless),
|
|
149
183
|
plugins: [
|
|
150
|
-
(0, loader_import_attribute_plugin_1.createLoaderImportAttributePlugin)(),
|
|
151
184
|
(0, wasm_plugin_1.createWasmPlugin)({ allowAsync: zoneless, cache: sourceFileCache?.loadResultCache }),
|
|
152
185
|
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
153
186
|
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
@@ -164,20 +197,48 @@ function createServerCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
164
197
|
else {
|
|
165
198
|
buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
|
|
166
199
|
}
|
|
200
|
+
// Mark manifest and polyfills file as external as these are generated by a different bundle step.
|
|
201
|
+
(buildOptions.external ??= []).push(...utils_1.SERVER_GENERATED_EXTERNALS);
|
|
167
202
|
buildOptions.plugins.push((0, virtual_module_plugin_1.createVirtualModulePlugin)({
|
|
203
|
+
namespace: mainServerInjectPolyfillsNamespace,
|
|
204
|
+
cache: sourceFileCache?.loadResultCache,
|
|
205
|
+
loadContent: () => ({
|
|
206
|
+
contents: `import './polyfills.server.mjs';`,
|
|
207
|
+
loader: 'js',
|
|
208
|
+
resolveDir: workspaceRoot,
|
|
209
|
+
}),
|
|
210
|
+
}), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
|
|
211
|
+
namespace: mainServerInjectManifestNamespace,
|
|
212
|
+
cache: sourceFileCache?.loadResultCache,
|
|
213
|
+
loadContent: async () => {
|
|
214
|
+
const contents = [
|
|
215
|
+
// Configure `@angular/ssr` manifest.
|
|
216
|
+
`import manifest from './${manifest_1.SERVER_APP_MANIFEST_FILENAME}';`,
|
|
217
|
+
`import { ɵsetAngularAppManifest } from '@angular/ssr';`,
|
|
218
|
+
`ɵsetAngularAppManifest(manifest);`,
|
|
219
|
+
];
|
|
220
|
+
return {
|
|
221
|
+
contents: contents.join('\n'),
|
|
222
|
+
loader: 'js',
|
|
223
|
+
resolveDir: workspaceRoot,
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
}), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
|
|
168
227
|
namespace: mainServerNamespace,
|
|
169
228
|
cache: sourceFileCache?.loadResultCache,
|
|
170
229
|
loadContent: async () => {
|
|
230
|
+
const mainServerEntryPointJsImport = entryFileToWorkspaceRelative(workspaceRoot, mainServerEntryPoint);
|
|
171
231
|
const contents = [
|
|
172
|
-
|
|
173
|
-
`export {
|
|
232
|
+
// Re-export all symbols including default export from 'main.server.ts'
|
|
233
|
+
`export { default } from '${mainServerEntryPointJsImport}';`,
|
|
234
|
+
`export * from '${mainServerEntryPointJsImport}';`,
|
|
235
|
+
// Add @angular/ssr exports
|
|
236
|
+
`export {
|
|
237
|
+
ɵdestroyAngularServerApp,
|
|
238
|
+
ɵextractRoutesAndCreateRouteTree,
|
|
239
|
+
ɵgetOrCreateAngularServerApp,
|
|
240
|
+
} from '@angular/ssr';`,
|
|
174
241
|
];
|
|
175
|
-
if (watch) {
|
|
176
|
-
contents.push(`export { ɵresetCompiledComponents } from '@angular/core';`);
|
|
177
|
-
}
|
|
178
|
-
if (prerenderOptions?.discoverRoutes) {
|
|
179
|
-
contents.push(`export { ɵgetRoutesFromAngularRouterConfig } from '@angular/ssr';`);
|
|
180
|
-
}
|
|
181
242
|
return {
|
|
182
243
|
contents: contents.join('\n'),
|
|
183
244
|
loader: 'js',
|
|
@@ -190,27 +251,114 @@ function createServerCodeBundleOptions(options, target, sourceFileCache) {
|
|
|
190
251
|
}
|
|
191
252
|
return buildOptions;
|
|
192
253
|
}
|
|
193
|
-
function
|
|
194
|
-
const
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
254
|
+
function createSsrEntryCodeBundleOptions(options, target, sourceFileCache) {
|
|
255
|
+
const { workspaceRoot, ssrOptions, externalPackages } = options;
|
|
256
|
+
const serverEntryPoint = ssrOptions?.entry;
|
|
257
|
+
(0, node_assert_1.default)(serverEntryPoint, 'createSsrEntryCodeBundleOptions should not be called without a defined serverEntryPoint.');
|
|
258
|
+
const { pluginOptions, styleOptions } = (0, compiler_plugin_options_1.createCompilerPluginOptions)(options, target, sourceFileCache);
|
|
259
|
+
const ssrEntryNamespace = 'angular:ssr-entry';
|
|
260
|
+
const ssrInjectManifestNamespace = 'angular:ssr-entry-inject-manifest';
|
|
261
|
+
const ssrInjectRequireNamespace = 'angular:ssr-entry-inject-require';
|
|
262
|
+
const buildOptions = {
|
|
263
|
+
...getEsBuildServerCommonOptions(options),
|
|
264
|
+
target,
|
|
265
|
+
entryPoints: {
|
|
266
|
+
// TODO: consider renaming to index
|
|
267
|
+
'server': ssrEntryNamespace,
|
|
268
|
+
},
|
|
269
|
+
supported: (0, utils_1.getFeatureSupport)(target, true),
|
|
270
|
+
plugins: [
|
|
271
|
+
(0, sourcemap_ignorelist_plugin_1.createSourcemapIgnorelistPlugin)(),
|
|
272
|
+
(0, compiler_plugin_1.createCompilerPlugin)(
|
|
273
|
+
// JS/TS options
|
|
274
|
+
{ ...pluginOptions, noopTypeScriptCompilation: true },
|
|
275
|
+
// Component stylesheet options
|
|
276
|
+
styleOptions),
|
|
277
|
+
],
|
|
278
|
+
inject: [ssrInjectRequireNamespace, ssrInjectManifestNamespace],
|
|
279
|
+
};
|
|
280
|
+
buildOptions.plugins ??= [];
|
|
281
|
+
if (externalPackages) {
|
|
282
|
+
buildOptions.packages = 'external';
|
|
198
283
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
serverPolyfills.push('@angular/localize/init');
|
|
284
|
+
else {
|
|
285
|
+
buildOptions.plugins.push((0, rxjs_esm_resolution_plugin_1.createRxjsEsmResolutionPlugin)());
|
|
202
286
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
287
|
+
// Mark manifest file as external. As this will be generated later on.
|
|
288
|
+
(buildOptions.external ??= []).push('*/main.server.mjs', ...utils_1.SERVER_GENERATED_EXTERNALS);
|
|
289
|
+
buildOptions.plugins.push({
|
|
290
|
+
name: 'angular-ssr-metadata',
|
|
291
|
+
setup(build) {
|
|
292
|
+
build.onEnd((result) => {
|
|
293
|
+
if (result.metafile) {
|
|
294
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
295
|
+
result.metafile['ng-ssr-entry-bundle'] = true;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
},
|
|
299
|
+
}, (0, virtual_module_plugin_1.createVirtualModulePlugin)({
|
|
300
|
+
namespace: ssrInjectRequireNamespace,
|
|
301
|
+
cache: sourceFileCache?.loadResultCache,
|
|
302
|
+
loadContent: () => {
|
|
303
|
+
const contents = [
|
|
304
|
+
// Note: Needed as esbuild does not provide require shims / proxy from ESModules.
|
|
305
|
+
// See: https://github.com/evanw/esbuild/issues/1921.
|
|
306
|
+
`import { createRequire } from 'node:module';`,
|
|
307
|
+
`globalThis['require'] ??= createRequire(import.meta.url);`,
|
|
308
|
+
];
|
|
309
|
+
return {
|
|
310
|
+
contents: contents.join('\n'),
|
|
311
|
+
loader: 'js',
|
|
312
|
+
resolveDir: workspaceRoot,
|
|
313
|
+
};
|
|
314
|
+
},
|
|
315
|
+
}), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
|
|
316
|
+
namespace: ssrInjectManifestNamespace,
|
|
317
|
+
cache: sourceFileCache?.loadResultCache,
|
|
318
|
+
loadContent: () => {
|
|
319
|
+
const contents = [
|
|
320
|
+
// Configure `@angular/ssr` app engine manifest.
|
|
321
|
+
`import manifest from './${manifest_1.SERVER_APP_ENGINE_MANIFEST_FILENAME}';`,
|
|
322
|
+
`import { ɵsetAngularAppEngineManifest } from '@angular/ssr';`,
|
|
323
|
+
`ɵsetAngularAppEngineManifest(manifest);`,
|
|
324
|
+
];
|
|
325
|
+
return {
|
|
326
|
+
contents: contents.join('\n'),
|
|
327
|
+
loader: 'js',
|
|
328
|
+
resolveDir: workspaceRoot,
|
|
329
|
+
};
|
|
330
|
+
},
|
|
331
|
+
}), (0, virtual_module_plugin_1.createVirtualModulePlugin)({
|
|
332
|
+
namespace: ssrEntryNamespace,
|
|
333
|
+
cache: sourceFileCache?.loadResultCache,
|
|
334
|
+
loadContent: () => {
|
|
335
|
+
const serverEntryPointJsImport = entryFileToWorkspaceRelative(workspaceRoot, serverEntryPoint);
|
|
336
|
+
const contents = [
|
|
337
|
+
// Re-export all symbols including default export
|
|
338
|
+
`import * as server from '${serverEntryPointJsImport}';`,
|
|
339
|
+
`export * from '${serverEntryPointJsImport}';`,
|
|
340
|
+
// The below is needed to avoid
|
|
341
|
+
// `Import "default" will always be undefined because there is no matching export` warning when no default is present.
|
|
342
|
+
`const defaultExportName = 'default';`,
|
|
343
|
+
`export default server[defaultExportName]`,
|
|
344
|
+
// Add @angular/ssr exports
|
|
345
|
+
`export { AngularAppEngine } from '@angular/ssr';`,
|
|
346
|
+
];
|
|
347
|
+
return {
|
|
348
|
+
contents: contents.join('\n'),
|
|
349
|
+
loader: 'js',
|
|
350
|
+
resolveDir: workspaceRoot,
|
|
351
|
+
};
|
|
352
|
+
},
|
|
353
|
+
}));
|
|
354
|
+
if (options.plugins) {
|
|
355
|
+
buildOptions.plugins.push(...options.plugins);
|
|
211
356
|
}
|
|
212
|
-
|
|
213
|
-
|
|
357
|
+
return buildOptions;
|
|
358
|
+
}
|
|
359
|
+
function getEsBuildServerCommonOptions(options) {
|
|
360
|
+
return {
|
|
361
|
+
...getEsBuildCommonOptions(options),
|
|
214
362
|
platform: 'node',
|
|
215
363
|
outExtension: { '.js': '.mjs' },
|
|
216
364
|
// Note: `es2015` is needed for RxJS v6. If not specified, `module` would
|
|
@@ -219,31 +367,18 @@ function createServerPolyfillBundleOptions(options, target, sourceFileCache) {
|
|
|
219
367
|
// More details: https://github.com/angular/angular-cli/issues/25405.
|
|
220
368
|
mainFields: ['es2020', 'es2015', 'module', 'main'],
|
|
221
369
|
entryNames: '[name]',
|
|
222
|
-
banner: {
|
|
223
|
-
js: [
|
|
224
|
-
// Note: Needed as esbuild does not provide require shims / proxy from ESModules.
|
|
225
|
-
// See: https://github.com/evanw/esbuild/issues/1921.
|
|
226
|
-
`import { createRequire } from 'node:module';`,
|
|
227
|
-
`globalThis['require'] ??= createRequire(import.meta.url);`,
|
|
228
|
-
].join('\n'),
|
|
229
|
-
},
|
|
230
|
-
target,
|
|
231
|
-
entryPoints: {
|
|
232
|
-
'polyfills.server': namespace,
|
|
233
|
-
},
|
|
234
370
|
};
|
|
235
|
-
return () => buildOptions;
|
|
236
371
|
}
|
|
237
372
|
function getEsBuildCommonOptions(options) {
|
|
238
|
-
const { workspaceRoot, outExtension, optimizationOptions, sourcemapOptions, tsconfig, externalDependencies, outputNames, preserveSymlinks, jit, loaderExtensions, jsonLogs, } = options;
|
|
373
|
+
const { workspaceRoot, outExtension, optimizationOptions, sourcemapOptions, tsconfig, externalDependencies, outputNames, preserveSymlinks, jit, loaderExtensions, jsonLogs, i18nOptions, } = options;
|
|
239
374
|
// Ensure unique hashes for i18n translation changes when using post-process inlining.
|
|
240
375
|
// This hash value is added as a footer to each file and ensures that the output file names (with hashes)
|
|
241
376
|
// change when translation files have changed. If this is not done the post processed files may have
|
|
242
377
|
// different content but would retain identical production file names which would lead to browser caching problems.
|
|
243
378
|
let footer;
|
|
244
|
-
if (
|
|
379
|
+
if (i18nOptions.shouldInline) {
|
|
245
380
|
// Update file hashes to include translation file content
|
|
246
|
-
const i18nHash = Object.values(
|
|
381
|
+
const i18nHash = Object.values(i18nOptions.locales).reduce((data, locale) => data + locale.files.map((file) => file.integrity || '').join('|'), '');
|
|
247
382
|
footer = { js: `/**i18n:${(0, node_crypto_1.createHash)('sha256').update(i18nHash).digest('hex')}*/` };
|
|
248
383
|
}
|
|
249
384
|
return {
|
|
@@ -267,7 +402,7 @@ function getEsBuildCommonOptions(options) {
|
|
|
267
402
|
splitting: true,
|
|
268
403
|
chunkNames: options.namedChunks ? '[name]-[hash]' : 'chunk-[hash]',
|
|
269
404
|
tsconfig,
|
|
270
|
-
external: externalDependencies,
|
|
405
|
+
external: externalDependencies ? [...externalDependencies] : undefined,
|
|
271
406
|
write: false,
|
|
272
407
|
preserveSymlinks,
|
|
273
408
|
define: {
|
|
@@ -322,12 +457,10 @@ function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfi
|
|
|
322
457
|
namespace,
|
|
323
458
|
cache: sourceFileCache?.loadResultCache,
|
|
324
459
|
loadContent: async (_, build) => {
|
|
325
|
-
let hasLocalizePolyfill = false;
|
|
326
460
|
let polyfillPaths = polyfills;
|
|
327
461
|
let warnings;
|
|
328
462
|
if (tryToResolvePolyfillsAsRelative) {
|
|
329
463
|
polyfillPaths = await Promise.all(polyfills.map(async (path) => {
|
|
330
|
-
hasLocalizePolyfill ||= path.startsWith('@angular/localize');
|
|
331
464
|
if (path.startsWith('zone.js') || !(0, node_path_1.extname)(path)) {
|
|
332
465
|
return path;
|
|
333
466
|
}
|
|
@@ -339,29 +472,6 @@ function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfi
|
|
|
339
472
|
return result.path ? potentialPathRelative : path;
|
|
340
473
|
}));
|
|
341
474
|
}
|
|
342
|
-
else {
|
|
343
|
-
hasLocalizePolyfill = polyfills.some((p) => p.startsWith('@angular/localize'));
|
|
344
|
-
}
|
|
345
|
-
// Add localize polyfill if needed.
|
|
346
|
-
// TODO: remove in version 19 or later.
|
|
347
|
-
if (!i18nOptions.shouldInline && !hasLocalizePolyfill) {
|
|
348
|
-
const result = await build.resolve('@angular/localize', {
|
|
349
|
-
kind: 'import-statement',
|
|
350
|
-
resolveDir: workspaceRoot,
|
|
351
|
-
});
|
|
352
|
-
if (result.path) {
|
|
353
|
-
polyfillPaths.push('@angular/localize/init');
|
|
354
|
-
(warnings ??= []).push({
|
|
355
|
-
text: 'Polyfill for "@angular/localize/init" was added automatically.',
|
|
356
|
-
notes: [
|
|
357
|
-
{
|
|
358
|
-
text: 'In the future, this functionality will be removed. ' +
|
|
359
|
-
'Please add this polyfill in the "polyfills" section of your "angular.json" instead.',
|
|
360
|
-
},
|
|
361
|
-
],
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
475
|
// Generate module contents with an import statement per defined polyfill
|
|
366
476
|
let contents = polyfillPaths
|
|
367
477
|
.map((file) => `import '${file.replace(/\\/g, '/')}';`)
|
|
@@ -385,3 +495,9 @@ function getEsBuildCommonPolyfillsOptions(options, namespace, tryToResolvePolyfi
|
|
|
385
495
|
}));
|
|
386
496
|
return buildOptions;
|
|
387
497
|
}
|
|
498
|
+
function entryFileToWorkspaceRelative(workspaceRoot, entryFile) {
|
|
499
|
+
return ('./' +
|
|
500
|
+
(0, node_path_1.relative)(workspaceRoot, entryFile)
|
|
501
|
+
.replace(/.[mc]?ts$/, '')
|
|
502
|
+
.replace(/\\/g, '/'));
|
|
503
|
+
}
|
|
@@ -28,7 +28,7 @@ function generateBudgetStats(metafile, outputFiles, initialFiles) {
|
|
|
28
28
|
continue;
|
|
29
29
|
}
|
|
30
30
|
// Exclude server bundles
|
|
31
|
-
if (type === bundler_context_1.BuildOutputFileType.
|
|
31
|
+
if (type === bundler_context_1.BuildOutputFileType.ServerApplication || type === bundler_context_1.BuildOutputFileType.ServerRoot) {
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
34
34
|
const initialRecord = initialFiles.get(file);
|
|
@@ -31,9 +31,10 @@ export interface InitialFileRecord {
|
|
|
31
31
|
depth: number;
|
|
32
32
|
}
|
|
33
33
|
export declare enum BuildOutputFileType {
|
|
34
|
-
Browser =
|
|
35
|
-
Media =
|
|
36
|
-
|
|
34
|
+
Browser = 0,
|
|
35
|
+
Media = 1,
|
|
36
|
+
ServerApplication = 2,
|
|
37
|
+
ServerRoot = 3,
|
|
37
38
|
Root = 4
|
|
38
39
|
}
|
|
39
40
|
export interface BuildOutputFile extends OutputFile {
|
|
@@ -18,9 +18,10 @@ const load_result_cache_1 = require("./load-result-cache");
|
|
|
18
18
|
const utils_1 = require("./utils");
|
|
19
19
|
var BuildOutputFileType;
|
|
20
20
|
(function (BuildOutputFileType) {
|
|
21
|
-
BuildOutputFileType[BuildOutputFileType["Browser"] =
|
|
22
|
-
BuildOutputFileType[BuildOutputFileType["Media"] =
|
|
23
|
-
BuildOutputFileType[BuildOutputFileType["
|
|
21
|
+
BuildOutputFileType[BuildOutputFileType["Browser"] = 0] = "Browser";
|
|
22
|
+
BuildOutputFileType[BuildOutputFileType["Media"] = 1] = "Media";
|
|
23
|
+
BuildOutputFileType[BuildOutputFileType["ServerApplication"] = 2] = "ServerApplication";
|
|
24
|
+
BuildOutputFileType[BuildOutputFileType["ServerRoot"] = 3] = "ServerRoot";
|
|
24
25
|
BuildOutputFileType[BuildOutputFileType["Root"] = 4] = "Root";
|
|
25
26
|
})(BuildOutputFileType || (exports.BuildOutputFileType = BuildOutputFileType = {}));
|
|
26
27
|
/**
|
|
@@ -138,6 +139,7 @@ class BundlerContext {
|
|
|
138
139
|
}
|
|
139
140
|
return result;
|
|
140
141
|
}
|
|
142
|
+
// eslint-disable-next-line max-lines-per-function
|
|
141
143
|
async #performBundle() {
|
|
142
144
|
// Create esbuild options if not present
|
|
143
145
|
if (this.#esbuildOptions === undefined) {
|
|
@@ -165,12 +167,6 @@ class BundlerContext {
|
|
|
165
167
|
// For non-incremental builds, perform a single build
|
|
166
168
|
result = await (0, esbuild_1.build)(this.#esbuildOptions);
|
|
167
169
|
}
|
|
168
|
-
if (this.#platformIsServer) {
|
|
169
|
-
for (const entry of Object.values(result.metafile.outputs)) {
|
|
170
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
171
|
-
entry['ng-platform-server'] = true;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
170
|
}
|
|
175
171
|
catch (failure) {
|
|
176
172
|
// Build failures will throw an exception which contains errors/warnings
|
|
@@ -280,6 +276,7 @@ class BundlerContext {
|
|
|
280
276
|
for (const { imports } of Object.values(result.metafile.outputs)) {
|
|
281
277
|
for (const importData of imports) {
|
|
282
278
|
if (!importData.external ||
|
|
279
|
+
utils_1.SERVER_GENERATED_EXTERNALS.has(importData.path) ||
|
|
283
280
|
(importData.kind !== 'import-statement' &&
|
|
284
281
|
importData.kind !== 'dynamic-import' &&
|
|
285
282
|
importData.kind !== 'require-call')) {
|
|
@@ -295,13 +292,24 @@ class BundlerContext {
|
|
|
295
292
|
if (!/\.([cm]?js|css|wasm)(\.map)?$/i.test(file.path)) {
|
|
296
293
|
fileType = BuildOutputFileType.Media;
|
|
297
294
|
}
|
|
295
|
+
else if (this.#platformIsServer) {
|
|
296
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
297
|
+
fileType = result.metafile['ng-ssr-entry-bundle']
|
|
298
|
+
? BuildOutputFileType.ServerRoot
|
|
299
|
+
: BuildOutputFileType.ServerApplication;
|
|
300
|
+
}
|
|
298
301
|
else {
|
|
299
|
-
fileType =
|
|
300
|
-
? BuildOutputFileType.Server
|
|
301
|
-
: BuildOutputFileType.Browser;
|
|
302
|
+
fileType = BuildOutputFileType.Browser;
|
|
302
303
|
}
|
|
303
304
|
return (0, utils_1.convertOutputFile)(file, fileType);
|
|
304
305
|
});
|
|
306
|
+
let externalConfiguration = this.#esbuildOptions.external;
|
|
307
|
+
if (this.#platformIsServer && externalConfiguration) {
|
|
308
|
+
externalConfiguration = externalConfiguration.filter((dep) => !utils_1.SERVER_GENERATED_EXTERNALS.has(dep));
|
|
309
|
+
if (!externalConfiguration.length) {
|
|
310
|
+
externalConfiguration = undefined;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
305
313
|
// Return the successful build results
|
|
306
314
|
return {
|
|
307
315
|
...result,
|
|
@@ -310,7 +318,7 @@ class BundlerContext {
|
|
|
310
318
|
externalImports: {
|
|
311
319
|
[this.#platformIsServer ? 'server' : 'browser']: externalImports,
|
|
312
320
|
},
|
|
313
|
-
externalConfiguration
|
|
321
|
+
externalConfiguration,
|
|
314
322
|
errors: undefined,
|
|
315
323
|
};
|
|
316
324
|
}
|
|
@@ -24,6 +24,9 @@ export interface ExternalResultMetadata {
|
|
|
24
24
|
implicitServer: string[];
|
|
25
25
|
explicit: string[];
|
|
26
26
|
}
|
|
27
|
+
export type PrerenderedRoutesRecord = Record<string, {
|
|
28
|
+
headers?: Record<string, string>;
|
|
29
|
+
}>;
|
|
27
30
|
/**
|
|
28
31
|
* Represents the result of a single builder execute call.
|
|
29
32
|
*/
|
|
@@ -33,7 +36,7 @@ export declare class ExecutionResult {
|
|
|
33
36
|
outputFiles: BuildOutputFile[];
|
|
34
37
|
assetFiles: BuildOutputAsset[];
|
|
35
38
|
errors: (Message | PartialMessage)[];
|
|
36
|
-
prerenderedRoutes:
|
|
39
|
+
prerenderedRoutes: PrerenderedRoutesRecord;
|
|
37
40
|
warnings: (Message | PartialMessage)[];
|
|
38
41
|
logs: string[];
|
|
39
42
|
externalMetadata?: ExternalResultMetadata;
|
|
@@ -46,7 +49,7 @@ export declare class ExecutionResult {
|
|
|
46
49
|
addLog(value: string): void;
|
|
47
50
|
addError(error: PartialMessage | string): void;
|
|
48
51
|
addErrors(errors: (PartialMessage | string)[]): void;
|
|
49
|
-
addPrerenderedRoutes(routes:
|
|
52
|
+
addPrerenderedRoutes(routes: PrerenderedRoutesRecord): void;
|
|
50
53
|
addWarning(error: PartialMessage | string): void;
|
|
51
54
|
addWarnings(errors: (PartialMessage | string)[]): void;
|
|
52
55
|
/**
|
|
@@ -19,7 +19,7 @@ class ExecutionResult {
|
|
|
19
19
|
outputFiles = [];
|
|
20
20
|
assetFiles = [];
|
|
21
21
|
errors = [];
|
|
22
|
-
prerenderedRoutes =
|
|
22
|
+
prerenderedRoutes = {};
|
|
23
23
|
warnings = [];
|
|
24
24
|
logs = [];
|
|
25
25
|
externalMetadata;
|
|
@@ -53,9 +53,13 @@ class ExecutionResult {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
addPrerenderedRoutes(routes) {
|
|
56
|
-
this.prerenderedRoutes
|
|
56
|
+
Object.assign(this.prerenderedRoutes, routes);
|
|
57
57
|
// Sort the prerendered routes.
|
|
58
|
-
|
|
58
|
+
const sortedObj = {};
|
|
59
|
+
for (const key of Object.keys(this.prerenderedRoutes).sort()) {
|
|
60
|
+
sortedObj[key] = this.prerenderedRoutes[key];
|
|
61
|
+
}
|
|
62
|
+
this.prerenderedRoutes = sortedObj;
|
|
59
63
|
}
|
|
60
64
|
addWarning(error) {
|
|
61
65
|
if (typeof error === 'string') {
|
|
@@ -84,5 +84,10 @@ export declare class MemoryCache<V> extends Cache<V, Map<string, V>> {
|
|
|
84
84
|
* Provides all the values currently present in the cache instance.
|
|
85
85
|
* @returns An iterable of all values in the cache.
|
|
86
86
|
*/
|
|
87
|
-
values():
|
|
87
|
+
values(): MapIterator<V>;
|
|
88
|
+
/**
|
|
89
|
+
* Provides all the keys/values currently present in the cache instance.
|
|
90
|
+
* @returns An iterable of all key/value pairs in the cache.
|
|
91
|
+
*/
|
|
92
|
+
entries(): MapIterator<[string, V]>;
|
|
88
93
|
}
|
|
@@ -88,5 +88,12 @@ class MemoryCache extends Cache {
|
|
|
88
88
|
values() {
|
|
89
89
|
return this.store.values();
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Provides all the keys/values currently present in the cache instance.
|
|
93
|
+
* @returns An iterable of all key/value pairs in the cache.
|
|
94
|
+
*/
|
|
95
|
+
entries() {
|
|
96
|
+
return this.store.entries();
|
|
97
|
+
}
|
|
91
98
|
}
|
|
92
99
|
exports.MemoryCache = MemoryCache;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.createCompilerPluginOptions = createCompilerPluginOptions;
|
|
11
11
|
function createCompilerPluginOptions(options, target, sourceFileCache) {
|
|
12
|
-
const { workspaceRoot, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, inlineStyleLanguage, jit, cacheOptions, tailwindConfiguration, postcssConfiguration, publicPath, } = options;
|
|
12
|
+
const { workspaceRoot, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, inlineStyleLanguage, jit, cacheOptions, tailwindConfiguration, postcssConfiguration, publicPath, externalRuntimeStyles, instrumentForCoverage, } = options;
|
|
13
13
|
return {
|
|
14
14
|
// JS/TS options
|
|
15
15
|
pluginOptions: {
|
|
@@ -22,6 +22,8 @@ function createCompilerPluginOptions(options, target, sourceFileCache) {
|
|
|
22
22
|
sourceFileCache,
|
|
23
23
|
loadResultCache: sourceFileCache?.loadResultCache,
|
|
24
24
|
incremental: !!options.watch,
|
|
25
|
+
externalRuntimeStyles,
|
|
26
|
+
instrumentForCoverage,
|
|
25
27
|
},
|
|
26
28
|
// Component stylesheet options
|
|
27
29
|
styleOptions: {
|
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.I18nInliner = void 0;
|
|
14
14
|
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
|
-
const
|
|
15
|
+
const worker_pool_1 = require("../../utils/worker-pool");
|
|
16
16
|
const bundler_context_1 = require("./bundler-context");
|
|
17
17
|
const utils_1 = require("./utils");
|
|
18
18
|
/**
|
|
@@ -36,7 +36,8 @@ class I18nInliner {
|
|
|
36
36
|
const files = new Map();
|
|
37
37
|
const pendingMaps = [];
|
|
38
38
|
for (const file of options.outputFiles) {
|
|
39
|
-
if (file.type === bundler_context_1.BuildOutputFileType.Root) {
|
|
39
|
+
if (file.type === bundler_context_1.BuildOutputFileType.Root || file.type === bundler_context_1.BuildOutputFileType.ServerRoot) {
|
|
40
|
+
// Skip also the server entry-point.
|
|
40
41
|
// Skip stats and similar files.
|
|
41
42
|
continue;
|
|
42
43
|
}
|
|
@@ -74,7 +75,7 @@ class I18nInliner {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
this.#localizeFiles = files;
|
|
77
|
-
this.#workerPool = new
|
|
78
|
+
this.#workerPool = new worker_pool_1.WorkerPool({
|
|
78
79
|
filename: require.resolve('./i18n-inliner-worker'),
|
|
79
80
|
maxThreads,
|
|
80
81
|
// Extract options to ensure only the named options are serialized and sent to the worker
|
|
@@ -83,7 +84,6 @@ class I18nInliner {
|
|
|
83
84
|
shouldOptimize: options.shouldOptimize,
|
|
84
85
|
files,
|
|
85
86
|
},
|
|
86
|
-
recordTiming: false,
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
@@ -14,6 +14,7 @@ interface JavaScriptTransformRequest {
|
|
|
14
14
|
skipLinker?: boolean;
|
|
15
15
|
sideEffects?: boolean;
|
|
16
16
|
jit: boolean;
|
|
17
|
+
instrumentForCoverage?: boolean;
|
|
17
18
|
}
|
|
18
19
|
export default function transformJavaScript(request: JavaScriptTransformRequest): Promise<unknown>;
|
|
19
20
|
export {};
|