@nx/react 23.3.0-canary.20260915-071d621 → 23.3.0-canary.20260917-ea5c01d

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.
@@ -72,6 +72,8 @@ function bundlerDeps(bundler) {
72
72
  '@rspack/cli': mfVersions.rspackCliVersion,
73
73
  '@rspack/core': mfVersions.rspackCoreVersion,
74
74
  '@rspack/dev-server': mfVersions.rspackDevServerVersion,
75
+ '@rspack/plugin-react-refresh': mfVersions.rspackPluginReactRefreshVersion,
76
+ 'react-refresh': mfVersions.reactRefreshVersion,
75
77
  },
76
78
  };
77
79
  }
@@ -8,4 +8,6 @@ export declare const rsbuildPluginReactVersion = "^1.3.0";
8
8
  export declare const moduleFederationRsbuildPluginVersion = "^2.5.0";
9
9
  export declare const rspackCoreVersion = "^2.0.3";
10
10
  export declare const rspackCliVersion = "^2.0.3";
11
+ export declare const rspackPluginReactRefreshVersion = "^2.0.0";
12
+ export declare const reactRefreshVersion = "~0.14.0";
11
13
  export declare const rspackDevServerVersion = "2.0.1";
@@ -3,7 +3,7 @@
3
3
  // versions (react, react-dom, @types/*, typescript) are owned by @nx/react
4
4
  // (../../utils/versions) and @nx/js so each dep has a single source of truth.
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.rspackDevServerVersion = exports.rspackCliVersion = exports.rspackCoreVersion = exports.moduleFederationRsbuildPluginVersion = exports.rsbuildPluginReactVersion = exports.rsbuildCoreVersion = exports.vitejsPluginReactVersion = exports.viteVersion = exports.moduleFederationRuntimeVersion = exports.moduleFederationVitePluginVersion = exports.moduleFederationEnhancedVersion = void 0;
6
+ exports.rspackDevServerVersion = exports.reactRefreshVersion = exports.rspackPluginReactRefreshVersion = exports.rspackCliVersion = exports.rspackCoreVersion = exports.moduleFederationRsbuildPluginVersion = exports.rsbuildPluginReactVersion = exports.rsbuildCoreVersion = exports.vitejsPluginReactVersion = exports.viteVersion = exports.moduleFederationRuntimeVersion = exports.moduleFederationVitePluginVersion = exports.moduleFederationEnhancedVersion = void 0;
7
7
  // Module Federation runtime packages. Keep `runtime` on the same major as
8
8
  // `enhanced` / the `vite` plugin (both pull runtime 2.4.x). A 0.x runtime in
9
9
  // the consumer would mismatch the 2.x runtime baked into the providers.
@@ -23,6 +23,9 @@ exports.moduleFederationRsbuildPluginVersion = '^2.5.0';
23
23
  // Rspack stack.
24
24
  exports.rspackCoreVersion = '^2.0.3';
25
25
  exports.rspackCliVersion = '^2.0.3';
26
+ // @rspack/plugin-react-refresh 2.x peers react-refresh >=0.10 <1.
27
+ exports.rspackPluginReactRefreshVersion = '^2.0.0';
28
+ exports.reactRefreshVersion = '~0.14.0';
26
29
  // Pinned (no ^) to dodge the broken 2.0.2 publish, which ships no dist/ so
27
30
  // @rspack/cli can't load it for `rspack serve`. Re-float to ^ once upstream
28
31
  // republishes a fixed 2.0.3+.
@@ -16,8 +16,10 @@
16
16
  "@rspack/cli": "<%= versions.rspackCliVersion %>",
17
17
  "@rspack/core": "<%= versions.rspackCoreVersion %>",
18
18
  "@rspack/dev-server": "<%= versions.rspackDevServerVersion %>",
19
+ "@rspack/plugin-react-refresh": "<%= versions.rspackPluginReactRefreshVersion %>",
19
20
  "@types/react": "<%= versions.typesReactVersion %>",
20
21
  "@types/react-dom": "<%= versions.typesReactDomVersion %>",
22
+ "react-refresh": "<%= versions.reactRefreshVersion %>",
21
23
  "typescript": "<%= versions.typescriptVersion %>"
22
24
  }
23
25
  }
@@ -1,6 +1,7 @@
1
1
  import { defineConfig } from '@rspack/cli';
2
2
  import { rspack } from '@rspack/core';
3
3
  import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack';
4
+ import { ReactRefreshRspackPlugin } from '@rspack/plugin-react-refresh';
4
5
  import * as path from 'node:path';
5
6
  import { fileURLToPath } from 'node:url';
6
7
 
