@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
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WriteIndexHtmlPlugin = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const rspack = tslib_1.__importStar(require("@rspack/core"));
6
+ const crypto_1 = require("crypto");
7
+ const fs_1 = require("fs");
8
+ const interpolate_env_variables_to_index_1 = require("../utils/webpack/interpolate-env-variables-to-index");
9
+ const package_chunk_sort_1 = require("../utils/webpack/package-chunk-sort");
10
+ const path_1 = require("path");
11
+ const parse5 = require('parse5');
12
+ class WriteIndexHtmlPlugin {
13
+ constructor(options) {
14
+ this.options = options;
15
+ }
16
+ apply(compiler) {
17
+ const { outputPath, indexPath, baseHref, deployUrl, sri = false, scripts = [], styles = [], crossOrigin, } = this.options;
18
+ compiler.hooks.thisCompilation.tap('WriteIndexHtmlPlugin', (compilation) => {
19
+ compilation.hooks.processAssets.tap({
20
+ name: 'WriteIndexHtmlPlugin',
21
+ // After minification and sourcemaps are done
22
+ stage: rspack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE,
23
+ }, () => {
24
+ const moduleFiles = this.getEmittedFiles(compilation);
25
+ const files = moduleFiles.filter((x) => x.extension === '.css');
26
+ let content = (0, fs_1.readFileSync)(indexPath).toString();
27
+ content = this.stripBom(content);
28
+ compilation.assets[outputPath] = this.augmentIndexHtml({
29
+ input: outputPath,
30
+ inputContent: (0, interpolate_env_variables_to_index_1.interpolateEnvironmentVariablesToIndex)(content, deployUrl),
31
+ baseHref,
32
+ deployUrl,
33
+ crossOrigin,
34
+ sri,
35
+ entrypoints: (0, package_chunk_sort_1.generateEntryPoints)({ scripts, styles }),
36
+ files: this.filterAndMapBuildFiles(files, ['.js', '.css']),
37
+ moduleFiles: this.filterAndMapBuildFiles(moduleFiles, ['.js']),
38
+ loadOutputFile: (filePath) => compilation.assets[filePath].source().toString(),
39
+ });
40
+ });
41
+ });
42
+ }
43
+ getEmittedFiles(compilation) {
44
+ const files = [];
45
+ // adds all chunks to the list of emitted files such as lazy loaded modules
46
+ for (const chunk of compilation.chunks) {
47
+ for (const file of chunk.files) {
48
+ files.push({
49
+ // The id is guaranteed to exist at this point in the compilation process
50
+ id: chunk.id.toString(),
51
+ name: chunk.name,
52
+ file,
53
+ extension: (0, path_1.extname)(file),
54
+ initial: chunk.isOnlyInitial(),
55
+ });
56
+ }
57
+ }
58
+ // other all files
59
+ for (const file of Object.keys(compilation.assets)) {
60
+ files.push({
61
+ file,
62
+ extension: (0, path_1.extname)(file),
63
+ initial: false,
64
+ asset: true,
65
+ });
66
+ }
67
+ // dedupe
68
+ return files.filter(({ file, name }, index) => files.findIndex((f) => f.file === file && (!name || name === f.name)) === index);
69
+ }
70
+ stripBom(data) {
71
+ return data.replace(/^\uFEFF/, '');
72
+ }
73
+ augmentIndexHtml(params) {
74
+ const { loadOutputFile, files, moduleFiles = [], entrypoints } = params;
75
+ let { crossOrigin = 'none' } = params;
76
+ if (params.sri && crossOrigin === 'none') {
77
+ crossOrigin = 'anonymous';
78
+ }
79
+ const stylesheets = new Set();
80
+ const scripts = new Set();
81
+ // Sort files in the order we want to insert them by entrypoint and dedupes duplicates
82
+ const mergedFiles = [...moduleFiles, ...files];
83
+ for (const entrypoint of entrypoints) {
84
+ for (const { extension, file, name } of mergedFiles) {
85
+ if (name !== entrypoint) {
86
+ continue;
87
+ }
88
+ switch (extension) {
89
+ case '.js':
90
+ scripts.add(file);
91
+ break;
92
+ case '.css':
93
+ stylesheets.add(file);
94
+ break;
95
+ }
96
+ }
97
+ }
98
+ // Find the head and body elements
99
+ const treeAdapter = parse5.treeAdapters.default;
100
+ const document = parse5.parse(params.inputContent, {
101
+ treeAdapter,
102
+ locationInfo: true,
103
+ });
104
+ let headElement;
105
+ let bodyElement;
106
+ for (const docChild of document.childNodes) {
107
+ if (docChild.tagName === 'html') {
108
+ for (const htmlChild of docChild.childNodes) {
109
+ if (htmlChild.tagName === 'head') {
110
+ headElement = htmlChild;
111
+ }
112
+ else if (htmlChild.tagName === 'body') {
113
+ bodyElement = htmlChild;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ if (!headElement || !bodyElement) {
119
+ throw new Error('Missing head and/or body elements');
120
+ }
121
+ // Determine script insertion point
122
+ let scriptInsertionPoint;
123
+ if (bodyElement.__location && bodyElement.__location.endTag) {
124
+ scriptInsertionPoint = bodyElement.__location.endTag.startOffset;
125
+ }
126
+ else {
127
+ // Less accurate fallback
128
+ // parse5 4.x does not provide locations if malformed html is present
129
+ scriptInsertionPoint = params.inputContent.indexOf('</body>');
130
+ }
131
+ let styleInsertionPoint;
132
+ if (headElement.__location && headElement.__location.endTag) {
133
+ styleInsertionPoint = headElement.__location.endTag.startOffset;
134
+ }
135
+ else {
136
+ // Less accurate fallback
137
+ // parse5 4.x does not provide locations if malformed html is present
138
+ styleInsertionPoint = params.inputContent.indexOf('</head>');
139
+ }
140
+ // Inject into the html
141
+ const indexSource = new rspack.sources.ReplaceSource(new rspack.sources.RawSource(params.inputContent), params.input);
142
+ let scriptElements = '';
143
+ for (const script of scripts) {
144
+ const attrs = [
145
+ { name: 'src', value: (params.deployUrl || '') + script },
146
+ ];
147
+ if (crossOrigin !== 'none') {
148
+ attrs.push({ name: 'crossorigin', value: crossOrigin });
149
+ }
150
+ // We want to include nomodule or module when a file is not common amongs all
151
+ // such as runtime.js
152
+ const scriptPredictor = ({ file, }) => file === script;
153
+ if (!files.some(scriptPredictor)) {
154
+ // in some cases for differential loading file with the same name is avialable in both
155
+ // nomodule and module such as scripts.js
156
+ // we shall not add these attributes if that's the case
157
+ const isModuleType = moduleFiles.some(scriptPredictor);
158
+ if (isModuleType) {
159
+ attrs.push({ name: 'type', value: 'module' });
160
+ }
161
+ else {
162
+ attrs.push({ name: 'defer', value: null });
163
+ }
164
+ }
165
+ else {
166
+ attrs.push({ name: 'type', value: 'module' });
167
+ }
168
+ if (params.sri) {
169
+ const content = loadOutputFile(script);
170
+ attrs.push(...this.generateSriAttributes(content));
171
+ }
172
+ const attributes = attrs
173
+ .map((attr) => attr.value === null ? attr.name : `${attr.name}="${attr.value}"`)
174
+ .join(' ');
175
+ scriptElements += `<script ${attributes}></script>`;
176
+ }
177
+ indexSource.insert(scriptInsertionPoint, scriptElements);
178
+ // Adjust base href if specified
179
+ if (typeof params.baseHref == 'string') {
180
+ let baseElement;
181
+ for (const headChild of headElement.childNodes) {
182
+ if (headChild.tagName === 'base') {
183
+ baseElement = headChild;
184
+ }
185
+ }
186
+ const baseFragment = treeAdapter.createDocumentFragment();
187
+ if (!baseElement) {
188
+ baseElement = treeAdapter.createElement('base', undefined, [
189
+ { name: 'href', value: params.baseHref },
190
+ ]);
191
+ treeAdapter.appendChild(baseFragment, baseElement);
192
+ indexSource.insert(headElement.__location.startTag.endOffset, parse5.serialize(baseFragment, { treeAdapter }));
193
+ }
194
+ else {
195
+ let hrefAttribute;
196
+ for (const attribute of baseElement.attrs) {
197
+ if (attribute.name === 'href') {
198
+ hrefAttribute = attribute;
199
+ }
200
+ }
201
+ if (hrefAttribute) {
202
+ hrefAttribute.value = params.baseHref;
203
+ }
204
+ else {
205
+ baseElement.attrs.push({ name: 'href', value: params.baseHref });
206
+ }
207
+ treeAdapter.appendChild(baseFragment, baseElement);
208
+ indexSource.replace(baseElement.__location.startOffset, baseElement.__location.endOffset, parse5.serialize(baseFragment, { treeAdapter }));
209
+ }
210
+ }
211
+ const styleElements = treeAdapter.createDocumentFragment();
212
+ for (const stylesheet of stylesheets) {
213
+ const attrs = [
214
+ { name: 'rel', value: 'stylesheet' },
215
+ { name: 'href', value: (params.deployUrl || '') + stylesheet },
216
+ ];
217
+ if (crossOrigin !== 'none') {
218
+ attrs.push({ name: 'crossorigin', value: crossOrigin });
219
+ }
220
+ if (params.sri) {
221
+ const content = loadOutputFile(stylesheet);
222
+ attrs.push(...this.generateSriAttributes(content));
223
+ }
224
+ const element = treeAdapter.createElement('link', undefined, attrs);
225
+ treeAdapter.appendChild(styleElements, element);
226
+ }
227
+ indexSource.insert(styleInsertionPoint, parse5.serialize(styleElements, { treeAdapter }));
228
+ return indexSource;
229
+ }
230
+ generateSriAttributes(content) {
231
+ const algo = 'sha384';
232
+ const hash = (0, crypto_1.createHash)(algo).update(content, 'utf8').digest('base64');
233
+ return [{ name: 'integrity', value: `${algo}-${hash}` }];
234
+ }
235
+ filterAndMapBuildFiles(files, extensionFilter) {
236
+ const filteredFiles = [];
237
+ // This test excludes files generated by HMR (e.g. main.hot-update.js).
238
+ const hotUpdateAsset = /hot-update\.[cm]?js$/;
239
+ for (const { file, name, extension, initial } of files) {
240
+ if (name &&
241
+ initial &&
242
+ extensionFilter.includes(extension) &&
243
+ !hotUpdateAsset.test(file)) {
244
+ filteredFiles.push({ file, extension, name });
245
+ }
246
+ }
247
+ return filteredFiles;
248
+ }
249
+ }
250
+ exports.WriteIndexHtmlPlugin = WriteIndexHtmlPlugin;
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export declare function getRspackE2EWebServerInfo(tree: Tree, projectName: string, configFilePath: string, isPluginBeingAdded: boolean, e2ePortOverride?: number): Promise<import("@nx/devkit/src/generators/e2e-web-server-info-utils").E2EWebServerDetails>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRspackE2EWebServerInfo = getRspackE2EWebServerInfo;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const e2e_web_server_info_utils_1 = require("@nx/devkit/src/generators/e2e-web-server-info-utils");
6
+ async function getRspackE2EWebServerInfo(tree, projectName, configFilePath, isPluginBeingAdded, e2ePortOverride) {
7
+ const nxJson = (0, devkit_1.readNxJson)(tree);
8
+ let e2ePort = e2ePortOverride ?? 4200;
9
+ if (nxJson.targetDefaults?.['serve'] &&
10
+ nxJson.targetDefaults?.['serve'].options?.port) {
11
+ e2ePort = nxJson.targetDefaults?.['serve'].options?.port;
12
+ }
13
+ return (0, e2e_web_server_info_utils_1.getE2EWebServerInfo)(tree, projectName, {
14
+ plugin: '@nx/rspack/plugin',
15
+ serveTargetName: 'serveTargetName',
16
+ serveStaticTargetName: 'previewTargetName',
17
+ configFilePath,
18
+ }, {
19
+ defaultServeTargetName: 'serve',
20
+ defaultServeStaticTargetName: 'preview',
21
+ defaultE2EWebServerAddress: `http://localhost:${e2ePort}`,
22
+ defaultE2ECiBaseUrl: 'http://localhost:4200',
23
+ defaultE2EPort: e2ePort,
24
+ }, isPluginBeingAdded);
25
+ }
@@ -1,16 +1,16 @@
1
1
  export declare const nxVersion: any;
2
- export declare const rspackCoreVersion = "^1.1.5";
2
+ export declare const rspackCoreVersion = "1.2.2";
3
3
  export declare const rspackDevServerVersion = "1.0.9";
4
- export declare const rspackPluginMinifyVersion = "^0.7.5";
5
4
  export declare const rspackPluginReactRefreshVersion = "^1.0.0";
6
5
  export declare const lessLoaderVersion = "~11.1.3";
6
+ export declare const sassLoaderVersion = "^16.0.4";
7
+ export declare const sassEmbeddedVersion = "^1.83.4";
7
8
  export declare const reactRefreshVersion = "~0.14.0";
8
9
  export declare const nestjsCommonVersion = "~9.0.0";
9
10
  export declare const nestjsCoreVersion = "~9.0.0";
10
11
  export declare const nestjsPlatformExpressVersion = "~9.0.0";
11
12
  export declare const nestjsMicroservicesVersion = "~9.0.0";
12
13
  export declare const lessVersion = "4.1.3";
13
- export declare const sassVersion = "^1.42.1";
14
14
  export declare const stylusVersion = "^0.55.0";
15
15
  export declare const eslintPluginImportVersion = "2.27.5";
16
16
  export declare const eslintPluginJsxA11yVersion = "6.7.1";
@@ -1,19 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.eslintPluginReactHooksVersion = exports.eslintPluginReactVersion = exports.eslintPluginJsxA11yVersion = exports.eslintPluginImportVersion = exports.stylusVersion = exports.sassVersion = exports.lessVersion = exports.nestjsMicroservicesVersion = exports.nestjsPlatformExpressVersion = exports.nestjsCoreVersion = exports.nestjsCommonVersion = exports.reactRefreshVersion = exports.lessLoaderVersion = exports.rspackPluginReactRefreshVersion = exports.rspackPluginMinifyVersion = exports.rspackDevServerVersion = exports.rspackCoreVersion = exports.nxVersion = void 0;
3
+ exports.eslintPluginReactHooksVersion = exports.eslintPluginReactVersion = exports.eslintPluginJsxA11yVersion = exports.eslintPluginImportVersion = exports.stylusVersion = exports.lessVersion = exports.nestjsMicroservicesVersion = exports.nestjsPlatformExpressVersion = exports.nestjsCoreVersion = exports.nestjsCommonVersion = exports.reactRefreshVersion = exports.sassEmbeddedVersion = exports.sassLoaderVersion = exports.lessLoaderVersion = exports.rspackPluginReactRefreshVersion = exports.rspackDevServerVersion = exports.rspackCoreVersion = exports.nxVersion = void 0;
4
4
  exports.nxVersion = require('../../package.json').version;
5
- exports.rspackCoreVersion = '^1.1.5';
5
+ exports.rspackCoreVersion = '1.2.2';
6
6
  exports.rspackDevServerVersion = '1.0.9';
7
- exports.rspackPluginMinifyVersion = '^0.7.5';
8
7
  exports.rspackPluginReactRefreshVersion = '^1.0.0';
9
8
  exports.lessLoaderVersion = '~11.1.3';
9
+ exports.sassLoaderVersion = '^16.0.4';
10
+ exports.sassEmbeddedVersion = '^1.83.4';
10
11
  exports.reactRefreshVersion = '~0.14.0';
11
12
  exports.nestjsCommonVersion = '~9.0.0';
12
13
  exports.nestjsCoreVersion = '~9.0.0';
13
14
  exports.nestjsPlatformExpressVersion = '~9.0.0';
14
15
  exports.nestjsMicroservicesVersion = '~9.0.0';
15
16
  exports.lessVersion = '4.1.3';
16
- exports.sassVersion = '^1.42.1';
17
17
  exports.stylusVersion = '^0.55.0';
18
18
  exports.eslintPluginImportVersion = '2.27.5';
19
19
  exports.eslintPluginJsxA11yVersion = '6.7.1';
@@ -0,0 +1 @@
1
+ export declare function interpolateEnvironmentVariablesToIndex(contents: string, deployUrl?: string): string;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.interpolateEnvironmentVariablesToIndex = interpolateEnvironmentVariablesToIndex;
4
+ function interpolateEnvironmentVariablesToIndex(contents, deployUrl) {
5
+ const environmentVariables = getClientEnvironment(deployUrl || '');
6
+ return interpolateEnvironmentVariables(contents, environmentVariables);
7
+ }
8
+ const NX_PREFIX = /^NX_PUBLIC_/i;
9
+ function isNxEnvironmentKey(x) {
10
+ return NX_PREFIX.test(x);
11
+ }
12
+ function getClientEnvironment(deployUrl) {
13
+ return Object.keys(process.env)
14
+ .filter(isNxEnvironmentKey)
15
+ .reduce((env, key) => {
16
+ env[key] = process.env[key];
17
+ return env;
18
+ }, {
19
+ NODE_ENV: process.env.NODE_ENV || 'development',
20
+ DEPLOY_URL: deployUrl || process.env.DEPLOY_URL || '',
21
+ });
22
+ }
23
+ function interpolateEnvironmentVariables(documentContents, environmentVariables) {
24
+ let temp = documentContents;
25
+ for (const [key, value] of Object.entries(environmentVariables)) {
26
+ temp = temp.replace(new RegExp(`%${key}%`, 'g'), value);
27
+ }
28
+ return temp;
29
+ }
@@ -0,0 +1,2 @@
1
+ import { ExtraEntryPoint, NormalizedEntryPoint } from '../model';
2
+ export declare function normalizeExtraEntryPoints(extraEntryPoints: ExtraEntryPoint[], defaultBundleName: string): NormalizedEntryPoint[];
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeExtraEntryPoints = normalizeExtraEntryPoints;
4
+ function normalizeExtraEntryPoints(extraEntryPoints, defaultBundleName) {
5
+ return extraEntryPoints.map((entry) => {
6
+ let normalizedEntry;
7
+ if (typeof entry === 'string') {
8
+ normalizedEntry = {
9
+ input: entry,
10
+ inject: true,
11
+ bundleName: defaultBundleName,
12
+ };
13
+ }
14
+ else {
15
+ const { inject = true, ...newEntry } = entry;
16
+ let bundleName;
17
+ if (entry.bundleName) {
18
+ bundleName = entry.bundleName;
19
+ }
20
+ else {
21
+ bundleName = defaultBundleName;
22
+ }
23
+ normalizedEntry = { ...newEntry, bundleName };
24
+ }
25
+ return normalizedEntry;
26
+ });
27
+ }
@@ -0,0 +1,5 @@
1
+ import { ExtraEntryPoint } from '../model';
2
+ export declare function generateEntryPoints(appConfig: {
3
+ styles: ExtraEntryPoint[];
4
+ scripts: ExtraEntryPoint[];
5
+ }): string[];
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateEntryPoints = generateEntryPoints;
4
+ const normalize_entry_1 = require("./normalize-entry");
5
+ function generateEntryPoints(appConfig) {
6
+ // Add all styles/scripts, except lazy-loaded ones.
7
+ const extraEntryPoints = (extraEntryPoints, defaultBundleName) => {
8
+ const entryPoints = (0, normalize_entry_1.normalizeExtraEntryPoints)(extraEntryPoints, defaultBundleName).map((entry) => entry.bundleName);
9
+ // remove duplicates
10
+ return [...new Set(entryPoints)];
11
+ };
12
+ const styleEntryPoints = appConfig.styles.filter((style) => !(typeof style !== 'string' && !style.inject));
13
+ const scriptEntryPoints = appConfig.scripts.filter((script) => !(typeof script !== 'string' && !script.inject));
14
+ const entryPoints = [
15
+ 'runtime',
16
+ 'polyfills',
17
+ 'sw-register',
18
+ ...extraEntryPoints(styleEntryPoints, 'styles'),
19
+ ...extraEntryPoints(scriptEntryPoints, 'scripts'),
20
+ 'vendor',
21
+ 'main',
22
+ ];
23
+ const duplicates = [
24
+ ...new Set(entryPoints.filter((x) => entryPoints.indexOf(x) !== entryPoints.lastIndexOf(x))),
25
+ ];
26
+ if (duplicates.length > 0) {
27
+ throw new Error(`Multiple bundles have been named the same: '${duplicates.join(`', '`)}'.`);
28
+ }
29
+ return entryPoints;
30
+ }
@@ -26,6 +26,7 @@ function withNx(pluginOptions = {}) {
26
26
  targetName: context.targetName,
27
27
  configurationName: context.configurationName,
28
28
  projectGraph: context.projectGraph,
29
+ useLegacyHtmlPlugin: pluginOptions.useLegacyHtmlPlugin ?? false,
29
30
  }, config);
30
31
  processed.add(config);
31
32
  return config;
@@ -8,12 +8,19 @@ export interface WithWebOptions {
8
8
  generateIndexHtml?: boolean;
9
9
  index?: string;
10
10
  postcssConfig?: string;
11
+ sassImplementation?: 'sass' | 'sass-embedded';
11
12
  scripts?: Array<ExtraEntryPointClass | string>;
12
13
  styles?: Array<ExtraEntryPointClass | string>;
13
14
  stylePreprocessorOptions?: {
14
15
  includePaths?: string[];
16
+ sassOptions?: Record<string, any>;
17
+ lessOptions?: Record<string, any>;
15
18
  };
16
19
  cssModules?: boolean;
17
20
  ssr?: boolean;
21
+ /**
22
+ * Use the legacy WriteIndexHtmlPlugin instead of the built-in HtmlRspackPlugin.
23
+ */
24
+ useLegacyHtmlPlugin?: boolean;
18
25
  }
19
26
  export declare function withWeb(pluginOptions?: WithWebOptions): (config: Configuration, { options, context }: NxRspackExecutionContext) => Configuration;
@@ -16,6 +16,7 @@ function withWeb(pluginOptions = {}) {
16
16
  targetName: context.targetName,
17
17
  configurationName: context.configurationName,
18
18
  projectGraph: context.projectGraph,
19
+ useLegacyHtmlPlugin: pluginOptions.useLegacyHtmlPlugin ?? false,
19
20
  }, config);
20
21
  processed.add(config);
21
22
  return config;