@nx/angular-rspack 24.0.0-beta.2 → 24.0.0-beta.4

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 (48) hide show
  1. package/dist/lib/config/config-utils/browser-config.d.ts +2 -1
  2. package/dist/lib/config/config-utils/browser-config.d.ts.map +1 -1
  3. package/dist/lib/config/config-utils/browser-config.js +2 -1
  4. package/dist/lib/config/config-utils/server-config.d.ts +2 -1
  5. package/dist/lib/config/config-utils/server-config.d.ts.map +1 -1
  6. package/dist/lib/config/config-utils/server-config.js +29 -3
  7. package/dist/lib/config/create-config.d.ts.map +1 -1
  8. package/dist/lib/config/create-config.js +5 -2
  9. package/dist/lib/models/augmented-compilation.d.ts +2 -2
  10. package/dist/lib/models/augmented-compilation.d.ts.map +1 -1
  11. package/dist/lib/plugins/angular-rspack-plugin.d.ts.map +1 -1
  12. package/dist/lib/plugins/angular-rspack-plugin.js +2 -2
  13. package/dist/lib/plugins/extract-licenses-plugin.d.ts +4 -4
  14. package/dist/lib/plugins/extract-licenses-plugin.d.ts.map +1 -1
  15. package/dist/lib/plugins/extract-licenses-plugin.js +43 -13
  16. package/dist/lib/plugins/index-html-plugin.d.ts +35 -0
  17. package/dist/lib/plugins/index-html-plugin.d.ts.map +1 -1
  18. package/dist/lib/plugins/index-html-plugin.js +138 -3
  19. package/dist/lib/plugins/loaders/angular-partial-transform.loader.d.ts.map +1 -1
  20. package/dist/lib/plugins/loaders/angular-partial-transform.loader.js +5 -7
  21. package/dist/lib/plugins/loaders/engine-manifest.d.ts +5 -2
  22. package/dist/lib/plugins/loaders/engine-manifest.d.ts.map +1 -1
  23. package/dist/lib/plugins/loaders/engine-manifest.js +9 -4
  24. package/dist/lib/plugins/ng-rspack.d.ts +7 -0
  25. package/dist/lib/plugins/ng-rspack.d.ts.map +1 -1
  26. package/dist/lib/plugins/ng-rspack.js +2 -0
  27. package/dist/lib/plugins/prerender-plugin.d.ts +2 -1
  28. package/dist/lib/plugins/prerender-plugin.d.ts.map +1 -1
  29. package/dist/lib/plugins/prerender-plugin.js +40 -23
  30. package/dist/lib/plugins/server-assets-plugin.d.ts +13 -0
  31. package/dist/lib/plugins/server-assets-plugin.d.ts.map +1 -0
  32. package/dist/lib/plugins/server-assets-plugin.js +42 -0
  33. package/dist/lib/plugins/tools/render-worker.d.ts +24 -1
  34. package/dist/lib/plugins/tools/render-worker.d.ts.map +1 -1
  35. package/dist/lib/plugins/tools/render-worker.js +48 -19
  36. package/dist/lib/ssr/server-assets.d.ts +29 -13
  37. package/dist/lib/ssr/server-assets.d.ts.map +1 -1
  38. package/dist/lib/ssr/server-assets.js +57 -34
  39. package/dist/lib/utils/beasties.d.ts +35 -0
  40. package/dist/lib/utils/beasties.d.ts.map +1 -0
  41. package/dist/lib/utils/beasties.js +11 -0
  42. package/dist/lib/utils/index-file/ngcm-attribute.d.ts +16 -0
  43. package/dist/lib/utils/index-file/ngcm-attribute.d.ts.map +1 -0
  44. package/dist/lib/utils/index-file/ngcm-attribute.js +37 -0
  45. package/dist/lib/utils/index-file/nonce.d.ts +15 -0
  46. package/dist/lib/utils/index-file/nonce.d.ts.map +1 -0
  47. package/dist/lib/utils/index-file/nonce.js +54 -0
  48. package/package.json +3 -3
@@ -3,5 +3,6 @@ import type { Configuration } from '@rspack/core';
3
3
  import type { HashFormat, I18nOptions, NormalizedAngularRspackPluginOptions } from '../../models';
4
4
  import type { AngularRspackPlugin } from '../../plugins/angular-rspack-plugin';
5
5
  import type { SharedLicenseInputs } from '../../plugins/extract-licenses-plugin';
6
- export declare function getBrowserConfig(normalizedOptions: NormalizedAngularRspackPluginOptions, i18n: I18nOptions, hashFormat: HashFormat, defaultConfig: Configuration, swcTranspilationTransform: SwcTranspilationTransform, sharedLicenseInputs?: SharedLicenseInputs, sharedAngularPlugin?: AngularRspackPlugin): Promise<Configuration>;
6
+ import type { SharedServerRenderingInputs } from '../../plugins/index-html-plugin';
7
+ export declare function getBrowserConfig(normalizedOptions: NormalizedAngularRspackPluginOptions, i18n: I18nOptions, hashFormat: HashFormat, defaultConfig: Configuration, swcTranspilationTransform: SwcTranspilationTransform, sharedLicenseInputs?: SharedLicenseInputs, sharedAngularPlugin?: AngularRspackPlugin, serverRenderingInputs?: SharedServerRenderingInputs): Promise<Configuration>;
7
8
  //# sourceMappingURL=browser-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser-config.d.ts","sourceRoot":"","sources":["../../../../src/lib/config/config-utils/browser-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,oCAAoC,EACrC,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAQjF,wBAAsB,gBAAgB,CACpC,iBAAiB,EAAE,oCAAoC,EACvD,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,yBAAyB,EAAE,yBAAyB,EACpD,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,mBAAmB,CAAC,EAAE,mBAAmB,GACxC,OAAO,CAAC,aAAa,CAAC,CAgFxB"}
