@nx/rspack 21.0.0-beta.0 → 21.0.0-beta.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.
Files changed (48) hide show
  1. package/generators.json +1 -0
  2. package/migrations.json +13 -34
  3. package/package.json +12 -10
  4. package/src/executors/dev-server/lib/get-dev-server-config.js +1 -2
  5. package/src/executors/dev-server/schema.json +1 -0
  6. package/src/executors/module-federation-dev-server/schema.json +1 -0
  7. package/src/executors/module-federation-ssr-dev-server/schema.json +1 -0
  8. package/src/executors/module-federation-static-server/schema.json +1 -0
  9. package/src/executors/rspack/lib/normalize-options.js +1 -0
  10. package/src/executors/rspack/schema.d.ts +6 -1
  11. package/src/executors/rspack/schema.json +14 -0
  12. package/src/executors/ssr-dev-server/schema.json +1 -0
  13. package/src/generators/application/application.js +0 -3
  14. package/src/generators/application/lib/normalize-options.js +7 -7
  15. package/src/generators/configuration/configuration.js +0 -3
  16. package/src/generators/convert-to-inferred/schema.json +4 -4
  17. package/src/generators/convert-webpack/convert-webpack.js +23 -0
  18. package/src/generators/convert-webpack/lib/transform-cjs.js +81 -0
  19. package/src/generators/convert-webpack/lib/transform-esm.js +81 -0
  20. package/src/generators/init/init.js +4 -1
  21. package/src/index.d.ts +1 -0
  22. package/src/index.js +1 -0
  23. package/src/migrations/update-20-2-0/migrate-with-mf-import-to-new-package.md +30 -0
  24. package/src/migrations/update-20-3-0/ensure-nx-module-federation-package.md +28 -0
  25. package/src/plugins/nx-app-rspack-plugin/nx-app-rspack-plugin.js +10 -0
  26. package/src/plugins/plugin.js +34 -9
  27. package/src/plugins/utils/apply-base-config.js +50 -13
  28. package/src/plugins/utils/apply-web-config.js +42 -11
  29. package/src/plugins/utils/is-lib-buildable.d.ts +7 -0
  30. package/src/plugins/utils/is-lib-buildable.js +48 -0
  31. package/src/plugins/utils/loaders/stylesheet-loaders.js +1 -1
  32. package/src/plugins/utils/models.d.ts +17 -2
  33. package/src/plugins/utils/plugins/normalize-options.js +3 -0
  34. package/src/plugins/write-index-html-plugin.d.ts +22 -0
  35. package/src/plugins/write-index-html-plugin.js +250 -0
  36. package/src/utils/e2e-web-server-info-utils.d.ts +2 -0
  37. package/src/utils/e2e-web-server-info-utils.js +25 -0
  38. package/src/utils/versions.d.ts +3 -3
  39. package/src/utils/versions.js +4 -4
  40. package/src/utils/webpack/interpolate-env-variables-to-index.d.ts +1 -0
  41. package/src/utils/webpack/interpolate-env-variables-to-index.js +29 -0
  42. package/src/utils/webpack/normalize-entry.d.ts +2 -0
  43. package/src/utils/webpack/normalize-entry.js +27 -0
  44. package/src/utils/webpack/package-chunk-sort.d.ts +5 -0
  45. package/src/utils/webpack/package-chunk-sort.js +30 -0
  46. package/src/utils/with-nx.js +1 -0
  47. package/src/utils/with-web.d.ts +7 -0
  48. package/src/utils/with-web.js +1 -0
