@angular-devkit/build-angular 18.0.0-next.1 → 18.0.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/package.json +20 -20
  2. package/src/builders/application/execute-build.js +2 -4
  3. package/src/builders/application/execute-post-bundle.js +9 -12
  4. package/src/builders/application/options.js +50 -32
  5. package/src/builders/browser/index.js +1 -1
  6. package/src/builders/dev-server/vite-server.js +3 -3
  7. package/src/builders/dev-server/webpack-server.js +2 -2
  8. package/src/builders/ssr-dev-server/index.js +29 -29
  9. package/src/tools/esbuild/angular/compiler-plugin.js +12 -4
  10. package/src/tools/esbuild/index-html-generator.d.ts +2 -2
  11. package/src/tools/esbuild/index-html-generator.js +5 -53
  12. package/src/tools/esbuild/javascript-transformer.js +5 -1
  13. package/src/tools/esbuild/stylesheets/css-resource-plugin.js +15 -8
  14. package/src/tools/esbuild/utils.js +2 -2
  15. package/src/tools/sass/rebasing-importer.js +3 -6
  16. package/src/tools/sass/sass-service.d.ts +24 -1
  17. package/src/tools/sass/worker.js +32 -4
  18. package/src/tools/webpack/plugins/any-component-style-budget-checker.d.ts +2 -2
  19. package/src/tools/webpack/plugins/any-component-style-budget-checker.js +13 -16
  20. package/src/tools/webpack/plugins/index-html-webpack-plugin.js +1 -1
  21. package/src/tools/webpack/utils/stats.d.ts +0 -13
  22. package/src/tools/webpack/utils/stats.js +3 -207
  23. package/src/utils/action-executor.d.ts +1 -1
  24. package/src/utils/bundle-calculator.d.ts +5 -5
  25. package/src/utils/bundle-calculator.js +8 -7
  26. package/src/utils/format-bytes.d.ts +8 -0
  27. package/src/utils/format-bytes.js +22 -0
  28. package/src/utils/i18n-inlining.d.ts +1 -1
  29. package/src/utils/i18n-options.d.ts +2 -9
  30. package/src/utils/i18n-options.js +4 -97
  31. package/src/utils/i18n-webpack.d.ts +16 -0
  32. package/src/utils/i18n-webpack.js +108 -0
  33. package/src/utils/index-file/add-event-dispatch-contract.d.ts +8 -0
  34. package/src/utils/index-file/add-event-dispatch-contract.js +28 -0
  35. package/src/utils/index-file/augment-index-html.js +1 -0
  36. package/src/utils/index-file/index-html-generator.d.ts +12 -2
  37. package/src/utils/index-file/index-html-generator.js +38 -22
  38. package/src/utils/index-file/inline-fonts.js +1 -1
  39. package/src/utils/index-file/{style-nonce.d.ts → nonce.d.ts} +2 -2
  40. package/src/utils/index-file/{style-nonce.js → nonce.js} +7 -5
  41. package/src/utils/load-proxy-config.d.ts +1 -1
  42. package/src/utils/load-proxy-config.js +2 -5
  43. package/src/utils/normalize-cache.js +1 -1
  44. package/src/utils/output-paths.d.ts +1 -1
  45. package/src/utils/postcss-configuration.d.ts +7 -1
  46. package/src/utils/postcss-configuration.js +13 -4
  47. package/src/utils/resolve-assets.d.ts +18 -0
  48. package/src/utils/resolve-assets.js +35 -0
  49. package/src/utils/stats-table.d.ts +20 -0
  50. package/src/utils/stats-table.js +205 -0
  51. package/src/utils/webpack-browser-config.d.ts +1 -1
  52. package/src/utils/webpack-browser-config.js +2 -2
package/package.json CHANGED
@@ -1,26 +1,26 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "18.0.0-next.1",
3
+ "version": "18.0.0-next.3",
4
4
  "description": "Angular Webpack Build Facade",
5
5
  "main": "src/index.js",
6
6
  "typings": "src/index.d.ts",
7
7
  "builders": "builders.json",