1
+ {"version":3,"file":"browser-config.d.ts","sourceRoot":"","sources":["../../../../src/lib/config/config-utils/browser-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,oCAAoC,EACrC,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAQnF,wBAAsB,gBAAgB,CACpC,iBAAiB,EAAE,oCAAoC,EACvD,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,yBAAyB,EAAE,yBAAyB,EACpD,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,qBAAqB,CAAC,EAAE,2BAA2B,GAClD,OAAO,CAAC,aAAa,CAAC,CAiFxB"}
@@ -10,7 +10,7 @@ const optimization_config_1 = require("./optimization-config");
10
10
  const swc_transpilation_1 = require("./swc-transpilation");
11
11
  const path_1 = require("path");
12
12
  const hmr_accept_loader_1 = require("../../plugins/loaders/hmr-accept-loader");
13
- async function getBrowserConfig(normalizedOptions, i18n, hashFormat, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin) {
13
+ async function getBrowserConfig(normalizedOptions, i18n, hashFormat, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin, serverRenderingInputs) {
14
14
  const isDevServer = (0, rspack_serve_env_1.isServeMode)();
15
15
  const isProduction = process.env['NODE_ENV'] === 'production';
16
16
  const { root } = normalizedOptions;
@@ -78,6 +78,7 @@ async function getBrowserConfig(normalizedOptions, i18n, hashFormat, defaultConf
78
78
  platform: 'browser',
79
79
  sharedLicenseInputs,
80
80
  sharedAngularPlugin,
81
+ serverRenderingInputs,
81
82
  }),
82
83
  ],
83
84
  };
@@ -3,5 +3,6 @@ import { type Configuration } from '@rspack/core';
3
3
  import type { I18nOptions, NormalizedAngularRspackPluginOptions } from '../../models';
4
4
  import type { AngularRspackPlugin } from '../../plugins/angular-rspack-plugin';
5
5
  import type { SharedLicenseInputs } from '../../plugins/extract-licenses-plugin';
6
- export declare function getServerConfig(normalizedOptions: NormalizedAngularRspackPluginOptions, i18n: I18nOptions, defaultConfig: Configuration, swcTranspilationTransform: SwcTranspilationTransform, sharedLicenseInputs?: SharedLicenseInputs, sharedAngularPlugin?: AngularRspackPlugin): Promise<Configuration>;
6
+ import type { SharedServerRenderingInputs } from '../../plugins/index-html-plugin';
7
+ export declare function getServerConfig(normalizedOptions: NormalizedAngularRspackPluginOptions, i18n: I18nOptions, defaultConfig: Configuration, swcTranspilationTransform: SwcTranspilationTransform, sharedLicenseInputs?: SharedLicenseInputs, sharedAngularPlugin?: AngularRspackPlugin, serverRenderingInputs?: SharedServerRenderingInputs): Promise<Configuration>;
7
8
  //# sourceMappingURL=server-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../../../src/lib/config/config-utils/server-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EACL,KAAK,aAAa,EAGnB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EACV,WAAW,EACX,oCAAoC,EAErC,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAkBjF,wBAAsB,eAAe,CACnC,iBAAiB,EAAE,oCAAoC,EACvD,IAAI,EAAE,WAAW,EACjB,aAAa,EAAE,aAAa,EAC5B,yBAAyB,EAAE,yBAAyB,EACpD,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,mBAAmB,CAAC,EAAE,mBAAmB,GACxC,OAAO,CAAC,aAAa,CAAC,CAkJxB"}
1
+ {"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../../../src/lib/config/config-utils/server-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EACL,KAAK,aAAa,EAGnB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EACV,WAAW,EACX,oCAAoC,EAErC,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAQjF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAYnF,wBAAsB,eAAe,CACnC,iBAAiB,EAAE,oCAAoC,EACvD,IAAI,EAAE,WAAW,EACjB,aAAa,EAAE,aAAa,EAC5B,yBAAyB,EAAE,yBAAyB,EACpD,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,mBAAmB,CAAC,EAAE,mBAAmB,EACzC,qBAAqB,CAAC,EAAE,2BAA2B,GAClD,OAAO,CAAC,aAAa,CAAC,CAsKxB"}
@@ -7,12 +7,13 @@ const ng_rspack_1 = require("../../plugins/ng-rspack");
7
7
  const engine_manifest_1 = require("../../plugins/loaders/engine-manifest");
8
8
  const engine_manifest_plugin_1 = require("../../plugins/engine-manifest-plugin");
9
9
  const prerender_plugin_1 = require("../../plugins/prerender-plugin");
10
+ const server_assets_plugin_1 = require("../../plugins/server-assets-plugin");
10
11
  const misc_helpers_1 = require("../../utils/misc-helpers");
11
12
  const dev_server_config_utils_1 = require("./dev-server-config-utils");
12
13
  const optimization_config_1 = require("./optimization-config");
13
14
  const swc_transpilation_1 = require("./swc-transpilation");
14
15
  const rspack_serve_env_1 = require("../../utils/rspack-serve-env");
15
- async function getServerConfig(normalizedOptions, i18n, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin) {
16
+ async function getServerConfig(normalizedOptions, i18n, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin, serverRenderingInputs) {
16
17
  const isDevServer = (0, rspack_serve_env_1.isServeMode)();
17
18
  const { root } = normalizedOptions;
18
19
  const angularSSRInstalled = (0, misc_helpers_1.isPackageInstalled)(root, '@angular/ssr');
@@ -32,12 +33,12 @@ async function getServerConfig(normalizedOptions, i18n, defaultConfig, swcTransp
32
33
  baseHref: normalizedOptions.baseHref ?? '/',
33
34
  locale: i18n.hasDefinedSourceLocale ? i18n.sourceLocale : undefined,
34
35
  inlineCriticalCss: !!normalizedOptions.optimization.styles.inlineCritical,
36
+ usesCriticalCssPlans: installedSsrUsesCriticalCssPlans(root),
35
37
  // Baked into the emitted bundle; posix separators keep it valid
36
38
  // when the build and the server run on different platforms.
37
39
  browserOutputRelativePath: (0, path_1.relative)(normalizedOptions.outputPath.server, normalizedOptions.outputPath.browser)
38
40
  .split(path_1.sep)
39
41
  .join(path_1.posix.sep),
40
- indexOutputName: normalizedOptions.index?.output,
41
42
  supportedLocales: { [i18n.sourceLocale]: '' },
42
43
  // An empty allowlist matches no host: from @angular/ssr 22 the
43
44
  // engine rejects every request, and the earlier versions that
@@ -115,12 +116,29 @@ async function getServerConfig(normalizedOptions, i18n, defaultConfig, swcTransp
115
116
  ],
116
117
  options: platformServerExportsLoaderOptions,
117
118
  },
119
+ // The SSR entry imports the manifest module only for its side effects
120
+ // (registering the app and engine manifests). Without this, apps that
121
+ // set `sideEffects` in their package.json have the import dropped and
122
+ // the engine fails with "Angular app engine manifest is not set".
123
+ ...(engineWiring?.manifestModuleRequest
124
+ ? [
125
+ {
126
+ include: [engineWiring.manifestModuleRequest],
127
+ sideEffects: true,
128
+ },
129
+ ]
130
+ : []),
118
131
  ...(defaultConfig.module?.rules ?? []),
119
132
  ],
120
133
  },