@@ -38,7 +39,9 @@ export default defineConfig((_env, argv) => {
38
39
  options: {
39
40
  jsc: {
40
41
  parser: { syntax: 'typescript', tsx: true },
41
- transform: { react: { runtime: 'automatic', development: isDev } },
42
+ transform: {
43
+ react: { runtime: 'automatic', development: isDev, refresh: isDev },
44
+ },
42
45
  },
43
46
  env: { targets: 'Chrome >= 87, Firefox >= 78, Edge >= 88, Safari >= 14' },
44
47
  },
@@ -47,6 +50,7 @@ export default defineConfig((_env, argv) => {
47
50
  ],
48
51
  },
49
52
  plugins: [
53
+ isDev && new ReactRefreshRspackPlugin(),
50
54
  new rspack.HtmlRspackPlugin({ template: './index.html' }),
51
55
  new ModuleFederationPlugin({
52
56
  name: NAME,
@@ -54,6 +58,6 @@ export default defineConfig((_env, argv) => {
54
58
  // src/mf.ts at module load time.
55
59
  shared: ['react', 'react-dom'],
56
60
  }),
57
- ],
61
+ ].filter(Boolean),
58
62
  };
59
63
  });
@@ -26,13 +26,7 @@ async function cypressComponentConfigGeneratorInternal(tree, options) {
26
26
  nxJson.useInferencePlugins !== false;
27
27
  options.addPlugin ??= addPlugin;
28
28
  const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
29
- const installTask = await baseCyCtConfig(tree, {
30
- project: options.project,
31
- skipFormat: true,
32
- jsx: true,
33
- addPlugin: options.addPlugin,
34
- });
35
- const found = await (0, ct_utils_1.configureCypressCT)(tree, {
29
+ const { found, bundler } = await (0, ct_utils_1.resolveCypressCTTarget)(tree, {
36
30
  project: options.project,
37
31
  buildTarget: options.buildTarget,
38
32
  bundler: options.bundler,
@@ -41,6 +35,14 @@ async function cypressComponentConfigGeneratorInternal(tree, options) {
41
35
  '@nx/vite:build',
42
36
  ]),
43
37
  });
38
+ const installTask = await baseCyCtConfig(tree, {
39
+ project: options.project,
40
+ skipFormat: true,
41
+ jsx: true,
42
+ addPlugin: options.addPlugin,
43
+ bundler,
44
+ });
45
+ await (0, ct_utils_1.configureCypressCT)(tree, { project: options.project, found, bundler });
44
46
  await (0, add_files_1.addFiles)(tree, projectConfig, options, found);
45
47
  if (!options.skipFormat) {
46
48
  await (0, devkit_1.formatFiles)(tree);
@@ -143,6 +143,11 @@ async function hostGenerator(host, schema) {
143
143
  : {}),
144
144
  }, undefined, true);
145
145
  tasks.push(installTask);
146
+ // The TS config templates use extensionless relative imports and
147
+ // `__dirname`, which Node's native type stripping cannot load.
148
+ if (options.typescriptConfiguration) {
149
+ tasks.push((0, internal_3.addSwcRegisterDependencies)(host));
150
+ }
146
151
  if (!options.skipFormat) {
147
152
  await (0, devkit_1.formatFiles)(host);
148
153
  }
@@ -15,8 +15,10 @@
15
15
  "@rspack/cli": "<%= versions.rspackCliVersion %>",
16
16
  "@rspack/core": "<%= versions.rspackCoreVersion %>",
17
17
  "@rspack/dev-server": "<%= versions.rspackDevServerVersion %>",
18
+ "@rspack/plugin-react-refresh": "<%= versions.rspackPluginReactRefreshVersion %>",
18
19
  "@types/react": "<%= versions.typesReactVersion %>",
19
20
  "@types/react-dom": "<%= versions.typesReactDomVersion %>",
21
+ "react-refresh": "<%= versions.reactRefreshVersion %>",
20
22
  "typescript": "<%= versions.typescriptVersion %>"
21
23
  }
22
24
  }
@@ -1,6 +1,7 @@
1
1
  import { defineConfig } from '@rspack/cli';
2
2
  import { rspack } from '@rspack/core';
3
3
  import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack';
4
+ import { ReactRefreshRspackPlugin } from '@rspack/plugin-react-refresh';
4
5
  import * as path from 'node:path';
5
6
  import { fileURLToPath } from 'node:url';
6
7
 