8
8
  "dependencies": {
9
9
  "@ampproject/remapping": "2.3.0",
10
- "@angular-devkit/architect": "0.1800.0-next.1",
11
- "@angular-devkit/build-webpack": "0.1800.0-next.1",
12
- "@angular-devkit/core": "18.0.0-next.1",
13
- "@babel/core": "7.24.3",
14
- "@babel/generator": "7.24.1",
10
+ "@angular-devkit/architect": "0.1800.0-next.3",
11
+ "@angular-devkit/build-webpack": "0.1800.0-next.3",
12
+ "@angular-devkit/core": "18.0.0-next.3",
13
+ "@babel/core": "7.24.4",
14
+ "@babel/generator": "7.24.4",
15
15
  "@babel/helper-annotate-as-pure": "7.22.5",
16
16
  "@babel/helper-split-export-declaration": "7.22.6",
17
17
  "@babel/plugin-transform-async-generator-functions": "7.24.3",
18
18
  "@babel/plugin-transform-async-to-generator": "7.24.1",
19
19
  "@babel/plugin-transform-runtime": "7.24.3",
20
- "@babel/preset-env": "7.24.3",
21
- "@babel/runtime": "7.24.1",
20
+ "@babel/preset-env": "7.24.4",
21
+ "@babel/runtime": "7.24.4",
22
22
  "@discoveryjs/json-ext": "0.5.7",
23
- "@ngtools/webpack": "18.0.0-next.1",
23
+ "@ngtools/webpack": "18.0.0-next.3",
24
24
  "@vitejs/plugin-basic-ssl": "1.1.0",
25
25
  "ansi-colors": "4.1.3",
26
26
  "autoprefixer": "10.4.19",
@@ -29,43 +29,43 @@
29
29
  "browserslist": "^4.21.5",
30
30
  "copy-webpack-plugin": "11.0.0",
31
31
  "critters": "0.0.22",
32
- "css-loader": "6.10.0",
32
+ "css-loader": "7.1.1",
33
33
  "esbuild-wasm": "0.20.2",
34
34
  "fast-glob": "3.3.2",
35
35
  "https-proxy-agent": "7.0.4",
36
- "http-proxy-middleware": "2.0.6",
37
- "inquirer": "9.2.16",
36
+ "http-proxy-middleware": "3.0.0",
37
+ "inquirer": "9.2.18",
38
38
  "jsonc-parser": "3.2.1",
39
39
  "karma-source-map-support": "1.4.0",
40
40
  "less": "4.2.0",
41
41
  "less-loader": "12.2.0",
42
42
  "license-webpack-plugin": "4.0.2",
43
43
  "loader-utils": "3.2.1",
44
- "magic-string": "0.30.8",
44
+ "magic-string": "0.30.9",
45
45
  "mini-css-extract-plugin": "2.8.1",
46
46
  "mrmime": "2.0.0",
47
47
  "open": "8.4.2",
48
48
  "ora": "5.4.1",
49
49
  "parse5-html-rewriting-stream": "7.0.0",
50
- "picomatch": "4.0.1",
50
+ "picomatch": "4.0.2",
51
51
  "piscina": "4.4.0",
52
52
  "postcss": "8.4.38",
53
53
  "postcss-loader": "8.1.1",
54
54
  "resolve-url-loader": "5.0.0",
55
55
  "rxjs": "7.8.1",
56
- "sass": "1.72.0",
57
- "sass-loader": "14.1.1",
56
+ "sass": "1.75.0",
57
+ "sass-loader": "14.2.0",
58
58
  "semver": "7.6.0",
59
59
  "source-map-loader": "5.0.0",
60
60
  "source-map-support": "0.5.21",
61
- "terser": "5.29.2",
61
+ "terser": "5.30.3",
62
62
  "tree-kill": "1.2.2",
63
63
  "tslib": "2.6.2",
64
- "undici": "6.10.1",
65
- "vite": "5.2.6",
64
+ "undici": "6.13.0",
65
+ "vite": "5.2.9",
66
66
  "watchpack": "2.4.1",
67
67
  "webpack": "5.91.0",
68
- "webpack-dev-middleware": "7.1.1",
68
+ "webpack-dev-middleware": "7.2.1",
69
69
  "webpack-dev-server": "5.0.4",
70
70
  "webpack-merge": "5.10.0",
71
71
  "webpack-subresource-integrity": "5.1.0"
@@ -16,7 +16,7 @@ const commonjs_checker_1 = require("../../tools/esbuild/commonjs-checker");
16
16
  const license_extractor_1 = require("../../tools/esbuild/license-extractor");
17
17
  const utils_1 = require("../../tools/esbuild/utils");
18
18
  const bundle_calculator_1 = require("../../utils/bundle-calculator");
19
- const copy_assets_1 = require("../../utils/copy-assets");
19
+ const resolve_assets_1 = require("../../utils/resolve-assets");
20
20
  const supported_browsers_1 = require("../../utils/supported-browsers");
21
21
  const execute_post_bundle_1 = require("./execute-post-bundle");
22
22
  const i18n_1 = require("./i18n");
@@ -86,9 +86,7 @@ async function executeBuild(options, context, rebuildState) {
86
86
  }
87
87
  // Copy assets
88
88
  if (assets) {
89
- // The webpack copy assets helper is used with no base paths defined. This prevents the helper
90
- // from directly writing to disk. This should eventually be replaced with a more optimized helper.
91
- executionResult.addAssets(await (0, copy_assets_1.copyAssets)(assets, [], workspaceRoot));
89
+ executionResult.addAssets(await (0, resolve_assets_1.resolveAssets)(assets, workspaceRoot));
92
90
  }
93
91
  // Extract and write licenses for used packages
94
92
  if (options.extractLicenses) {
@@ -32,37 +32,34 @@ async function executePostBundleSteps(options, outputFiles, assetFiles, initialF
32
32
  const allErrors = [];
33
33
  const allWarnings = [];
34
34
  const prerenderedRoutes = [];
35
- const { serviceWorker, indexHtmlOptions, optimizationOptions, sourcemapOptions, ssrOptions, prerenderOptions, appShellOptions, workspaceRoot, verbose, } = options;
35
+ const { serviceWorker, indexHtmlOptions, optimizationOptions, sourcemapOptions, prerenderOptions, appShellOptions, workspaceRoot, verbose, } = options;
36
36
  /**
37
37
  * Index HTML content without CSS inlining to be used for server rendering (AppShell, SSG and SSR).
38
38
  *
39
39
  * NOTE: we don't perform critical CSS inlining as this will be done during server rendering.
40
40
  */
41
- let indexContentOutputNoCssInlining;
41
+ let ssrIndexContent;
42
42
  // When using prerender/app-shell the index HTML file can be regenerated.
43
43
  // Thus, we use a Map so that we do not generate 2 files with the same filename.
44
44
  const additionalHtmlOutputFiles = new Map();
45
45
  // Generate index HTML file
46
46
  // If localization is enabled, index generation is handled in the inlining process.
47
47
  if (indexHtmlOptions) {
48
- const { content, contentWithoutCriticalCssInlined, errors, warnings } = await (0, index_html_generator_1.generateIndexHtml)(initialFiles, outputFiles, {
49
- ...options,
50
- optimizationOptions,
51
- }, locale);
52
- indexContentOutputNoCssInlining = contentWithoutCriticalCssInlined;
48
+ const { csrContent, ssrContent, errors, warnings } = await (0, index_html_generator_1.generateIndexHtml)(initialFiles, outputFiles, options, locale);
53
49
  allErrors.push(...errors);
54
50
  allWarnings.push(...warnings);
55
- additionalHtmlOutputFiles.set(indexHtmlOptions.output, (0, utils_1.createOutputFileFromText)(indexHtmlOptions.output, content, bundler_context_1.BuildOutputFileType.Browser));
56
- if (ssrOptions) {
51
+ additionalHtmlOutputFiles.set(indexHtmlOptions.output, (0, utils_1.createOutputFileFromText)(indexHtmlOptions.output, csrContent, bundler_context_1.BuildOutputFileType.Browser));
52
+ if (ssrContent) {
57
53
  const serverIndexHtmlFilename = 'index.server.html';
58
- additionalHtmlOutputFiles.set(serverIndexHtmlFilename, (0, utils_1.createOutputFileFromText)(serverIndexHtmlFilename, contentWithoutCriticalCssInlined, bundler_context_1.BuildOutputFileType.Server));
54
+ additionalHtmlOutputFiles.set(serverIndexHtmlFilename, (0, utils_1.createOutputFileFromText)(serverIndexHtmlFilename, ssrContent, bundler_context_1.BuildOutputFileType.Server));
55
+ ssrIndexContent = ssrContent;
59
56
  }
60
57
  }
61
58
  // Pre-render (SSG) and App-shell
62
59
  // If localization is enabled, prerendering is handled in the inlining process.
63
60
  if (prerenderOptions || appShellOptions) {
64
- (0, node_assert_1.default)(indexContentOutputNoCssInlining, 'The "index" option is required when using the "ssg" or "appShell" options.');
65
- const { output, warnings, errors, prerenderedRoutes: generatedRoutes, } = await (0, prerender_1.prerenderPages)(workspaceRoot, appShellOptions, prerenderOptions, outputFiles, assetFiles, indexContentOutputNoCssInlining, sourcemapOptions.scripts, optimizationOptions.styles.inlineCritical, environment_options_1.maxWorkers, verbose);
61
+ (0, node_assert_1.default)(ssrIndexContent, 'The "index" option is required when using the "ssg" or "appShell" options.');
62
+ const { output, warnings, errors, prerenderedRoutes: generatedRoutes, } = await (0, prerender_1.prerenderPages)(workspaceRoot, appShellOptions, prerenderOptions, outputFiles, assetFiles, ssrIndexContent, sourcemapOptions.scripts, optimizationOptions.styles.inlineCritical, environment_options_1.maxWorkers, verbose);
66
63
  allErrors.push(...errors);
67
64
  allWarnings.push(...warnings);
68
65
  prerenderedRoutes.push(...Array.from(generatedRoutes));
@@ -21,7 +21,6 @@ const environment_options_1 = require("../../utils/environment-options");
21
21
  const i18n_options_1 = require("../../utils/i18n-options");
22
22
  const normalize_cache_1 = require("../../utils/normalize-cache");
23
23
  const postcss_configuration_1 = require("../../utils/postcss-configuration");
24
- const tailwind_1 = require("../../utils/tailwind");
25
24
  const schema_1 = require("./schema");
26
25
  /**
27
26
  * Normalize the user provided options by creating full paths for all path based options
@@ -108,34 +107,13 @@ async function normalizeOptions(context, projectName, options, extensions) {
108
107
  loaderExtensions[extension] = value;
109
108
  }
110
109
  }
111
- const postcssConfiguration = await (0, postcss_configuration_1.loadPostcssConfiguration)(workspaceRoot, projectRoot);
110
+ // A configuration file can exist in the project or workspace root
111
+ const searchDirectories = await (0, postcss_configuration_1.generateSearchDirectories)([projectRoot, workspaceRoot]);
112
+ const postcssConfiguration = await (0, postcss_configuration_1.loadPostcssConfiguration)(searchDirectories);
112
113
  // Skip tailwind configuration if postcss is customized
113
114
  const tailwindConfiguration = postcssConfiguration
114
115
  ? undefined
115
- : await getTailwindConfig(workspaceRoot, projectRoot, context);
116
- const globalStyles = normalizeGlobalEntries(options.styles, 'styles');
117
- const globalScripts = normalizeGlobalEntries(options.scripts, 'scripts');
118
- let indexHtmlOptions;
119
- // index can never have a value of `true` but in the schema it's of type `boolean`.
120
- if (typeof options.index !== 'boolean') {
121
- indexHtmlOptions = {
122
- input: node_path_1.default.join(workspaceRoot, typeof options.index === 'string' ? options.index : options.index.input),
123
- // The output file will be created within the configured output path
124
- output: typeof options.index === 'string'
125
- ? node_path_1.default.basename(options.index)
126
- : options.index.output || 'index.html',
127
- insertionOrder: [
128
- ['polyfills', true],
129
- ...globalStyles.filter((s) => s.initial).map((s) => [s.name, false]),
130
- ...globalScripts.filter((s) => s.initial).map((s) => [s.name, false]),
131
- ['main', true],
132
- // [name, esm]
133
- ],
134
- transformer: extensions?.indexHtmlTransformer,
135
- // Preload initial defaults to true
136
- preloadInitial: typeof options.index !== 'object' || (options.index.preloadInitial ?? true),
137
- };
138
- }
116
+ : await getTailwindConfig(searchDirectories, workspaceRoot, context);
139
117
  let serverEntryPoint;
140
118
  if (options.server) {
141
119
  serverEntryPoint = node_path_1.default.join(workspaceRoot, options.server);
@@ -167,8 +145,48 @@ async function normalizeOptions(context, projectName, options, extensions) {
167
145
  route: 'shell',
168
146
  };
169
147
  }
170
- if ((appShellOptions || ssrOptions || prerenderOptions) && !serverEntryPoint) {
171
- throw new Error('The "server" option is required when enabling "ssr", "prerender" or "app-shell".');
148
+ const globalStyles = normalizeGlobalEntries(options.styles, 'styles');
149
+ const globalScripts = normalizeGlobalEntries(options.scripts, 'scripts');
150
+ let indexHtmlOptions;
151
+ // index can never have a value of `true` but in the schema it's of type `boolean`.
152
+ if (typeof options.index !== 'boolean') {
153
+ let indexOutput;
154
+ // The output file will be created within the configured output path
155
+ if (typeof options.index === 'string') {
156
+ /**
157
+ * If SSR is activated, create a distinct entry file for the `index.html`.
158
+ * This is necessary because numerous server/cloud providers automatically serve the `index.html` as a static file
159
+ * if it exists (handling SSG).
160
+ * For instance, accessing `foo.com/` would lead to `foo.com/index.html` being served instead of hitting the server.
161
+ */
162
+ const indexBaseName = node_path_1.default.basename(options.index);
163
+ indexOutput = ssrOptions && indexBaseName === 'index.html' ? 'index.csr.html' : indexBaseName;
164
+ }
165
+ else {
166
+ indexOutput = options.index.output || 'index.html';
167
+ }
168
+ indexHtmlOptions = {
169
+ input: node_path_1.default.join(workspaceRoot, typeof options.index === 'string' ? options.index : options.index.input),
170
+ output: indexOutput,
171
+ insertionOrder: [
172
+ ['polyfills', true],
173
+ ...globalStyles.filter((s) => s.initial).map((s) => [s.name, false]),
174
+ ...globalScripts.filter((s) => s.initial).map((s) => [s.name, false]),
175
+ ['main', true],
176
+ // [name, esm]
177
+ ],
178
+ transformer: extensions?.indexHtmlTransformer,
179
+ // Preload initial defaults to true
180
+ preloadInitial: typeof options.index !== 'object' || (options.index.preloadInitial ?? true),
181
+ };
182
+ }
183
+ if (appShellOptions || ssrOptions || prerenderOptions) {
184
+ if (!serverEntryPoint) {
185
+ throw new Error('The "server" option is required when enabling "ssr", "prerender" or "app-shell".');
186
+ }
187
+ if (!indexHtmlOptions) {
188
+ throw new Error('The "index" option cannot be set to false when enabling "ssr", "prerender" or "app-shell".');
189
+ }
172
190
  }
173
191
  // Initial options to keep
174
192
  const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, statsJson, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, deleteOutputPath, namedChunks, budgets, deployUrl, clearScreen, define, } = options;
@@ -230,13 +248,13 @@ async function normalizeOptions(context, projectName, options, extensions) {
230
248
  };
231
249
  }
232
250
  exports.normalizeOptions = normalizeOptions;
233
- async function getTailwindConfig(workspaceRoot, projectRoot, context) {
234
- const tailwindConfigurationPath = await (0, tailwind_1.findTailwindConfigurationFile)(workspaceRoot, projectRoot);
251
+ async function getTailwindConfig(searchDirectories, workspaceRoot, context) {
252
+ const tailwindConfigurationPath = (0, postcss_configuration_1.findTailwindConfiguration)(searchDirectories);
235
253
  if (!tailwindConfigurationPath) {
236
254
  return undefined;
237
255
  }
238
- // Create a node resolver at the project root as a directory
239
- const resolver = (0, node_module_1.createRequire)(projectRoot + '/');
256
+ // Create a node resolver from the configuration file
257
+ const resolver = (0, node_module_1.createRequire)(tailwindConfigurationPath);
240
258
  try {
241
259
  return {
242
260
  file: tailwindConfigurationPath,
@@ -229,7 +229,7 @@ function buildWebpackBrowser(options, context, transforms = {}) {
229
229
  let hasErrors = false;
230
230
  for (const [locale, outputPath] of outputPaths.entries()) {
231
231
  try {
232
- const { content, warnings, errors } = await indexHtmlGenerator.process({
232
+ const { csrContent: content, warnings, errors, } = await indexHtmlGenerator.process({
233
233
  baseHref: getLocaleBaseHref(i18n, locale) ?? options.baseHref,
234
234
  // i18nLocale is used when Ivy is disabled
235
235
  lang: locale || undefined,
@@ -260,7 +260,7 @@ function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logg
260
260
  if (serverOptions.liveReload || serverOptions.hmr) {
261
261
  if (updatedFiles.every((f) => f.endsWith('.css'))) {
262
262
  const timestamp = Date.now();
263
- server.ws.send({
263
+ server.hot.send({
264
264
  type: 'update',
265
265
  updates: updatedFiles.map((filePath) => {
266
266
  return {
@@ -277,7 +277,7 @@ function handleUpdate(normalizePath, generatedFiles, server, serverOptions, logg
277
277
  }
278
278
  // Send reload command to clients
279
279
  if (serverOptions.liveReload) {
280
- server.ws.send({
280
+ server.hot.send({
281
281
  type: 'full-reload',
282
282
  path: '*',
283
283
  });
@@ -332,7 +332,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
332
332
  }
333
333
  }
334
334
  async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssr, prebundleTransformer, target, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
335
- const proxy = await (0, utils_2.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig, true);
335
+ const proxy = await (0, utils_2.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig);
336
336
  // dynamically import Vite for ESM compatibility
337
337
  const { normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
338
338
  // Path will not exist on disk and only used to provide separate path for Vite requests
@@ -42,7 +42,7 @@ const service_worker_plugin_1 = require("../../tools/webpack/plugins/service-wor
42
42
  const stats_1 = require("../../tools/webpack/utils/stats");
43
43
  const utils_1 = require("../../utils");
44
44
  const color_1 = require("../../utils/color");
45
- const i18n_options_1 = require("../../utils/i18n-options");
45
+ const i18n_webpack_1 = require("../../utils/i18n-webpack");
46
46
  const load_translations_1 = require("../../utils/load-translations");
47
47
  const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
48
48
  const version_1 = require("../../utils/version");
@@ -266,7 +266,7 @@ async function setupLocalize(locale, i18n, browserOptions, webpackConfig, cacheO
266
266
  compiler.hooks.thisCompilation.tap('build-angular', (compilation) => {
267
267
  if (i18n.shouldInline && i18nLoaderOptions.translation === undefined) {
268
268
  // Reload translations
269
- (0, i18n_options_1.loadTranslations)(locale, localeDescription, context.workspaceRoot, loader, {
269
+ (0, i18n_webpack_1.loadTranslations)(locale, localeDescription, context.workspaceRoot, loader, {
270
270
  warn(message) {
271
271
  (0, webpack_diagnostics_1.addWarning)(compilation, message);
272
272
  },
@@ -156,7 +156,7 @@ exports.log = log;
156
156
  function startNodeServer(serverOutput, port, logger, inspectMode = false) {
157
157
  const outputPath = serverOutput.outputPath;
158
158
  const path = (0, path_1.join)(outputPath, 'main.js');
159
- const env = { ...process.env, SSR_PORT: '' + port, PORT: '' + port };
159
+ const env = { ...process.env, PORT: '' + port };
160
160
  const args = ['--enable-source-maps', `"${path}"`];
161
161
  if (inspectMode) {
162
162
  args.unshift('--inspect-brk');
@@ -223,21 +223,24 @@ async function initBrowserSync(browserSyncInstance, nodeServerPort, options, con
223
223
  if (hasPathname) {
224
224
  const { createProxyMiddleware } = await Promise.resolve().then(() => __importStar(require('http-proxy-middleware')));
225
225
  // Remove leading slash
226
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
227
- (bsOptions.scriptPath = (p) => p.substring(1)),
228
- (bsOptions.middleware = [
229
- createProxyMiddleware(defaultSocketIoPath, {
230
- target: url.format({
231
- protocol: 'http',
232
- hostname: host,
233
- port: bsPort,
234
- pathname: path,
235
- }),
236
- ws: true,
237
- logLevel: 'silent',
238
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
226
+ bsOptions.scriptPath = (p) => p.substring(1);
227
+ bsOptions.middleware = [
228
+ createProxyMiddleware({
229
+ pathFilter: defaultSocketIoPath,
230
+ target: url.format({
231
+ protocol: 'http',
232
+ hostname: host,
233
+ port: bsPort,
234
+ pathname: path,
239
235
  }),
240
- ]);
236
+ ws: true,
237
+ logger: {
238
+ info: () => { },
239
+ warn: () => { },
240
+ error: () => { },
241
+ },
242
+ }),
243
+ ];
241
244
  }
242
245
  }
243
246
  if (proxyConfig) {
@@ -283,21 +286,18 @@ function getSslConfig(root, options) {
283
286
  return ssl;
284
287
  }
285
288
  async function getProxyConfig(root, proxyConfig) {
286
- const proxy = await (0, utils_1.loadProxyConfiguration)(root, proxyConfig, false);
287
- const createdProxies = [];
289
+ const proxy = await (0, utils_1.loadProxyConfiguration)(root, proxyConfig);
290
+ if (!proxy) {
291
+ return [];
292
+ }
288
293
  const { createProxyMiddleware } = await Promise.resolve().then(() => __importStar(require('http-proxy-middleware')));
289
- for (const [key, context] of Object.entries(proxy)) {
290
- if (typeof key === 'string') {
291
- createdProxies.push(createProxyMiddleware(key.replace(/^\*$/, '**').replace(/\/\*$/, ''),
292
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
293
- context));
294
- }
295
- else {
296
- createdProxies.push(
294
+ return Object.entries(proxy).map(([key, context]) => {
295
+ const filterRegExp = new RegExp(key);
296
+ return createProxyMiddleware({
297
+ pathFilter: (pathname) => filterRegExp.test(pathname),
297
298
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
298
- createProxyMiddleware(key, context));
299
- }
300
- }
301
- return createdProxies;
299
+ ...context,
300
+ });
301
+ });
302
302
  }
303
303
  exports.default = (0, architect_1.createBuilder)(execute);
@@ -341,16 +341,16 @@ exports.createCompilerPlugin = createCompilerPlugin;
341
341
  function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks) {
342
342
  return (compilerOptions) => {
343
343
  // target of 9 is ES2022 (using the number avoids an expensive import of typescript just for an enum)
344
- if (compilerOptions.target === undefined || compilerOptions.target < 9) {
344
+ if (compilerOptions.target === undefined || compilerOptions.target < 9 /** ES2022 */) {
345
345
  // If 'useDefineForClassFields' is already defined in the users project leave the value as is.
346
346
  // Otherwise fallback to false due to https://github.com/microsoft/TypeScript/issues/45995
347
347
  // which breaks the deprecated `@Effects` NGRX decorator and potentially other existing code as well.
348
- compilerOptions.target = 9;
348
+ compilerOptions.target = 9 /** ES2022 */;
349
349
  compilerOptions.useDefineForClassFields ??= false;
350
350
  // Only add the warning on the initial build
351
351
  setupWarnings?.push({
352
- text: 'TypeScript compiler options "target" and "useDefineForClassFields" are set to "ES2022" and ' +
353
- '"false" respectively by the Angular CLI.',
352
+ text: `TypeScript compiler options 'target' and 'useDefineForClassFields' are set to 'ES2022' and ` +
353
+ `'false' respectively by the Angular CLI.`,
354
354
  location: { file: pluginOptions.tsconfig },
355
355
  notes: [
356
356
  {
@@ -377,6 +377,14 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
377
377
  else {
378
378
  compilerOptions.incremental = false;
379
379
  }
380
+ if (compilerOptions.module === undefined || compilerOptions.module < 5 /** ES2015 */) {
381
+ compilerOptions.module = 7; /** ES2022 */
382
+ setupWarnings?.push({
383
+ text: `TypeScript compiler options 'module' values 'CommonJS', 'UMD', 'System' and 'AMD' are not supported.`,
384
+ location: null,
385
+ notes: [{ text: `The 'module' option will be set to 'ES2022' instead.` }],
386
+ });
387
+ }
380
388
  return {
381
389
  ...compilerOptions,
382
390
  noEmitOnError: false,
@@ -8,8 +8,8 @@
8
8
  import { NormalizedApplicationBuildOptions } from '../../builders/application/options';
9
9
  import { BuildOutputFile, InitialFileRecord } from './bundler-context';
10
10
  export declare function generateIndexHtml(initialFiles: Map<string, InitialFileRecord>, outputFiles: BuildOutputFile[], buildOptions: NormalizedApplicationBuildOptions, lang?: string): Promise<{
11
- content: string;
12
- contentWithoutCriticalCssInlined: string;
11
+ csrContent: string;
12
+ ssrContent?: string;
13
13
  warnings: string[];
14
14
  errors: string[];
15
15
  }>;
@@ -6,29 +6,6 @@
6
6
  * Use of this source code is governed by an MIT-style license that can be
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- var desc = Object.getOwnPropertyDescriptor(m, k);
12
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
- desc = { enumerable: true, get: function() { return m[k]; } };
14
- }
15
- Object.defineProperty(o, k2, desc);
16
- }) : (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- o[k2] = m[k];
19
- }));
20
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
- Object.defineProperty(o, "default", { enumerable: true, value: v });
22
- }) : function(o, v) {
23
- o["default"] = v;
24
- });
25
- var __importStar = (this && this.__importStar) || function (mod) {
26
- if (mod && mod.__esModule) return mod;
27
- var result = {};
28
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
- __setModuleDefault(result, mod);
30
- return result;
31
- };
32
9
  var __importDefault = (this && this.__importDefault) || function (mod) {
33
10
  return (mod && mod.__esModule) ? mod : { "default": mod };
34
11
  };
@@ -78,19 +55,16 @@ async function generateIndexHtml(initialFiles, outputFiles, buildOptions, lang)
78
55
  indexPath: indexHtmlOptions.input,
79
56
  entrypoints: indexHtmlOptions.insertionOrder,
80
57
  sri: subresourceIntegrity,
81
- optimization: {
82
- ...optimizationOptions,
83
- styles: {
84
- ...optimizationOptions.styles,
85
- inlineCritical: false, // Disable critical css inline as for SSR and SSG this will be done during rendering.
86
- },
87
- },
58
+ optimization: optimizationOptions,
88
59
  crossOrigin: crossOrigin,
89
60
  deployUrl: buildOptions.publicPath,
90
61
  postTransform: indexHtmlOptions.transformer,
62
+ generateDedicatedSSRContent: !!(buildOptions.ssrOptions ||
63
+ buildOptions.prerenderOptions ||
64
+ buildOptions.appShellOptions),
91
65
  });
92
66
  indexHtmlGenerator.readAsset = readAsset;
93
- const transformResult = await indexHtmlGenerator.process({
67
+ return indexHtmlGenerator.process({
94
68
  baseHref,
95
69
  lang,
96
70
  outputPath: virtualOutputPath,
@@ -103,27 +77,5 @@ async function generateIndexHtml(initialFiles, outputFiles, buildOptions, lang)
103
77
  })),
104
78
  hints,
105
79
  });
106
- const contentWithoutCriticalCssInlined = transformResult.content;
107
- if (!optimizationOptions.styles.inlineCritical) {
108
- return {
109
- ...transformResult,
110
- contentWithoutCriticalCssInlined,
111
- };
112
- }
113
- const { InlineCriticalCssProcessor } = await Promise.resolve().then(() => __importStar(require('../../utils/index-file/inline-critical-css')));
114
- const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({
115
- minify: false, // CSS has already been minified during the build.
116
- deployUrl: buildOptions.publicPath,
117
- readAsset,
118
- });
119
- const { content, errors, warnings } = await inlineCriticalCssProcessor.process(contentWithoutCriticalCssInlined, {
120
- outputPath: virtualOutputPath,
121
- });
122
- return {
123
- errors: [...transformResult.errors, ...errors],
124
- warnings: [...transformResult.warnings, ...warnings],
125
- content,
126
- contentWithoutCriticalCssInlined,
127
- };
128
80
  }
129
81
  exports.generateIndexHtml = generateIndexHtml;
@@ -87,7 +87,11 @@ class JavaScriptTransformer {
87
87
  skipLinker,
88
88
  sideEffects,
89
89
  ...this.#commonOptions,
90
- }, { transferList: [data.buffer] }));
90
+ }, {
91
+ // The below is disable as with Yarn PNP this causes build failures with the below message
92
+ // `Unable to deserialize cloned data`.
93
+ transferList: process.versions.pnp ? undefined : [data.buffer],
94
+ }));
91
95
  // If there is a cache then store the result
92
96
  if (this.cache && cacheKey) {
93
97
  try {
@@ -30,31 +30,38 @@ function createCssResourcePlugin(cache) {
30
30
  name: 'angular-css-resource',
31
31
  setup(build) {
32
32
  build.onResolve({ filter: /.*/ }, async (args) => {
33
+ const { importer, path, kind, resolveDir, namespace, pluginData = {} } = args;
33
34
  // Only attempt to resolve url tokens which only exist inside CSS.
34
35
  // Also, skip this plugin if already attempting to resolve the url-token.
35
- if (args.kind !== 'url-token' || args.pluginData?.[CSS_RESOURCE_RESOLUTION]) {
36
+ if (kind !== 'url-token' || pluginData[CSS_RESOURCE_RESOLUTION]) {
36
37
  return null;
37
38
  }
39
+ let [containingDir, resourceUrl] = path.split('||file:', 2);
40
+ if (resourceUrl === undefined) {
41
+ // This can happen due to early exit checks in rebasing-importer
42
+ // logic such as when the url is an external URL.
43
+ resourceUrl = containingDir;
44
+ containingDir = '';
45
+ }
38
46
  // If root-relative, absolute or protocol relative url, mark as external to leave the
39
47
  // path/URL in place.
40
- if (/^((?:\w+:)?\/\/|data:|chrome:|#|\/)/.test(args.path)) {
48
+ if (/^((?:\w+:)?\/\/|data:|chrome:|#|\/)/.test(resourceUrl)) {
41
49
  return {
42
- path: args.path,
50
+ path: resourceUrl,
43
51
  external: true,
44
52
  };
45
53
  }
46
- const { importer, kind, resolveDir, namespace, pluginData = {} } = args;
47
54
  pluginData[CSS_RESOURCE_RESOLUTION] = true;
48
- const result = await build.resolve(args.path, {
55
+ const result = await build.resolve(resourceUrl, {
49
56
  importer,
50
57
  kind,
51
58
  namespace,
52
59
  pluginData,
53
- resolveDir,
60
+ resolveDir: (0, node_path_1.join)(resolveDir, containingDir),
54
61
  });
55
62
  if (result.errors.length) {
56
63
  const error = result.errors[0];
57
- if (args.path[0] === '~') {
64
+ if (resourceUrl[0] === '~') {
58
65
  error.notes = [
59
66
  {
60
67
  location: null,
@@ -62,7 +69,7 @@ function createCssResourcePlugin(cache) {
62
69
  },
63
70
  ];
64
71
  }
65
- else if (args.path[0] === '^') {
72
+ else if (resourceUrl[0] === '^') {
66
73
  error.notes = [
67
74
  {
68
75
  location: null,
@@ -20,7 +20,7 @@ const node_url_1 = require("node:url");
20
20
  const node_zlib_1 = require("node:zlib");
21
21
  const semver_1 = require("semver");
22
22
  const spinner_1 = require("../../utils/spinner");
23
- const stats_1 = require("../webpack/utils/stats");
23
+ const stats_table_1 = require("../../utils/stats-table");
24
24
  const bundler_context_1 = require("./bundler-context");
25
25
  function logBuildStats(metafile, initial, budgetFailures, colors, changedFiles, estimatedTransferSizes, ssrOutputEnabled, verbose) {
26
26
  const browserStats = [];
@@ -65,7 +65,7 @@ function logBuildStats(metafile, initial, budgetFailures, colors, changedFiles,
65
65
  }
66
66
  }
67
67
  if (browserStats.length > 0 || serverStats.length > 0) {
68
- const tableText = (0, stats_1.generateEsbuildBuildStatsTable)([browserStats, serverStats], colors, unchangedCount === 0, !!estimatedTransferSizes, budgetFailures, verbose);
68
+ const tableText = (0, stats_table_1.generateEsbuildBuildStatsTable)([browserStats, serverStats], colors, unchangedCount === 0, !!estimatedTransferSizes, budgetFailures, verbose);
69
69
  return tableText + '\n';
70
70
  }
71
71
  else if (changedFiles !== undefined) {