@@ -14,7 +14,14 @@ const resolve_user_defined_rspack_config_1 = require("../utils/resolve-user-defi
14
14
  const util_1 = require("@nx/js/src/plugins/typescript/util");
15
15
  const pmc = (0, devkit_1.getPackageManagerCommand)();
16
16
  function readTargetsCache(cachePath) {
17
- return (0, fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
17
+ try {
18
+ return process.env.NX_CACHE_PROJECT_GRAPH !== 'false'
19
+ ? (0, devkit_1.readJsonFile)(cachePath)
20
+ : {};
21
+ }
22
+ catch {
23
+ return {};
24
+ }
18
25
  }
19
26
  function writeTargetsToCache(cachePath, results) {
20
27
  (0, devkit_1.writeJsonFile)(cachePath, results);
@@ -52,16 +59,15 @@ async function createNodesInternal(configFilePath, options, context, targetsCach
52
59
  packageJson = (0, devkit_1.readJsonFile)((0, path_1.join)(context.workspaceRoot, projectRoot, 'package.json'));
53
60
  }
54
61
  const normalizedOptions = normalizeOptions(options);
55
- // We do not want to alter how the hash is calculated, so appending the config file path to the hash
56
- // to prevent vite/vitest files overwriting the target cache created by the other
62
+ const lockFileHash = (0, file_hasher_1.hashFile)((0, path_1.join)(context.workspaceRoot, (0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)))) ?? '';
57
63
  const nodeHash = (0, file_hasher_1.hashArray)([
58
- ...[
59
- (0, path_1.join)(context.workspaceRoot, configFilePath),
60
- (0, path_1.join)(context.workspaceRoot, (0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot))),
61
- ].map(file_hasher_1.hashFile),
62
- (0, file_hasher_1.hashObject)(options),
64
+ (0, file_hasher_1.hashFile)((0, path_1.join)(context.workspaceRoot, configFilePath)),
65
+ lockFileHash,
66
+ (0, file_hasher_1.hashObject)({ ...options, isTsSolutionSetup }),
63
67
  (0, file_hasher_1.hashObject)(packageJson),
64
68
  ]);
69
+ // We do not want to alter how the hash is calculated, so appending the config file path to the hash
70
+ // to prevent vite/vitest files overwriting the target cache created by the other
65
71
  const hash = `${nodeHash}_${configFilePath}`;
66
72
  targetsCache[hash] ??= await createRspackTargets(configFilePath, projectRoot, normalizedOptions, context, isTsSolutionSetup);
67
73
  const { targets, metadata } = targetsCache[hash];
@@ -86,9 +92,23 @@ async function createRspackTargets(configFilePath, projectRoot, options, context
86
92
  }
87
93
  }
88
94
  const targets = {};