@@ -43,7 +44,9 @@ export default defineConfig((_env, argv) => {
43
44
  options: {
44
45
  jsc: {
45
46
  parser: { syntax: 'typescript', tsx: true },
46
- transform: { react: { runtime: 'automatic', development: isDev } },
47
+ transform: {
48
+ react: { runtime: 'automatic', development: isDev, refresh: isDev },
49
+ },
47
50
  },
48
51
  env: { targets: 'Chrome >= 87, Firefox >= 78, Edge >= 88, Safari >= 14' },
49
52
  },
@@ -52,6 +55,7 @@ export default defineConfig((_env, argv) => {
52
55
  ],
53
56
  },
54
57
  plugins: [
58
+ isDev && new ReactRefreshRspackPlugin(),
55
59
  // excludeChunks is REQUIRED on a provider: without it the federation
56
60
  // remoteEntry chunk gets injected into the standalone HTML and breaks
57
61
  // direct serves.
@@ -64,6 +68,6 @@ export default defineConfig((_env, argv) => {
64
68
  },
65
69
  shared: ['react', 'react-dom'],
66
70
  }),
67
- ],
71
+ ].filter(Boolean),
68
72
  };
69
73
  });
@@ -188,6 +188,11 @@ async function remoteGenerator(host, schema) {
188
188
  : {}),
189
189
  }, undefined, true);
190
190
  tasks.push(installTask);
191
+ // The TS config templates use extensionless relative imports and
192
+ // `__dirname`, which Node's native type stripping cannot load.
193
+ if (options.typescriptConfiguration) {
194
+ tasks.push((0, internal_3.addSwcRegisterDependencies)(host));
195
+ }
191
196
  if (!options.skipFormat) {
192
197
  await (0, devkit_1.formatFiles)(host);
193
198
  }
@@ -1,11 +1,19 @@
1
1
  import { Tree } from '@nx/devkit';
2
2
  import { type FoundTarget } from '@nx/cypress/internal';
3
- export declare function configureCypressCT(tree: Tree, options: {
3
+ export declare function resolveCypressCTTarget(tree: Tree, options: {
4
4
  project: string;
5
5
  buildTarget: string;
6
6
  bundler: 'vite' | 'webpack';
7
7
  validExecutorNames: Set<string>;
8
- }): Promise<FoundTarget>;
8
+ }): Promise<{
9
+ found: FoundTarget;
10
+ bundler: 'vite' | 'webpack';
11
+ }>;
12
+ export declare function configureCypressCT(tree: Tree, options: {
13
+ project: string;
14
+ found: FoundTarget;
15
+ bundler: 'vite' | 'webpack';
16
+ }): Promise<void>;
9
17
  export declare function getBundlerFromTarget(found: FoundTarget, tree: Tree): Promise<'vite' | 'webpack'>;