121
134
  plugins: [
122
135
  ...(defaultConfig.plugins ?? []),
123
136
  ...(engineManifestPlugin ? [engineManifestPlugin] : []),
137
+ ...(engineWiring && serverRenderingInputs
138
+ ? [
139
+ new server_assets_plugin_1.ServerAssetsPlugin(serverRenderingInputs, engineWiring.usesCriticalCssPlans),
140
+ ]
141
+ : []),
124
142
  // Fixes Critical dependency: the request of a dependency is an expression
125
143
  new core_1.ContextReplacementPlugin(/@?hapi|express[\\/]/),
126
144
  // rspack inlines `import.meta.url` as the source file's URL, breaking
@@ -136,11 +154,19 @@ async function getServerConfig(normalizedOptions, i18n, defaultConfig, swcTransp
136
154
  }),
137
155
  ...(normalizedOptions.prerender ||
138
156
  (normalizedOptions.appShell && !isDevServer)
139
- ? [new prerender_plugin_1.PrerenderPlugin(normalizedOptions, i18n)]
157
+ ? [new prerender_plugin_1.PrerenderPlugin(normalizedOptions, i18n, serverRenderingInputs)]
140
158
  : []),
141
159
  ],
142
160
  };
143
161
  }
162
+ function installedSsrUsesCriticalCssPlans(root) {
163
+ const version = (0, misc_helpers_1.getInstalledPackageVersionFromRoot)(root, '@angular/ssr');
164
+ if (!version) {
165
+ return false;
166
+ }
167
+ const [major, minor] = version.split('.').map((part) => parseInt(part, 10));
168
+ return major > 22 || (major === 22 && minor >= 2);
169
+ }
144
170
  // TODO(v24): drop the probe and the loader's inline fallback once
145
171
  // @rspack/core v1 is out of the support window.