95
+ const env = {};
96
+ const isTsConfig = ['.ts', '.cts', '.mts'].includes((0, path_1.extname)(configFilePath));
97
+ if (isTsConfig) {
98
+ // https://rspack.dev/config/#using-ts-node
99
+ env['TS_NODE_COMPILER_OPTIONS'] = JSON.stringify({
100
+ module: 'CommonJS',
101
+ moduleResolution: 'Node10',
102
+ customConditions: null,
103
+ });
104
+ }
89
105
  targets[options.buildTargetName] = {
90
106
  command: `rspack build`,
91
- options: { cwd: projectRoot, args: ['--node-env=production'] },
107
+ options: {
108
+ cwd: projectRoot,
109
+ args: ['--node-env=production'],
110
+ env,
111
+ },
92
112
  cache: true,
93
113
  dependsOn: [`^${options.buildTargetName}`],
94
114
  inputs: 'production' in namedInputs
@@ -109,20 +129,25 @@ async function createRspackTargets(configFilePath, projectRoot, options, context
109
129
  outputs,
110
130
  };
111
131
  targets[options.serveTargetName] = {
132
+ continuous: true,
112
133
  command: `rspack serve`,
113
134
  options: {
114
135
  cwd: projectRoot,
115
136
  args: ['--node-env=development'],
137
+ env,
116
138
  },
117
139
  };
118
140
  targets[options.previewTargetName] = {
141
+ continuous: true,
119
142
  command: `rspack serve`,
120
143
  options: {
121
144
  cwd: projectRoot,
122
145
  args: ['--node-env=production'],
146
+ env,
123
147
  },
124
148
  };
125
149
  targets[options.serveStaticTargetName] = {
150
+ continuous: true,
126
151
  executor: '@nx/web:file-server',
127
152
  options: {
128
153
  buildTarget: options.buildTargetName,
@@ -13,6 +13,7 @@ const nx_tsconfig_paths_rspack_plugin_1 = require("./plugins/nx-tsconfig-paths-r
13
13
  const get_terser_ecma_version_1 = require("./get-terser-ecma-version");
14
14
  const nodeExternals = require("webpack-node-externals");
15
15
  const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
16
+ const is_lib_buildable_1 = require("./is-lib-buildable");
16
17
  const IGNORED_RSPACK_WARNINGS = [
17
18
  /The comment file/i,
18
19
  /could not find any license/i,
@@ -42,7 +43,7 @@ function applyNxIndependentConfig(options, config) {
42
43
  config.node = false;
43
44
  config.mode =
44
45
  // When the target is Node avoid any optimizations, such as replacing `process.env.NODE_ENV` with build time value.
45
- config.target === 'node'
46
+ config.target === 'node' || config.target === 'async-node'
46
47
  ? 'none'
47
48
  : // Otherwise, make sure it matches `process.env.NODE_ENV`.
48
49
  // When mode is development or production, rspack will automatically
@@ -59,13 +60,20 @@ function applyNxIndependentConfig(options, config) {
59
60
  : 'none');
60
61
  // When target is Node, the Webpack mode will be set to 'none' which disables in memory caching and causes a full rebuild on every change.
61
62
  // So to mitigate this we enable in memory caching when target is Node and in watch mode.
62
- config.cache = options.target === 'node' && options.watch ? true : undefined;
63
+ config.cache =
64
+ (options.target === 'node' || options.target === 'async-node') &&
65
+ options.watch
66
+ ? true
67
+ : undefined;
63
68
  config.devtool =
64
69
  options.sourceMap === true ? 'source-map' : options.sourceMap;
65
70
  config.output = {
66
71
  ...(config.output ?? {}),
67
- libraryTarget: config.output?.libraryTarget ??
68
- (options.target === 'node' ? 'commonjs' : undefined),
72
+ libraryTarget: options.target === 'node'
73
+ ? 'commonjs'
74
+ : options.target === 'async-node'
75
+ ? 'commonjs-module'
76
+ : undefined,
69
77
  path: config.output?.path ??
70
78
  (options.outputPath
71
79
  ? // If path is relative, it is relative from project root (aka cwd).
@@ -81,7 +89,7 @@ function applyNxIndependentConfig(options, config) {
81
89
  hashFunction: config.output?.hashFunction ?? 'xxhash64',
82
90
  // Disabled for performance
83
91
  pathinfo: config.output?.pathinfo ?? false,
84
- clean: options.deleteOutputPath,
92
+ clean: config.output?.clean ?? options.deleteOutputPath,
85
93
  };
86
94
  config.watch = options.watch;
87
95
  config.watchOptions = {
@@ -124,7 +132,6 @@ function applyNxIndependentConfig(options, config) {
124
132
  },
125
133
  }),
126
134
  ],
127
- runtimeChunk: false,
128
135
  concatenateModules: true,
129
136
  };
130
137
  config.stats = {
@@ -177,15 +184,18 @@ function applyNxDependentConfig(options, config, { useNormalizedEntry } = {}) {
177
184
  if (options.useTsconfigPaths) {
178
185
  plugins.push(new nx_tsconfig_paths_rspack_plugin_1.NxTsconfigPathsRspackPlugin({ ...options, tsConfig }));
179
186
  }
180
- // New TS Solution already has a typecheck target
181
- if (!options?.skipTypeChecking && !isUsingTsSolution) {
182
- const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
183
- plugins.push(new ForkTsCheckerWebpackPlugin({
187
+ // New TS Solution already has a typecheck target but allow it to run during serve
188
+ if ((!options?.skipTypeChecking && !isUsingTsSolution) ||
189
+ (isUsingTsSolution &&
190
+ options?.skipTypeChecking === false &&
191
+ process.env['WEBPACK_SERVE'])) {
192
+ const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');
193
+ plugins.push(new TsCheckerRspackPlugin({
184
194
  typescript: {
185
195
  configFile: path.isAbsolute(tsConfig)
186
196
  ? tsConfig
187
197
  : path.join(options.root, tsConfig),
188
- memoryLimit: options.memoryLimit || 2018,
198
+ memoryLimit: options.memoryLimit || 8192, // default memory limit is 8192
189
199
  },
190
200
  }));
191
201
  }
@@ -263,9 +273,34 @@ function applyNxDependentConfig(options, config, { useNormalizedEntry } = {}) {
263
273
  plugins.push(new stats_json_plugin_1.StatsJsonPlugin());
264
274
  }
265
275
  const externals = [];
266
- if (options.target === 'node' && options.externalDependencies === 'all') {
276
+ if ((options.target === 'node' || options.target === 'async-node') &&
277
+ options.externalDependencies === 'all') {
267
278
  const modulesDir = `${options.root}/node_modules`;
268
- externals.push(nodeExternals({ modulesDir }));
279
+ const graph = options.projectGraph;
280
+ const projectName = options.projectName;
281
+ const deps = graph?.dependencies?.[projectName] ?? [];
282
+ // Collect non-buildable TS project references so that they are bundled
283
+ // in the final output. This is needed for projects that are not buildable
284
+ // but are referenced by buildable projects. This is needed for the new TS
285
+ // solution setup.
286
+ const nonBuildableWorkspaceLibs = isUsingTsSolution
287
+ ? deps
288
+ .filter((dep) => {
289
+ const node = graph.nodes?.[dep.target];
290
+ if (!node || node.type !== 'lib')
291
+ return false;
292
+ const hasBuildTarget = 'build' in (node.data?.targets ?? {});
293
+ if (hasBuildTarget) {
294
+ return false;
295
+ }
296
+ // If there is no build target we check the package exports to see if they reference
297
+ // source files
298
+ return !(0, is_lib_buildable_1.isBuildableLibrary)(node);
299
+ })
300
+ .map((dep) => graph.nodes?.[dep.target]?.data?.metadata?.js?.packageName)
301
+ .filter((name) => !!name)
302
+ : [];
303
+ externals.push(nodeExternals({ modulesDir, allowlist: nonBuildableWorkspaceLibs }));
269
304
  }
270
305
  else if (Array.isArray(options.externalDependencies)) {
271
306
  externals.push(function (ctx, callback) {
@@ -333,6 +368,8 @@ function applyNxDependentConfig(options, config, { useNormalizedEntry } = {}) {
333
368
  tsx: true,
334
369
  },
335
370
  transform: {
371
+ legacyDecorator: true,
372
+ decoratorMetadata: true,
336
373
  react: {
337
374
  runtime: 'automatic',
338
375
  pragma: 'React.createElement',
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.applyWebConfig = applyWebConfig;
4
4
  const core_1 = require("@rspack/core");
5
+ const write_index_html_plugin_1 = require("../write-index-html-plugin");
5
6
  const instantiate_script_plugins_1 = require("./instantiate-script-plugins");
6
7
  const path_1 = require("path");
7
8
  const hash_format_1 = require("./hash-format");
@@ -32,14 +33,27 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
32
33
  plugins.push(...(0, instantiate_script_plugins_1.instantiateScriptPlugins)(options));
33
34
  }
34
35
  if (options.index && options.generateIndexHtml) {
35
- plugins.push(new core_1.HtmlRspackPlugin({
36
- template: options.index,
37
- sri: options.subresourceIntegrity ? 'sha256' : undefined,
38
- ...(options.baseHref ? { base: { href: options.baseHref } } : {}),
39
- ...(config.output?.scriptType === 'module'
40
- ? { scriptLoading: 'module' }
41
- : {}),
42
- }));
36
+ if (options.useLegacyHtmlPlugin) {
37
+ plugins.push(new write_index_html_plugin_1.WriteIndexHtmlPlugin({
38
+ indexPath: options.index,
39
+ outputPath: 'index.html',
40
+ baseHref: typeof options.baseHref === 'string' ? options.baseHref : undefined,
41
+ sri: options.subresourceIntegrity,
42
+ scripts: options.scripts,
43
+ styles: options.styles,
44
+ crossOrigin: config.output?.scriptType === 'module' ? 'anonymous' : undefined,
45
+ }));
46
+ }
47
+ else {
48
+ plugins.push(new core_1.HtmlRspackPlugin({
49
+ template: options.index,
50
+ sri: options.subresourceIntegrity ? 'sha256' : undefined,
51
+ ...(options.baseHref ? { base: { href: options.baseHref } } : {}),
52
+ ...(config.output?.scriptType === 'module'
53
+ ? { scriptLoading: 'module' }
54
+ : {}),
55
+ }));
56
+ }
43
57
  }
44
58
  const minimizer = [];
45
59
  if (isProd && stylesOptimization) {
@@ -54,6 +68,8 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
54
68
  const globalStylePaths = [];
55
69
  // Determine hashing format.
56
70
  const hashFormat = (0, hash_format_1.getOutputHashFormat)(options.outputHashing);
71
+ const sassOptions = options.stylePreprocessorOptions?.sassOptions;
72
+ const lessOptions = options.stylePreprocessorOptions?.lessOptions;
57
73
  const includePaths = [];
58
74
  if (options?.stylePreprocessorOptions?.includePaths?.length > 0) {
59
75
  options.stylePreprocessorOptions.includePaths.forEach((includePath) => includePaths.push((0, path_1.resolve)(options.root, includePath)));
@@ -88,11 +104,15 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
88
104
  {
89
105
  loader: require.resolve('sass-loader'),
90
106
  options: {
91
- implementation: require('sass'),
107
+ implementation: options.sassImplementation === 'sass'
108
+ ? require.resolve('sass')
109
+ : require.resolve('sass-embedded'),
110
+ api: 'modern-compiler',
92
111
  sassOptions: {
93
112
  fiber: false,
94
113
  precision: 8,
95
114
  includePaths,
115
+ ...(sassOptions ?? {}),
96
116
  },
97
117
  },
98
118
  },
@@ -108,6 +128,7 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
108
128
  options: {
109
129
  lessOptions: {
110
130
  paths: includePaths,
131
+ ...(lessOptions ?? {}),
111
132
  },
112
133
  },
113
134
  },
@@ -143,13 +164,17 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
143
164
  {
144
165
  loader: require.resolve('sass-loader'),
145
166
  options: {
146
- implementation: require('sass'),
167
+ api: 'modern-compiler',
168
+ implementation: options.sassImplementation === 'sass'
169
+ ? require.resolve('sass')
170
+ : require.resolve('sass-embedded'),
147
171
  sourceMap: !!options.sourceMap,
148
172
  sassOptions: {
149
173
  fiber: false,
150
174
  // bootstrap-sass requires a minimum precision of 8
151
175
  precision: 8,
152
176
  includePaths,
177
+ ...(sassOptions ?? {}),
153
178
  },
154
179
  },
155
180
  },
@@ -167,6 +192,7 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
167
192
  lessOptions: {
168
193
  javascriptEnabled: true,
169
194
  ...lessPathOptions,
195
+ ...(lessOptions ?? {}),
170
196
  },
171
197
  },
172
198
  },
@@ -203,13 +229,17 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
203
229
  {
204
230
  loader: require.resolve('sass-loader'),
205
231
  options: {
206
- implementation: require('sass'),
232
+ api: 'modern-compiler',
233
+ implementation: options.sassImplementation === 'sass'
234
+ ? require.resolve('sass')
235
+ : require.resolve('sass-embedded'),
207
236
  sourceMap: !!options.sourceMap,
208
237
  sassOptions: {
209
238
  fiber: false,
210
239
  // bootstrap-sass requires a minimum precision of 8
211
240
  precision: 8,
212
241
  includePaths,
242
+ ...(sassOptions ?? {}),
213
243
  },
214
244
  },
215
245
  },
@@ -227,6 +257,7 @@ function applyWebConfig(options, config = {}, { useNormalizedEntry, } = {}) {
227
257
  lessOptions: {
228
258
  javascriptEnabled: true,
229
259
  ...lessPathOptions,
260
+ ...(lessOptions ?? {}),
230
261
  },
231
262
  },
232
263
  },
@@ -0,0 +1,7 @@
1
+ import { type ProjectGraphProjectNode } from '@nx/devkit';
2
+ /**
3
+ * Check if the library is buildable.
4
+ * @param node from the project graph
5
+ * @returns boolean
6
+ */
7
+ export declare function isBuildableLibrary(node: ProjectGraphProjectNode): boolean;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isBuildableLibrary = isBuildableLibrary;
4
+ function isSourceFile(path) {
5
+ return ['.ts', '.tsx', '.mts', '.cts'].some((ext) => path.endsWith(ext));
6
+ }
7
+ function isBuildableExportMap(packageExports) {
8
+ if (!packageExports || Object.keys(packageExports).length === 0) {
9
+ return false; // exports = {} → not buildable
10
+ }
11
+ const isCompiledExport = (value) => {
12
+ if (typeof value === 'string') {
13
+ return !isSourceFile(value);
14
+ }
15
+ if (typeof value === 'object' && value !== null) {
16
+ return Object.entries(value).some(([key, subValue]) => {
17
+ if (key === 'types' ||
18
+ key === 'development' ||
19
+ key === './package.json')
20
+ return false;
21
+ return typeof subValue === 'string' && !isSourceFile(subValue);
22
+ });
23
+ }
24
+ return false;
25
+ };
26
+ if (packageExports['.']) {
27
+ return isCompiledExport(packageExports['.']);
28
+ }
29
+ return Object.entries(packageExports).some(([key, value]) => key !== '.' && isCompiledExport(value));
30
+ }
31
+ /**
32
+ * Check if the library is buildable.
33
+ * @param node from the project graph
34
+ * @returns boolean
35
+ */
36
+ function isBuildableLibrary(node) {
37
+ if (!node.data.metadata?.js) {
38
+ return false;
39
+ }
40
+ const { packageExports, packageMain } = node.data.metadata.js;
41
+ // if we have exports only check this else fallback to packageMain
42
+ if (packageExports) {
43
+ return isBuildableExportMap(packageExports);
44
+ }
45
+ return (typeof packageMain === 'string' &&
46
+ packageMain !== '' &&
47
+ !isSourceFile(packageMain));
48
+ }
@@ -99,7 +99,7 @@ function postcssOptionsCreator(options, { includePaths, forCssModules = false, }
99
99
  ? []
100
100
  : [
101
101
  (0, postcss_cli_resources_1.PostcssCliResources)({
102
- baseHref: options.baseHref,
102
+ baseHref: options.baseHref ? options.baseHref : undefined,
103
103
  deployUrl: options.deployUrl,
104
104
  loader,
105
105
  filename: `[name]${hashFormat.file}.[ext]`,
@@ -55,7 +55,7 @@ export interface NxAppRspackPluginOptions {
55
55
  /**
56
56
  * Set <base href> for the resulting index.html.
57
57
  */
58
- baseHref?: string;
58
+ baseHref?: string | false;
59
59
  /**
60
60
  * Build the libraries from source. Default is `true`.
61
61
  */
@@ -63,6 +63,7 @@ export interface NxAppRspackPluginOptions {
63
63
  commonChunk?: boolean;
64
64
  /**
65
65
  * Delete the output path before building.
66
+ * @deprecated Use the `output.clean` option in Rspack. https://rspack.dev/config/output#outputclean
66
67
  */
67
68
  deleteOutputPath?: boolean;
68
69
  /**
@@ -148,6 +149,11 @@ export interface NxAppRspackPluginOptions {
148
149
  * Add an additional chunk for the rspack runtime. Defaults to `true` when `target === 'web'`.
149
150
  */
150
151
  runtimeChunk?: boolean;
152
+ /**
153
+ * The implementation of the SASS compiler to use. Can be either `sass` or `sass-embedded`. Defaults to `sass-embedded`.
154
+ * @deprecated Sass option will be removed in Nx 22. This option will also be removed in Nx 22 as it is no longer needed.
155
+ */
156
+ sassImplementation?: 'sass' | 'sass-embedded';
151
157
  /**
152
158
  * External scripts that will be included before the main application entry.
153
159
  */
@@ -183,7 +189,11 @@ export interface NxAppRspackPluginOptions {
183
189
  /**
184
190
  * Options for the style preprocessor. e.g. `{ "includePaths": [] }` for SASS.
185
191
  */
186
- stylePreprocessorOptions?: any;
192
+ stylePreprocessorOptions?: {
193
+ includePaths?: string[];
194
+ sassOptions?: Record<string, any>;
195
+ lessOptions?: Record<string, any>;
196
+ };
187
197
  /**
188
198
  * External stylesheets that will be included with the application.
189
199
  */
@@ -224,6 +234,10 @@ export interface NxAppRspackPluginOptions {
224
234
  * Whether to rebase absolute path for assets in postcss cli resources.
225
235
  */
226
236
  rebaseRootRelative?: boolean;
237
+ /**
238
+ * Use the legacy WriteIndexHtmlPlugin instead of the built-in HtmlRspackPlugin.
239
+ */
240
+ useLegacyHtmlPlugin?: boolean;
227
241
  }
228
242
  export interface NormalizedNxAppRspackPluginOptions extends NxAppRspackPluginOptions {
229
243
  projectName: string;
@@ -235,4 +249,5 @@ export interface NormalizedNxAppRspackPluginOptions extends NxAppRspackPluginOpt
235
249
  projectGraph: ProjectGraph;
236
250
  outputFileName: string;
237
251
  assets: AssetGlobPattern[];
252
+ useLegacyHtmlPlugin: boolean;
238
253
  }
@@ -65,6 +65,7 @@ function normalizeOptions(options) {
65
65
  extractCss: combinedPluginAndMaybeExecutorOptions.extractCss ?? true,
66
66
  fileReplacements: normalizeFileReplacements(devkit_1.workspaceRoot, combinedPluginAndMaybeExecutorOptions.fileReplacements),
67
67
  generateIndexHtml: combinedPluginAndMaybeExecutorOptions.generateIndexHtml ?? true,
68
+ useLegacyHtmlPlugin: combinedPluginAndMaybeExecutorOptions.useLegacyHtmlPlugin ?? false,
68
69
  main: combinedPluginAndMaybeExecutorOptions.main,
69
70
  namedChunks: combinedPluginAndMaybeExecutorOptions.namedChunks ?? !isProd,
70
71
  optimization: combinedPluginAndMaybeExecutorOptions.optimization ?? isProd,
@@ -77,6 +78,8 @@ function normalizeOptions(options) {
77
78
  projectRoot: projectNode.data.root,
78
79
  root: devkit_1.workspaceRoot,
79
80
  runtimeChunk: combinedPluginAndMaybeExecutorOptions.runtimeChunk ?? true,
81
+ sassImplementation: combinedPluginAndMaybeExecutorOptions.sassImplementation ??
82
+ 'sass-embedded',
80
83
  scripts: combinedPluginAndMaybeExecutorOptions.scripts ?? [],
81
84
  sourceMap: combinedPluginAndMaybeExecutorOptions.sourceMap ?? !isProd,
82
85
  sourceRoot,
@@ -0,0 +1,22 @@
1
+ import { Compiler } from '@rspack/core';
2
+ import { ExtraEntryPoint } from '../utils/model';
3
+ export interface WriteIndexHtmlOptions {
4
+ indexPath: string;
5
+ outputPath: string;
6
+ baseHref?: string;
7
+ deployUrl?: string;
8
+ sri?: boolean;
9
+ scripts?: ExtraEntryPoint[];
10
+ styles?: ExtraEntryPoint[];
11
+ crossOrigin?: 'none' | 'anonymous' | 'use-credentials';
12
+ }
13
+ export declare class WriteIndexHtmlPlugin {
14
+ private readonly options;
15
+ constructor(options: WriteIndexHtmlOptions);
16
+ apply(compiler: Compiler): void;
17
+ private getEmittedFiles;
18
+ private stripBom;
19
+ private augmentIndexHtml;
20
+ private generateSriAttributes;
21
+ private filterAndMapBuildFiles;
22
+ }