10
18
  export declare function getActualBundler(tree: Tree, options: {
11
19
  buildTarget?: string;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveCypressCTTarget = resolveCypressCTTarget;
3
4
  exports.configureCypressCT = configureCypressCT;
4
5
  exports.getBundlerFromTarget = getBundlerFromTarget;
5
6
  exports.getActualBundler = getActualBundler;
@@ -10,9 +11,9 @@ const ast_utils_1 = require("./ast-utils");
10
11
  let tsModule;
11
12
  const allowedFileExt = new RegExp(/\.[jt]sx?/);
12
13
  const isSpecFile = new RegExp(/(spec|test)\./);
13
- async function configureCypressCT(tree, options) {
14
+ // Resolved before the shared cypress generator runs, so the bundler reaches it.
15
+ async function resolveCypressCTTarget(tree, options) {
14
16
  let found = { target: options.buildTarget, config: undefined };
15
- const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
16
17
  // Specifically undefined as a workaround for Remix to pass an empty string as the buildTarget
17
18
  if (options.buildTarget === undefined) {
18
19
  const { findBuildConfig, } = require('@nx/cypress/internal');
@@ -32,9 +33,17 @@ async function configureCypressCT(tree, options) {
32
33
  throw new Error(`Cypress Component Testing is not currently supported for this project. Either 'executer' is not defined in '${target} target' of '${project} project.json' or executer present is not valid one. Valid ones are ${JSON.stringify([...options.validExecutorNames])}. Please check https://github.com/nrwl/nx/issues/21546 for more information.`);
33
34
  }
34
35
  }
36
+ return {
37
+ found,
38
+ bundler: options.bundler ?? (await getActualBundler(tree, options, found)),
39
+ };
40
+ }
41
+ async function configureCypressCT(tree, options) {
42
+ const { found } = options;
43
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
35
44
  const { addDefaultCTConfig, getProjectCypressConfigPath, getInstalledCypressMajorVersion, } = require('@nx/cypress/internal');
36
45
  const ctConfigOptions = {
37
- bundler: options.bundler ?? (await getActualBundler(tree, options, found)),
46
+ bundler: options.bundler,
38
47
  };
39
48
  if (projectConfig.targets?.['component-test']?.executor ===
40
49
  '@nx/cypress:cypress') {
@@ -51,7 +60,6 @@ async function configureCypressCT(tree, options) {
51
60
  const cypressConfigFilePath = getProjectCypressConfigPath(tree, projectConfig.root);
52
61
  const updatedCyConfig = await addDefaultCTConfig(tree.read(cypressConfigFilePath, 'utf-8'), ctConfigOptions, '@nx/react/plugins/component-testing', getInstalledCypressMajorVersion(tree));
53
62
  tree.write(cypressConfigFilePath, updatedCyConfig);
54
- return found;
55
63
  }
56
64
  function assertValidConfig(config) {
57
65
  if (!config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/react",
3
- "version": "23.3.0-canary.20260915-071d621",
3
+ "version": "23.3.0-canary.20260917-ea5c01d",
4
4
  "private": false,
5
5
  "description": "The React plugin for Nx contains executors and generators for managing React applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Vitest, Playwright, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
6
6
  "repository": {
@@ -96,7 +96,7 @@
96
96
  "react-dom": ">=18.0.0 <20.0.0",
97
97
  "express": "^4.21.2",
98
98
  "http-proxy-middleware": "^3.0.7",
99
- "@nx/module-federation": "23.3.0-canary.20260915-071d621"
99
+ "@nx/module-federation": "23.3.0-canary.20260917-ea5c01d"
100
100
  },
101
101
  "peerDependenciesMeta": {
102
102
  "babel-plugin-react-compiler": {
@@ -118,27 +118,27 @@
118
118
  "minimatch": "10.2.5",
119
119
  "tslib": "^2.3.0",
120
120
  "semver": "^7.6.3",
121
- "@nx/devkit": "23.3.0-canary.20260915-071d621",
122
- "@nx/js": "23.3.0-canary.20260915-071d621",
123
- "@nx/eslint": "23.3.0-canary.20260915-071d621",
124
- "@nx/web": "23.3.0-canary.20260915-071d621"
121
+ "@nx/devkit": "23.3.0-canary.20260917-ea5c01d",
122
+ "@nx/js": "23.3.0-canary.20260917-ea5c01d",
123
+ "@nx/eslint": "23.3.0-canary.20260917-ea5c01d",
124
+ "@nx/web": "23.3.0-canary.20260917-ea5c01d"
125
125
  },
126
126
  "devDependencies": {
127
127
  "express": "^4.21.2",
128
128
  "http-proxy-middleware": "^3.0.7",
129
- "@nx/cypress": "23.3.0-canary.20260915-071d621",
130
- "@nx/module-federation": "23.3.0-canary.20260915-071d621",
131
- "@nx/playwright": "23.3.0-canary.20260915-071d621",
132
- "@nx/rollup": "23.3.0-canary.20260915-071d621",
133
- "@nx/rsbuild": "23.3.0-canary.20260915-071d621",
134
- "@nx/vite": "23.3.0-canary.20260915-071d621",
135
- "@nx/vitest": "23.3.0-canary.20260915-071d621",
136
- "@nx/webpack": "23.3.0-canary.20260915-071d621",
137
- "@nx/storybook": "23.3.0-canary.20260915-071d621",
138
- "nx": "23.3.0-canary.20260915-071d621"
129
+ "@nx/cypress": "23.3.0-canary.20260917-ea5c01d",
130
+ "@nx/module-federation": "23.3.0-canary.20260917-ea5c01d",
131
+ "@nx/playwright": "23.3.0-canary.20260917-ea5c01d",
132
+ "@nx/rollup": "23.3.0-canary.20260917-ea5c01d",
133
+ "@nx/rsbuild": "23.3.0-canary.20260917-ea5c01d",
134
+ "@nx/vite": "23.3.0-canary.20260917-ea5c01d",
135
+ "@nx/vitest": "23.3.0-canary.20260917-ea5c01d",
136
+ "@nx/webpack": "23.3.0-canary.20260917-ea5c01d",
137
+ "@nx/storybook": "23.3.0-canary.20260917-ea5c01d",
138
+ "nx": "23.3.0-canary.20260917-ea5c01d"
139
139
  },
140
140
  "optionalDependencies": {
141
- "@nx/vite": "23.3.0-canary.20260915-071d621"
141
+ "@nx/vite": "23.3.0-canary.20260917-ea5c01d"
142
142
  },
143
143
  "publishConfig": {
144
144
  "access": "public"