146
172
  function installedRspackSupportsVirtualModules(root) {
@@ -1 +1 @@
1
- {"version":3,"file":"create-config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/create-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAmB5D,wBAAsB,YAAY,CAChC,cAAc,EAAE;IACd,OAAO,EAAE,0BAA0B,CAAC;IACpC,qBAAqB,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAChD,EACD,cAAc,GAAE,MAAM,CACpB,MAAM,EACN;IACE,OAAO,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC7C,qBAAqB,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAChD,CACG,EACN,YAAY,SAAgB,GAC3B,OAAO,CAAC,aAAa,EAAE,CAAC,CAY1B;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,0BAA0B,EACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC7C,OAAO,CAAC,aAAa,EAAE,CAAC,CAqE1B"}
1
+ {"version":3,"file":"create-config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/create-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAoB5D,wBAAsB,YAAY,CAChC,cAAc,EAAE;IACd,OAAO,EAAE,0BAA0B,CAAC;IACpC,qBAAqB,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAChD,EACD,cAAc,GAAE,MAAM,CACpB,MAAM,EACN;IACE,OAAO,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC7C,qBAAqB,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAChD,CACG,EACN,YAAY,SAAgB,GAC3B,OAAO,CAAC,aAAa,EAAE,CAAC,CAY1B;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,0BAA0B,EACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC7C,OAAO,CAAC,aAAa,EAAE,CAAC,CA4E1B"}
@@ -42,13 +42,16 @@ async function _createConfig(options, rspackConfigOverrides) {
42
42
  const sharedAngularPlugin = normalizedOptions.hasServer
43
43
  ? new angular_rspack_plugin_1.AngularRspackPlugin(normalizedOptions, i18n)
44
44
  : undefined;
45
+ // The browser compiler generates the documents and critical CSS plans the
46
+ // server compiler renders with.
47
+ const serverRenderingInputs = normalizedOptions.hasServer ? {} : undefined;
45
48
  const configs = [];
46
49
  if (normalizedOptions.hasServer) {
47
- const serverConfig = await (0, server_config_1.getServerConfig)(normalizedOptions, i18n, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin);
50
+ const serverConfig = await (0, server_config_1.getServerConfig)(normalizedOptions, i18n, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin, serverRenderingInputs);
48
51
  const mergedConfig = (0, webpack_merge_1.merge)(serverConfig, rspackConfigOverrides ?? {});
49
52
  configs.push(mergedConfig);
50
53
  }
51
- const browserConfig = await (0, browser_config_1.getBrowserConfig)(normalizedOptions, i18n, hashFormat, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin);
54
+ const browserConfig = await (0, browser_config_1.getBrowserConfig)(normalizedOptions, i18n, hashFormat, defaultConfig, swcTranspilationTransform, sharedLicenseInputs, sharedAngularPlugin, serverRenderingInputs);
52
55
  const mergedConfig = (0, webpack_merge_1.merge)(browserConfig, rspackConfigOverrides ?? {});
53
56
  configs.unshift(mergedConfig);
54
57
  return configs;
@@ -1,9 +1,9 @@
1
1
  import type { Compilation } from '@rspack/core';
2
- import type { JavaScriptTransformer, SourceFileCache } from '@nx/angular-rspack-compiler';
2
+ import type { JavaScriptTransformerAdapter, SourceFileCache } from '@nx/angular-rspack-compiler';
3
3
  import { I18nOptions } from './i18n';
4
4
  export declare const NG_RSPACK_SYMBOL_NAME = "NG_RSPACK_BUILD";
5
5
  export type NG_RSPACK_COMPILATION_STATE = {
6
- javascriptTransformer: JavaScriptTransformer;
6
+ javascriptTransformer: JavaScriptTransformerAdapter;
7
7
  typescriptFileCache: SourceFileCache['typeScriptFileCache'];
8
8
  babelFileCache: SourceFileCache['babelFileCache'];
9
9
  useTypeScriptTranspilation: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"augmented-compilation.d.ts","sourceRoot":"","sources":["../../../src/lib/models/augmented-compilation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,MAAM,MAAM,2BAA2B,GAAG;IACxC,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,mBAAmB,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC;IAC5D,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAGlD,0BAA0B,EAAE,OAAO,CAAC;IAGpC,wBAAwB,EAAE,OAAO,CAAC;IAGlC,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAIpE,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,CAAC,qBAAqB,CAAC,EAAE,MAAM,2BAA2B,CAAC;CAC5D,CAAC"}
1
+ {"version":3,"file":"augmented-compilation.d.ts","sourceRoot":"","sources":["../../../src/lib/models/augmented-compilation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EACV,4BAA4B,EAC5B,eAAe,EAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,MAAM,MAAM,2BAA2B,GAAG;IACxC,qBAAqB,EAAE,4BAA4B,CAAC;IACpD,mBAAmB,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC;IAC5D,cAAc,EAAE,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAGlD,0BAA0B,EAAE,OAAO,CAAC;IAGpC,wBAAwB,EAAE,OAAO,CAAC;IAGlC,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAIpE,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,CAAC,qBAAqB,CAAC,EAAE,MAAM,2BAA2B,CAAC;CAC5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"angular-rspack-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/angular-rspack-plugin.ts"],"names":[],"mappings":"AAoBA,OAAO,EAEL,KAAK,QAAQ,EAEb,KAAK,oBAAoB,EAE1B,MAAM,cAAc,CAAC;AAUtB,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,oCAAoC,EAC1C,MAAM,WAAW,CAAC;AAgDnB,qBAAa,mBAAoB,YAAW,oBAAoB;;IAwB9D,YACE,OAAO,EAAE,oCAAoC,EAC7C,WAAW,CAAC,EAAE,WAAW,EA2B1B;IAED,KAAK,CAAC,QAAQ,EAAE,QAAQ,QA4XvB;IAED;;;;;;;OAOG;IACH,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,QAgC1C;YA+Ea,gBAAgB;YAyFhB,eAAe;CAyC9B"}
1
+ {"version":3,"file":"angular-rspack-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/angular-rspack-plugin.ts"],"names":[],"mappings":"AAoBA,OAAO,EAEL,KAAK,QAAQ,EAEb,KAAK,oBAAoB,EAE1B,MAAM,cAAc,CAAC;AAUtB,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,oCAAoC,EAC1C,MAAM,WAAW,CAAC;AA+CnB,qBAAa,mBAAoB,YAAW,oBAAoB;;IAwB9D,YACE,OAAO,EAAE,oCAAoC,EAC7C,WAAW,CAAC,EAAE,WAAW,EA0B1B;IAED,KAAK,CAAC,QAAQ,EAAE,QAAQ,QA4XvB;IAED;;;;;;;OAOG;IACH,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,QAgC1C;YA8Ea,gBAAgB;YAyFhB,eAAe;CAyC9B"}
@@ -73,7 +73,7 @@ class AngularRspackPlugin {
73
73
  if (persistentCachePath) {
74
74
  tslib_1.__classPrivateFieldSet(this, _AngularRspackPlugin_javascriptTransformerCache, (0, angular_rspack_compiler_1.createJavascriptTransformerCache)(persistentCachePath), "f");
75
75
  }
76
- tslib_1.__classPrivateFieldSet(this, _AngularRspackPlugin_javascriptTransformer, new angular_rspack_compiler_1.JavaScriptTransformer({
76
+ tslib_1.__classPrivateFieldSet(this, _AngularRspackPlugin_javascriptTransformer, (0, angular_rspack_compiler_1.createJavaScriptTransformer)({
77
77
  /**
78
78
  * Matches https://github.com/angular/angular-cli/blob/33ed6e875e509ebbaa0cbdb57be9e932f9915dff/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts#L89
79
79
  * where pluginOptions.sourcemap is set https://github.com/angular/angular-cli/blob/61d98fde122468978de9b17bd79761befdbf2fac/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts#L34
@@ -83,7 +83,7 @@ class AngularRspackPlugin {
83
83
  thirdPartySourcemaps: tslib_1.__classPrivateFieldGet(this, _AngularRspackPlugin__options, "f").sourceMap.vendor,
84
84
  advancedOptimizations: tslib_1.__classPrivateFieldGet(this, _AngularRspackPlugin__options, "f").advancedOptimizations,
85
85
  jit: !tslib_1.__classPrivateFieldGet(this, _AngularRspackPlugin__options, "f").aot,
86
- }, (0, angular_rspack_compiler_1.maxWorkers)(), tslib_1.__classPrivateFieldGet(this, _AngularRspackPlugin_javascriptTransformerCache, "f")?.cache), "f");
86
+ }, tslib_1.__classPrivateFieldGet(this, _AngularRspackPlugin_javascriptTransformerCache, "f")?.cache), "f");
87
87
  }
88
88
  apply(compiler) {
89
89
  const root = tslib_1.__classPrivateFieldGet(this, _AngularRspackPlugin__options, "f").root;
@@ -29,10 +29,10 @@ interface LicenseMetafile {
29
29
  * package. If a license file (e.g., `LICENSE`) is present in the root of the package, it
30
30
  * will also be included in the output licenses file.
31
31
  *
32
- * Vendored from `@angular/build` (`src/tools/esbuild/license-extractor.ts`, identical
33
- * across the supported Angular majors) since it is not exposed in the package's public
34
- * or private API. Only the esbuild `Metafile` type import is replaced with the local
35
- * `LicenseMetafile` interface.
32
+ * Vendored from `@angular/build` 22.1.3 (`src/tools/esbuild/license-extractor.ts`) since
33
+ * it is not exposed in the package's public or private API. Only the esbuild `Metafile`
34
+ * type import is replaced with the local `LicenseMetafile` interface. When an earlier
35
+ * `@angular/build` is installed, its license file lookup is used instead.
36
36
  *
37
37
  * @param metafile An esbuild metafile object.
38
38
  * @param rootDirectory The root directory of the workspace.
@@ -1 +1 @@
1
- {"version":3,"file":"extract-licenses-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/extract-licenses-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAU,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAK3E;;;GAGG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CACb,MAAM,GAAG,MAAM,EACf;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CACtD,CAAC;CACH;AAoCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,MAAM,mBA4HtB;AAID;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,GAAG,CACnC,MAAM,EACN,MAAM,CAAC,MAAM,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAC1C,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,oBAAoB;IAGpD,OAAO,CAAC,OAAO;IAF3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IAEnD,YAAoB,OAAO,EAAE,4BAA4B,EAExD;IAED,KAAK,CAAC,QAAQ,EAAE,QAAQ,QAoDvB;CACF"}
1
+ {"version":3,"file":"extract-licenses-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/extract-licenses-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAU,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAK3E;;;GAGG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CACb,MAAM,GAAG,MAAM,EACf;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CACtD,CAAC;CACH;AAyCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,MAAM,mBAoJtB;AAID;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,GAAG,CACnC,MAAM,EACN,MAAM,CAAC,MAAM,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAC1C,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,oBAAoB;IAGpD,OAAO,CAAC,OAAO;IAF3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IAEnD,YAAoB,OAAO,EAAE,4BAA4B,EAExD;IAED,KAAK,CAAC,QAAQ,EAAE,QAAQ,QAoDvB;CACF"}
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.ExtractLicensesPlugin = void 0;
11
11
  exports.extractLicenses = extractLicenses;
12
12
  const tslib_1 = require("tslib");
13
+ const angular_rspack_compiler_1 = require("@nx/angular-rspack-compiler");
13
14
  const promises_1 = require("node:fs/promises");
14
15
  const node_path_1 = tslib_1.__importDefault(require("node:path"));
15
16
  const models_1 = require("../models");
@@ -31,9 +32,13 @@ const NODE_MODULE_SEGMENT = 'node_modules';
31
32
  */
32
33
  const CUSTOM_LICENSE_TEXT = 'SEE LICENSE IN ';
33
34
  /**
34
- * A list of commonly named license files found within packages.
35
+ * A regular expression for commonly named license files found within packages.
35
36
  */
36
- const LICENSE_FILES = ['LICENSE', 'LICENSE.txt', 'LICENSE.md'];
37
+ const LICENSE_FILE_REGEXP = /^(?:mit-)?licen[cs]e(?:$|[-._])/i;
38
+ /**
39
+ * The license files `@angular/build` < 22.1.3 looks for, in order.
40
+ */
41
+ const LEGACY_LICENSE_FILES = ['LICENSE', 'LICENSE.txt', 'LICENSE.md'];
37
42
  /**
38
43
  * Header text that will be added to the top of the output license extraction file.
39
44
  */
@@ -54,10 +59,10 @@ const EXTRACTION_FILE_SEPARATOR = '-'.repeat(80) + '\n';
54
59
  * package. If a license file (e.g., `LICENSE`) is present in the root of the package, it
55
60
  * will also be included in the output licenses file.
56
61
  *
57
- * Vendored from `@angular/build` (`src/tools/esbuild/license-extractor.ts`, identical
58
- * across the supported Angular majors) since it is not exposed in the package's public
59
- * or private API. Only the esbuild `Metafile` type import is replaced with the local
60
- * `LicenseMetafile` interface.
62
+ * Vendored from `@angular/build` 22.1.3 (`src/tools/esbuild/license-extractor.ts`) since
63
+ * it is not exposed in the package's public or private API. Only the esbuild `Metafile`
64
+ * type import is replaced with the local `LicenseMetafile` interface. When an earlier
65
+ * `@angular/build` is installed, its license file lookup is used instead.
61
66
  *
62
67
  * @param metafile An esbuild metafile object.
63
68
  * @param rootDirectory The root directory of the workspace.
@@ -65,7 +70,9 @@ const EXTRACTION_FILE_SEPARATOR = '-'.repeat(80) + '\n';
65
70
  */
66
71
  async function extractLicenses(metafile, rootDirectory) {
67
72
  let extractedLicenseContent = `${EXTRACTION_FILE_HEADER}\n${EXTRACTION_FILE_SEPARATOR}`;
73
+ const useLegacyLicenseLookup = !(0, angular_rspack_compiler_1.isAngularBuildVersionAtLeast)('22.1.3');
68
74
  const seenPaths = new Set();
75
+ const seenPackageDirectories = new Set();
69
76
  const seenPackages = new Set();
70
77
  for (const entry of Object.values(metafile.outputs)) {
71
78
  for (const [inputPath, { bytesInOutput }] of Object.entries(entry.inputs)) {
@@ -104,6 +111,10 @@ async function extractLicenses(metafile, rootDirectory) {
104
111
  ? `${nameOrScope}/${nameOrFile}`
105
112
  : nameOrScope;
106
113
  const packageDirectory = node_path_1.default.join(baseDirectory, packageName);
114
+ if (seenPackageDirectories.has(packageDirectory)) {
115
+ continue;
116
+ }
117
+ seenPackageDirectories.add(packageDirectory);
107
118
  // Load the package's metadata to find the package's name, version, and license type
108
119
  const packageJsonPath = node_path_1.default.join(packageDirectory, 'package.json');
109
120
  let packageJson;
@@ -122,11 +133,15 @@ async function extractLicenses(metafile, rootDirectory) {
122
133
  seenPackages.add(packageId);
123
134
  // Attempt to find license text inside package
124
135
  let licenseText = '';
125
- if (typeof packageJson.license === 'string' &&
126
- packageJson.license.toLowerCase().startsWith(CUSTOM_LICENSE_TEXT)) {
136
+ if (
137
+ // Earlier versions never matched it: they compared the lowercased
138
+ // license with the uppercase constant.
139
+ !useLegacyLicenseLookup &&
140
+ typeof packageJson.license === 'string' &&
141
+ packageJson.license.toUpperCase().startsWith(CUSTOM_LICENSE_TEXT)) {
127
142
  // Attempt to load the package's custom license
128
143
  let customLicensePath;
129
- const customLicenseFile = node_path_1.default.normalize(packageJson.license.slice(CUSTOM_LICENSE_TEXT.length + 1).trim());
144
+ const customLicenseFile = node_path_1.default.normalize(packageJson.license.slice(CUSTOM_LICENSE_TEXT.length).trim());
130
145
  if (customLicenseFile.startsWith('..') ||
131
146
  node_path_1.default.isAbsolute(customLicenseFile)) {
132
147
  // Path is attempting to access files outside of the package
@@ -136,14 +151,12 @@ async function extractLicenses(metafile, rootDirectory) {
136
151
  customLicensePath = node_path_1.default.join(packageDirectory, customLicenseFile);
137
152
  try {
138
153
  licenseText = await (0, promises_1.readFile)(customLicensePath, 'utf-8');
139
- break;
140
154
  }
141
155
  catch { }
142
156
  }
143
157
  }
144
- else {
145
- // Search for a license file within the root of the package
146
- for (const potentialLicense of LICENSE_FILES) {
158
+ else if (useLegacyLicenseLookup) {
159
+ for (const potentialLicense of LEGACY_LICENSE_FILES) {
147
160
  const packageLicensePath = node_path_1.default.join(packageDirectory, potentialLicense);
148
161
  try {
149
162
  licenseText = await (0, promises_1.readFile)(packageLicensePath, 'utf-8');
@@ -152,6 +165,23 @@ async function extractLicenses(metafile, rootDirectory) {
152
165
  catch { }
153
166
  }
154
167
  }
168
+ else {
169
+ // Search for a license file within the root of the package
170
+ const entries = await (0, promises_1.readdir)(packageDirectory, {
171
+ withFileTypes: true,
172
+ }).catch(() => []);
173
+ for (const entry of entries) {
174
+ if ((entry.isFile() || entry.isSymbolicLink()) &&
175
+ LICENSE_FILE_REGEXP.test(entry.name)) {
176
+ const packageLicensePath = node_path_1.default.join(packageDirectory, entry.name);
177
+ try {
178
+ licenseText = await (0, promises_1.readFile)(packageLicensePath, 'utf-8');
179
+ break;
180
+ }
181
+ catch { }
182
+ }
183
+ }
184
+ }
155
185
  // Generate the package's license entry in the output content
156
186
  extractedLicenseContent += `Package: ${packageJson.name}\n`;
157
187
  extractedLicenseContent += `License: ${JSON.stringify(packageJson.license, null, 2)}\n`;
@@ -1,14 +1,49 @@
1
1
  import { IndexHtmlGenerator, type IndexHtmlGeneratorOptions } from '@angular/build/private';
2
2
  import { Compilation, RspackPluginInstance, type Compiler } from '@rspack/core';
3
3
  import type { I18nOptions, IndexExpandedDefinition } from '../models';
4
+ import { type CriticalCssPlan } from '../utils/beasties';
5
+ /** The index html documents of a server build for one locale. */
6
+ export interface ServerIndexHtml {
7
+ /** `index.server.html`, the document server rendering renders into. */
8
+ server: string;
9
+ /** `index.csr.html`, served as-is for client-rendered routes. */
10
+ csr: string;
11
+ /** The `ngCspNonce` attribute value of the server document. */
12
+ nonce: string | undefined;
13
+ }
14
+ export interface ServerRenderingInputs {
15
+ /** Keyed by locale, the empty string when not localizing. */
16
+ indexHtml: Map<string, ServerIndexHtml>;
17
+ /**
18
+ * Set when critical CSS is inlined from compiled plans, which
19
+ * `@angular/build` >= 22.2 does.
20
+ */
21
+ criticalCssPlans: CriticalCssPlan[] | undefined;
22
+ }
23
+ /**
24
+ * Holds the server rendering inputs of the browser compiler's last
25
+ * compilation without errors, for the server compiler that runs after it.
26
+ */
27
+ export interface SharedServerRenderingInputs {
28
+ current?: ServerRenderingInputs;
29
+ }
4
30
  export interface IndexHtmlPluginOptions extends IndexHtmlGeneratorOptions {
5
31
  baseHref: string | undefined;
6
32
  i18n: I18nOptions;
7
33
  index: IndexExpandedDefinition;
8
34
  isSsr: boolean;
9
35
  outputPath: string;
36
+ serverRenderingInputs?: SharedServerRenderingInputs;
10
37
  }
38
+ /**
39
+ * Whether a server build emits its server index as `index.original.html`,
40
+ * which Nx's CommonEngine server template renders instead of `index.html`.
41
+ * From 22.2, CommonEngine inlining critical CSS a second time into the browser
42
+ * index leaves a stylesheet that never loads.
43
+ */
44
+ export declare function emitsServerIndexAsOriginal(index: IndexExpandedDefinition): boolean;
11
45
  export declare class IndexHtmlPlugin extends IndexHtmlGenerator implements RspackPluginInstance {
46
+ #private;
12
47
  readonly options: IndexHtmlPluginOptions;
13
48
  private _compilation;
14
49
  get compilation(): Compilation;
@@ -1 +1 @@
1
- {"version":3,"file":"index-html-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/index-html-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAElB,KAAK,yBAAyB,EAC/B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGhF,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAYtE,MAAM,WAAW,sBAAuB,SAAQ,yBAAyB;IACvE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,uBAAuB,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,qBAAa,eACX,SAAQ,kBACR,YAAW,oBAAoB;aAWD,OAAO,EAAE,sBAAsB;IAT7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,IAAI,WAAW,IAAI,WAAW,CAM7B;IAED,YAA8B,OAAO,EAAE,sBAAsB,EAE5D;IAED,KAAK,CAAC,QAAQ,EAAE,QAAQ,QAyGvB;IAEc,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAItD;IAED,UAAyB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBhE;IAED,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAwBpD;CACF"}
1
+ {"version":3,"file":"index-html-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/plugins/index-html-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAElB,KAAK,yBAAyB,EAC/B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIhF,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,mBAAmB,CAAC;AAc3B,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxC;;;OAGG;IACH,gBAAgB,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,qBAAqB,CAAC;CACjC;AAED,MAAM,WAAW,sBAAuB,SAAQ,yBAAyB;IACvE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,uBAAuB,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,2BAA2B,CAAC;CACrD;AAID;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAKT;AAQD,qBAAa,eACX,SAAQ,kBACR,YAAW,oBAAoB;;aAeD,OAAO,EAAE,sBAAsB;IAb7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,IAAI,WAAW,IAAI,WAAW,CAM7B;IAMD,YAA8B,OAAO,EAAE,sBAAsB,EAgB5D;IAED,KAAK,CAAC,QAAQ,EAAE,QAAQ,QAqNvB;IA2Bc,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAItD;IAED,UAAyB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBhE;IAED,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAwBpD;CACF"}
@@ -1,18 +1,41 @@
1
1
  "use strict";
2
+ var _IndexHtmlPlugin_instances, _IndexHtmlPlugin_sharedIndexContent, _IndexHtmlPlugin_pendingServerRenderingInputs, _IndexHtmlPlugin_compileCriticalCssPlans;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.IndexHtmlPlugin = void 0;
5
+ exports.emitsServerIndexAsOriginal = emitsServerIndexAsOriginal;
6
+ const tslib_1 = require("tslib");
4
7
  const private_1 = require("@angular/build/private");
5
8
  const core_1 = require("@angular/core");
9
+ const angular_rspack_compiler_1 = require("@nx/angular-rspack-compiler");
6
10
  const core_2 = require("@rspack/core");
11
+ const node_assert_1 = tslib_1.__importDefault(require("node:assert"));
7
12
  const node_crypto_1 = require("node:crypto");
8
13
  const node_path_1 = require("node:path");
14
+ const beasties_1 = require("../utils/beasties");
9
15
  const add_event_dispatch_contract_1 = require("../utils/index-file/add-event-dispatch-contract");
16
+ const ngcm_attribute_1 = require("../utils/index-file/ngcm-attribute");
17
+ const nonce_1 = require("../utils/index-file/nonce");
10
18
  const misc_helpers_1 = require("../utils/misc-helpers");
11
19
  const i18n_1 = require("../utils/i18n");
12
20
  const rspack_diagnostics_1 = require("../utils/rspack-diagnostics");
13
21
  const url_1 = require("../utils/url");
14
22
  const get_index_output_file_1 = require("../utils/index-file/get-index-output-file");
15
23
  const PLUGIN_NAME = 'IndexHtmlPlugin';
24
+ /**
25
+ * Whether a server build emits its server index as `index.original.html`,
26
+ * which Nx's CommonEngine server template renders instead of `index.html`.
27
+ * From 22.2, CommonEngine inlining critical CSS a second time into the browser
28
+ * index leaves a stylesheet that never loads.
29
+ */
30
+ function emitsServerIndexAsOriginal(index) {
31
+ return ((0, angular_rspack_compiler_1.isAngularBuildVersionAtLeast)('22.2.0') &&
32
+ (0, get_index_output_file_1.getIndexOutputFile)(index) === 'index.html');
33
+ }
34
+ /**
35
+ * Holds the server index documents between generation and hashing, which
36
+ * rewrites their file references. Removed from the browser output after.
37
+ */
38
+ const SERVER_INDEX_ASSETS_DIR = '__ng-rspack-server-index__';
16
39
  class IndexHtmlPlugin extends private_1.IndexHtmlGenerator {
17
40
  get compilation() {
18
41
  if (this._compilation) {
@@ -21,12 +44,33 @@ class IndexHtmlPlugin extends private_1.IndexHtmlGenerator {
21
44
  throw new Error('compilation is undefined.');
22
45
  }
23
46
  constructor(options) {
24
- super(options);
47
+ super(options.serverRenderingInputs
48
+ ? {
49
+ ...options,
50
+ // The last generator step shared by all index documents, where
51
+ // the server documents branch off.
52
+ postTransform: async (html) => {
53
+ tslib_1.__classPrivateFieldSet(this, _IndexHtmlPlugin_sharedIndexContent, options.postTransform
54
+ ? await options.postTransform(html)
55
+ : html, "f");
56
+ return tslib_1.__classPrivateFieldGet(this, _IndexHtmlPlugin_sharedIndexContent, "f");
57
+ },
58
+ }
59
+ : options);
60
+ _IndexHtmlPlugin_instances.add(this);
25
61
  this.options = options;
62
+ /** The output of the generator steps shared by all index documents. */
63
+ _IndexHtmlPlugin_sharedIndexContent.set(this, void 0);
64
+ _IndexHtmlPlugin_pendingServerRenderingInputs.set(this, void 0);
26
65
  }
27
66
  apply(compiler) {
67
+ const { serverRenderingInputs } = this.options;
68
+ const emitServerIndexAsOriginal = emitsServerIndexAsOriginal(this.options.index);
69
+ const compileCriticalCssPlans = (0, angular_rspack_compiler_1.isAngularBuildVersionAtLeast)('22.2.0') &&
70
+ !!this.options.optimization?.styles.inlineCritical;
28
71
  compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
29
72
  this._compilation = compilation;
73
+ const serverIndexAssets = [];
30
74
  compilation.hooks.processAssets.tapPromise({
31
75
  name: PLUGIN_NAME,
32
76
  stage: core_2.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
@@ -82,18 +126,40 @@ class IndexHtmlPlugin extends private_1.IndexHtmlGenerator {
82
126
  }
83
127
  const outputPaths = (0, i18n_1.ensureOutputPaths)(this.options.outputPath, this.options.i18n);
84
128
  for (const [locale, outputPath] of outputPaths.entries()) {
85
- const { csrContent, warnings, errors } = await this.process({
129
+ // @angular/build 22.2 reads `outputPath` from the constructor
130
+ // options; earlier versions read it from these.
131
+ const processOptions = {
86
132
  files,
87
133
  outputPath,
88
134
  baseHref: this.getLocaleBaseHref(locale) ?? this.options.baseHref,
89
135
  lang: locale || undefined,
90
- });
136
+ };
137
+ const { csrContent, warnings, errors } = await this.process(processOptions);
91
138
  let html = csrContent;
92
139
  if (this.options.isSsr) {
93
140
  html = await (0, add_event_dispatch_contract_1.addEventDispatchContract)(csrContent);
94
141
  }
95
142
  const { RawSource } = compiler.rspack.sources;
96
143
  compilation.emitAsset((0, node_path_1.join)(outputPath, (0, get_index_output_file_1.getIndexOutputFile)(this.options.index)), new RawSource(html));
144
+ if (serverRenderingInputs) {
145
+ (0, node_assert_1.default)(tslib_1.__classPrivateFieldGet(this, _IndexHtmlPlugin_sharedIndexContent, "f") !== undefined, 'The index html generator did not run its shared steps.');
146
+ // Unlike the browser index, these match the documents the
147
+ // `@angular/build` application builder generates for a server.
148
+ const [server, csr] = await Promise.all([
149
+ (0, add_event_dispatch_contract_1.addEventDispatchContract)(tslib_1.__classPrivateFieldGet(this, _IndexHtmlPlugin_sharedIndexContent, "f")).then(nonce_1.addNonce),
150
+ (0, ngcm_attribute_1.addNgcmAttribute)(csrContent),
151
+ ]);
152
+ const assetsDir = `${SERVER_INDEX_ASSETS_DIR}/${serverIndexAssets.length}`;
153
+ const serverIndexAsset = {
154
+ locale,
155
+ outputPath,
156
+ server: `${assetsDir}/index.server.html`,
157
+ csr: `${assetsDir}/index.csr.html`,
158
+ };
159
+ compilation.emitAsset(serverIndexAsset.server, new RawSource(server));
160
+ compilation.emitAsset(serverIndexAsset.csr, new RawSource(csr));
161
+ serverIndexAssets.push(serverIndexAsset);
162
+ }
97
163
  warnings.forEach((msg) => (0, rspack_diagnostics_1.addWarning)(compilation, msg));
98
164
  errors.forEach((msg) => (0, rspack_diagnostics_1.addError)(compilation, msg));
99
165
  }
@@ -103,7 +169,55 @@ class IndexHtmlPlugin extends private_1.IndexHtmlGenerator {
103
169
  (0, rspack_diagnostics_1.addError)(compilation, error.message);
104
170
  }
105
171
  });
172
+ if (!serverRenderingInputs) {
173
+ return;
174
+ }
175
+ compilation.hooks.processAssets.tapPromise({
176
+ name: PLUGIN_NAME,
177
+ // Hashing renames the files the documents and plans reference.
178
+ stage: core_2.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH + 1,
179
+ }, async () => {
180
+ try {
181
+ const indexHtml = new Map();
182
+ for (const { locale, outputPath, server, csr, } of serverIndexAssets) {
183
+ const serverContent = compilation.assets[server]
184
+ .source()
185
+ .toString();
186
+ const csrContent = compilation.assets[csr].source().toString();
187
+ compilation.deleteAsset(server);
188
+ compilation.deleteAsset(csr);
189
+ indexHtml.set(locale, {
190
+ server: serverContent,
191
+ csr: csrContent,
192
+ nonce: (await (0, nonce_1.findNonce)(serverContent)) ?? undefined,
193
+ });
194
+ if (emitServerIndexAsOriginal) {
195
+ compilation.emitAsset((0, node_path_1.join)(outputPath, 'index.original.html'), new compiler.rspack.sources.RawSource(serverContent));
196
+ }
197
+ }
198
+ tslib_1.__classPrivateFieldSet(this, _IndexHtmlPlugin_pendingServerRenderingInputs, {
199
+ indexHtml,
200
+ criticalCssPlans: compileCriticalCssPlans
201
+ ? await tslib_1.__classPrivateFieldGet(this, _IndexHtmlPlugin_instances, "m", _IndexHtmlPlugin_compileCriticalCssPlans).call(this, compilation)
202
+ : undefined,
203
+ }, "f");
204
+ }
205
+ catch (error) {
206
+ (0, misc_helpers_1.assertIsError)(error);
207
+ (0, rspack_diagnostics_1.addError)(compilation, error.message);
208
+ }
209
+ });
106
210
  });
211
+ if (serverRenderingInputs) {
212
+ compiler.hooks.done.tap(PLUGIN_NAME, (stats) => {
213
+ // A compilation with errors emits nothing, so the server compiler
214
+ // keeps the documents matching the browser output on disk.
215
+ if (!stats.hasErrors() && tslib_1.__classPrivateFieldGet(this, _IndexHtmlPlugin_pendingServerRenderingInputs, "f")) {
216
+ serverRenderingInputs.current = tslib_1.__classPrivateFieldGet(this, _IndexHtmlPlugin_pendingServerRenderingInputs, "f");
217
+ }
218
+ tslib_1.__classPrivateFieldSet(this, _IndexHtmlPlugin_pendingServerRenderingInputs, undefined, "f");
219
+ });
220
+ }
107
221
  }
108
222
  async readAsset(path) {
109
223
  const data = this.compilation.assets[(0, node_path_1.basename)(path)].source();
@@ -145,3 +259,24 @@ class IndexHtmlPlugin extends private_1.IndexHtmlGenerator {
145
259
  }
146
260
  }
147
261
  exports.IndexHtmlPlugin = IndexHtmlPlugin;
262
+ _IndexHtmlPlugin_sharedIndexContent = new WeakMap(), _IndexHtmlPlugin_pendingServerRenderingInputs = new WeakMap(), _IndexHtmlPlugin_instances = new WeakSet(), _IndexHtmlPlugin_compileCriticalCssPlans =
263
+ /** Compiles every stylesheet the way `@angular/build` >= 22.2 does. */
264
+ async function _IndexHtmlPlugin_compileCriticalCssPlans(compilation) {
265
+ const { compileSheet, encodePlan } = await (0, beasties_1.loadAngularBuildBeasties)('compiler');
266
+ const stylesheets = new Set();
267
+ for (const chunk of compilation.chunks) {
268
+ for (const file of chunk.files) {
269
+ if ((0, node_path_1.extname)(file) === '.css') {
270
+ stylesheets.add(file);
271
+ }
272
+ }
273
+ }
274
+ const plans = [];
275
+ for (const file of stylesheets) {
276
+ const sheet = compileSheet(compilation.assets[file].source().toString(), {
277
+ href: (0, url_1.joinUrlParts)(this.options.deployUrl ?? '', file),
278
+ });
279
+ plans.push(encodePlan(sheet));
280
+ }
281
+ return plans;
282
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"angular-partial-transform.loader.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/loaders/angular-partial-transform.loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAQ3D,MAAM,WAAW,oCAAoC;IACnD,2DAA2D;IAC3D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAC5B,IAAI,EAAE,aAAa,CAAC,oCAAoC,CAAC,EACzD,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,QA+IjC"}
1
+ {"version":3,"file":"angular-partial-transform.loader.d.ts","sourceRoot":"","sources":["../../../../src/lib/plugins/loaders/angular-partial-transform.loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAQ3D,MAAM,WAAW,oCAAoC;IACnD,2DAA2D;IAC3D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAC5B,IAAI,EAAE,aAAa,CAAC,oCAAoC,CAAC,EACzD,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,QA4IjC"}