@nx/react 21.3.0-canary.20250715-cf994df → 21.3.0-canary.20250716-46d21c7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/react",
3
- "version": "21.3.0-canary.20250715-cf994df",
3
+ "version": "21.3.0-canary.20250716-46d21c7",
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": {
@@ -38,11 +38,11 @@
38
38
  "minimatch": "9.0.3",
39
39
  "picocolors": "^1.1.0",
40
40
  "tslib": "^2.3.0",
41
- "@nx/devkit": "21.3.0-canary.20250715-cf994df",
42
- "@nx/js": "21.3.0-canary.20250715-cf994df",
43
- "@nx/eslint": "21.3.0-canary.20250715-cf994df",
44
- "@nx/web": "21.3.0-canary.20250715-cf994df",
45
- "@nx/module-federation": "21.3.0-canary.20250715-cf994df",
41
+ "@nx/devkit": "21.3.0-canary.20250716-46d21c7",
42
+ "@nx/js": "21.3.0-canary.20250716-46d21c7",
43
+ "@nx/eslint": "21.3.0-canary.20250716-46d21c7",
44
+ "@nx/web": "21.3.0-canary.20250716-46d21c7",
45
+ "@nx/module-federation": "21.3.0-canary.20250716-46d21c7",
46
46
  "express": "^4.21.2",
47
47
  "http-proxy-middleware": "^3.0.3",
48
48
  "semver": "^7.6.3"
@@ -4,9 +4,10 @@ export interface CreateComponentStoriesFileSchema {
4
4
  project: string;
5
5
  componentPath: string;
6
6
  interactionTests?: boolean;
7
+ uiFramework?: string;
7
8
  skipFormat?: boolean;
8
9
  }
9
- export declare function createComponentStoriesFile(host: Tree, { project, componentPath, interactionTests }: CreateComponentStoriesFileSchema): void;
10
- export declare function findPropsAndGenerateFile(host: Tree, sourceFile: ts.SourceFile, cmpDeclaration: ts.Node, componentDirectory: string, name: string, interactionTests: boolean, isPlainJs: boolean, fromNodeArray?: boolean): void;
10
+ export declare function createComponentStoriesFile(host: Tree, { project, componentPath, interactionTests, uiFramework, }: CreateComponentStoriesFileSchema): void;
11
+ export declare function findPropsAndGenerateFile(host: Tree, sourceFile: ts.SourceFile, cmpDeclaration: ts.Node, componentDirectory: string, name: string, interactionTests: boolean, uiFramework: string, isPlainJs: boolean, fromNodeArray?: boolean): void;
11
12
  export declare function componentStoryGenerator(host: Tree, schema: CreateComponentStoriesFileSchema): Promise<void>;
12
13
  export default componentStoryGenerator;
@@ -8,8 +8,9 @@ const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescri
8
8
  const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
9
9
  const ast_utils_1 = require("../../utils/ast-utils");
10
10
  const component_props_1 = require("../../utils/component-props");
11
+ const framework_1 = require("../../utils/framework");
11
12
  let tsModule;
12
- function createComponentStoriesFile(host, { project, componentPath, interactionTests }) {
13
+ function createComponentStoriesFile(host, { project, componentPath, interactionTests, uiFramework, }) {
13
14
  if (!tsModule) {
14
15
  tsModule = (0, ensure_typescript_1.ensureTypescript)();
15
16
  }
@@ -33,7 +34,7 @@ function createComponentStoriesFile(host, { project, componentPath, interactionT
33
34
  const componentNodes = (0, ast_utils_1.findExportDeclarationsForJsx)(sourceFile);
34
35
  if (componentNodes?.length) {
35
36
  componentNodes.forEach((declaration) => {
36
- findPropsAndGenerateFile(host, sourceFile, declaration, componentDirectory, name, interactionTests, isPlainJs, componentNodes.length > 1);
37
+ findPropsAndGenerateFile(host, sourceFile, declaration, componentDirectory, name, interactionTests, uiFramework, isPlainJs, componentNodes.length > 1);
37
38
  });
38
39
  }
39
40
  else {
@@ -41,10 +42,10 @@ function createComponentStoriesFile(host, { project, componentPath, interactionT
41
42
  }
42
43
  }
43
44
  else {
44
- findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name, interactionTests, isPlainJs);
45
+ findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name, interactionTests, uiFramework, isPlainJs);
45
46
  }
46
47
  }
47
- function findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name, interactionTests, isPlainJs, fromNodeArray) {
48
+ function findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name, interactionTests, uiFramework, isPlainJs, fromNodeArray) {
48
49
  const { props, argTypes } = (0, component_props_1.getComponentPropDefaults)(sourceFile, cmpDeclaration);
49
50
  (0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname, `./files${isPlainJs ? '/jsx' : '/tsx'}`), (0, devkit_1.normalizePath)(componentDirectory), {
50
51
  tmpl: '',
@@ -56,12 +57,14 @@ function findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDir
56
57
  argTypes,
57
58
  componentName: cmpDeclaration.name.text,
58
59
  interactionTests,
60
+ uiFramework,
59
61
  });
60
62
  }
61
63
  async function componentStoryGenerator(host, schema) {
62
64
  createComponentStoriesFile(host, {
63
65
  ...schema,
64
66
  interactionTests: schema.interactionTests ?? true,
67
+ uiFramework: schema.uiFramework ?? (0, framework_1.getUiFramework)(host, schema.project),
65
68
  });
66
69
  if (!schema.skipFormat) {
67
70
  await (0, devkit_1.formatFiles)(host);
@@ -1,33 +1,35 @@
1
- import type { Meta, StoryObj } from 'storybook/internal/types';
1
+ import type { Meta, StoryObj } from '<%= uiFramework %>';
2
2
  import { <%= componentName %> } from './<%= componentImportFileName %>';
3
3
  <%_ if ( interactionTests ) { _%>
4
4
  import { expect } from 'storybook/test';
5
5
  <%_ } _%>
6
6
 
7
- const meta: Meta<typeof <%= componentName %>> = {
7
+ const meta = {
8
8
  component: <%= componentName %>,
9
- title: '<%= componentName %>',<% if ( argTypes && argTypes.length > 0 ) { %>
9
+ title: '<%= componentName %>',
10
+ <%_ if ( argTypes && argTypes.length > 0 ) { _%>
10
11
  argTypes: {<% for (let argType of argTypes) { %>
11
- <%= argType.name %>: { <%- argType.type %> : "<%- argType.actionText %>" },<% } %>
12
- }
13
- <% } %>
14
- };
12
+ <%= argType.name %>: { <%- argType.type %>: "<%- argType.actionText %>" },<% } %>
13
+ }
14
+ <%_ } _%>
15
+ } satisfies Meta<typeof <%= componentName %>>;
15
16
  export default meta;
17
+
16
18
  type Story = StoryObj<typeof <%= componentName %>>;
17
19
 
18
20
  export const Primary = {
19
21
  args: {<% for (let prop of props) { %>
20
- <%= prop.name %>: <%- prop.defaultValue %>,<% } %>
22
+ <%= prop.name %>: <%- prop.defaultValue %>,<% } %>
21
23
  },
22
- };
23
-
24
+ } satisfies Story;
24
25
  <%_ if ( interactionTests ) { _%>
25
- export const Heading: Story = {
26
+
27
+ export const Heading = {
26
28
  args: {<% for (let prop of props) { %>
27
- <%= prop.name %>: <%- prop.defaultValue %>,<% } %>
29
+ <%= prop.name %>: <%- prop.defaultValue %>,<% } %>
28
30
  },
29
31
  play: async ({ canvas }) => {
30
- await expect(canvas.getByText(/Welcome to <%=componentName%>!/gi)).toBeTruthy();
32
+ await expect(canvas.getByText(/<%=componentName%>/gi)).toBeTruthy();
31
33
  },
32
- };
34
+ } satisfies Story;
33
35
  <% } %>
@@ -4,10 +4,11 @@ export interface StorybookStoriesSchema {
4
4
  interactionTests?: boolean;
5
5
  js?: boolean;
6
6
  ignorePaths?: string[];
7
+ uiFramework?: string;
7
8
  skipFormat?: boolean;
8
9
  }
9
10
  export declare function projectRootPath(tree: Tree, config: ProjectConfiguration): Promise<string>;
10
11
  export declare function containsComponentDeclaration(tree: Tree, componentPath: string): boolean;
11
- export declare function createAllStories(tree: Tree, projectName: string, interactionTests: boolean, js: boolean, projects: Map<string, ProjectConfiguration>, projectConfiguration: ProjectConfiguration, ignorePaths?: string[]): Promise<void>;
12
+ export declare function createAllStories(tree: Tree, schema: StorybookStoriesSchema, projectConfiguration: ProjectConfiguration): Promise<void>;
12
13
  export declare function storiesGenerator(host: Tree, schema: StorybookStoriesSchema): Promise<void>;
13
14
  export default storiesGenerator;
@@ -10,6 +10,7 @@ const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-set
10
10
  const minimatch_1 = require("minimatch");
11
11
  const path_1 = require("path");
12
12
  const ast_utils_1 = require("../../utils/ast-utils");
13
+ const framework_1 = require("../../utils/framework");
13
14
  const component_story_1 = require("../component-story/component-story");
14
15
  let tsModule;
15
16
  async function projectRootPath(tree, config) {
@@ -46,16 +47,16 @@ function containsComponentDeclaration(tree, componentPath) {
46
47
  return !!((0, ast_utils_1.getComponentNode)(sourceFile) ||
47
48
  (0, ast_utils_1.findExportDeclarationsForJsx)(sourceFile)?.length);
48
49
  }
49
- async function createAllStories(tree, projectName, interactionTests, js, projects, projectConfiguration, ignorePaths) {
50
+ async function createAllStories(tree, schema, projectConfiguration) {
50
51
  const { isTheFileAStory } = await Promise.resolve().then(() => require('@nx/storybook/src/utils/utilities'));
51
- const { sourceRoot, root } = projectConfiguration;
52
+ const sourceRoot = (0, ts_solution_setup_1.getProjectSourceRoot)(projectConfiguration, tree);
52
53
  let componentPaths = [];
53
54
  const projectPath = await projectRootPath(tree, projectConfiguration);
54
55
  (0, devkit_1.visitNotIgnoredFiles)(tree, projectPath, (path) => {
55
56
  // Ignore private files starting with "_".
56
57
  if ((0, path_1.basename)(path).startsWith('_'))
57
58
  return;
58
- if (ignorePaths?.some((pattern) => (0, minimatch_1.minimatch)(path, pattern)))
59
+ if (schema.ignorePaths?.some((pattern) => (0, minimatch_1.minimatch)(path, pattern)))
59
60
  return;
60
61
  if ((path.endsWith('.tsx') && !path.endsWith('.spec.tsx')) ||
61
62
  (path.endsWith('.js') && !path.endsWith('.spec.js')) ||
@@ -73,15 +74,16 @@ async function createAllStories(tree, projectName, interactionTests, js, project
73
74
  }
74
75
  });
75
76
  await Promise.all(componentPaths.map(async (componentPath) => {
76
- const relativeCmpDir = componentPath.replace((0, path_1.join)(sourceRoot ?? root, '/'), '');
77
+ const relativeCmpDir = componentPath.replace(`${sourceRoot}/`, '');
77
78
  if (!containsComponentDeclaration(tree, componentPath)) {
78
79
  return;
79
80
  }
80
81
  await (0, component_story_1.default)(tree, {
81
82
  componentPath: relativeCmpDir,
82
- project: projectName,
83
+ project: schema.project,
84
+ interactionTests: schema.interactionTests,
85
+ uiFramework: schema.uiFramework,
83
86
  skipFormat: true,
84
- interactionTests,
85
87
  });
86
88
  }));
87
89
  }
@@ -89,7 +91,8 @@ async function storiesGenerator(host, schema) {
89
91
  const projects = (0, devkit_1.getProjects)(host);
90
92
  const projectConfiguration = projects.get(schema.project);
91
93
  schema.interactionTests = schema.interactionTests ?? true;
92
- await createAllStories(host, schema.project, schema.interactionTests, schema.js, projects, projectConfiguration, schema.ignorePaths);
94
+ schema.uiFramework ??= (0, framework_1.getUiFramework)(host, schema.project);
95
+ await createAllStories(host, schema, projectConfiguration);
93
96
  if (!schema.skipFormat) {
94
97
  await (0, devkit_1.formatFiles)(host);
95
98
  }
@@ -1,6 +1,5 @@
1
- import { StorybookConfigureSchema } from './schema';
2
- import { type GeneratorCallback, Tree } from '@nx/devkit';
1
+ import { type GeneratorCallback, type Tree } from '@nx/devkit';
2
+ import type { StorybookConfigureSchema } from './schema';
3
3
  export declare function storybookConfigurationGenerator(host: Tree, schema: StorybookConfigureSchema): Promise<GeneratorCallback>;
4
4
  export declare function storybookConfigurationGeneratorInternal(host: Tree, schema: StorybookConfigureSchema): Promise<GeneratorCallback>;
5
5
  export default storybookConfigurationGenerator;
6
- export declare function findWebpackConfig(tree: Tree, projectRoot: string): string | undefined;
@@ -2,20 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.storybookConfigurationGenerator = storybookConfigurationGenerator;
4
4
  exports.storybookConfigurationGeneratorInternal = storybookConfigurationGeneratorInternal;
5
- exports.findWebpackConfig = findWebpackConfig;
6
- const stories_1 = require("../stories/stories");
7
5
  const devkit_1 = require("@nx/devkit");
6
+ const framework_1 = require("../../utils/framework");
8
7
  const versions_1 = require("../../utils/versions");
9
- async function generateStories(host, schema) {
10
- const projectConfig = (0, devkit_1.readProjectConfiguration)(host, schema.project);
11
- await (0, stories_1.default)(host, {
12
- project: schema.project,
13
- js: schema.js,
14
- ignorePaths: schema.ignorePaths,
15
- skipFormat: true,
16
- interactionTests: schema.interactionTests ?? true,
17
- });
18
- }
8
+ const stories_1 = require("../stories/stories");
19
9
  function storybookConfigurationGenerator(host, schema) {
20
10
  return storybookConfigurationGeneratorInternal(host, {
21
11
  addPlugin: false,
@@ -29,13 +19,7 @@ async function storybookConfigurationGeneratorInternal(host, schema) {
29
19
  nxJson.useInferencePlugins !== false;
30
20
  schema.addPlugin ??= addPluginDefault;
31
21
  const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/storybook', versions_1.nxVersion);
32
- let uiFramework = '@storybook/react-vite';
33
- const projectConfig = (0, devkit_1.readProjectConfiguration)(host, schema.project);
34
- if (findWebpackConfig(host, projectConfig.root) ||
35
- projectConfig.targets?.['build']?.executor === '@nx/rollup:rollup' ||
36
- projectConfig.targets?.['build']?.executor === '@nx/expo:build') {
37
- uiFramework = '@storybook/react-webpack5';
38
- }
22
+ const uiFramework = (0, framework_1.getUiFramework)(host, schema.project);
39
23
  if (uiFramework === '@storybook/react-vite') {
40
24
  tasks.push((0, devkit_1.addDependenciesToPackageJson)(host, {}, { '@vitejs/plugin-react': versions_1.reactViteVersion }));
41
25
  }
@@ -52,18 +36,16 @@ async function storybookConfigurationGeneratorInternal(host, schema) {
52
36
  });
53
37
  tasks.push(installTask);
54
38
  if (schema.generateStories) {
55
- await generateStories(host, schema);
39
+ await (0, stories_1.storiesGenerator)(host, {
40
+ project: schema.project,
41
+ js: schema.js,
42
+ ignorePaths: schema.ignorePaths,
43
+ skipFormat: true,
44
+ interactionTests: schema.interactionTests ?? true,
45
+ uiFramework,
46
+ });
56
47
  }
57
48
  await (0, devkit_1.formatFiles)(host);
58
49
  return (0, devkit_1.runTasksInSerial)(...tasks);
59
50
  }
60
51
  exports.default = storybookConfigurationGenerator;
61
- function findWebpackConfig(tree, projectRoot) {
62
- const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
63
- for (const ext of allowsExt) {
64
- const webpackConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, `webpack.config.${ext}`);
65
- if (tree.exists(webpackConfigPath)) {
66
- return webpackConfigPath;
67
- }
68
- }
69
- }
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export declare function getUiFramework(tree: Tree, project: string): '@storybook/react-vite' | '@storybook/react-webpack5';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUiFramework = getUiFramework;
4
+ const devkit_1 = require("@nx/devkit");
5
+ function getUiFramework(tree, project) {
6
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, project);
7
+ if (findWebpackConfig(tree, projectConfig.root) ||
8
+ projectConfig.targets?.['build']?.executor === '@nx/rollup:rollup' ||
9
+ projectConfig.targets?.['build']?.executor === '@nx/expo:build') {
10
+ return '@storybook/react-webpack5';
11
+ }
12
+ return '@storybook/react-vite';
13
+ }
14
+ function findWebpackConfig(tree, projectRoot) {
15
+ const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
16
+ for (const ext of allowsExt) {
17
+ const webpackConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, `webpack.config.${ext}`);
18
+ if (tree.exists(webpackConfigPath)) {
19
+ return webpackConfigPath;
20
+ }
21
+ }
22
+ }
@@ -44,8 +44,8 @@ export declare const typesExpressVersion = "^4.17.21";
44
44
  export declare const isbotVersion = "^3.6.5";
45
45
  export declare const corsVersion = "~2.8.5";
46
46
  export declare const typesCorsVersion = "~2.8.12";
47
- export declare const moduleFederationNodeVersion = "^2.6.26";
48
- export declare const moduleFederationEnhancedVersion = "^0.15.0";
47
+ export declare const moduleFederationNodeVersion = "^2.7.9";
48
+ export declare const moduleFederationEnhancedVersion = "^0.17.0";
49
49
  export declare const lessVersion = "3.12.2";
50
50
  export declare const sassVersion = "^1.55.0";
51
51
  export declare const rollupPluginUrlVersion = "^8.0.2";
@@ -51,8 +51,8 @@ exports.typesExpressVersion = '^4.17.21';
51
51
  exports.isbotVersion = '^3.6.5';
52
52
  exports.corsVersion = '~2.8.5';
53
53
  exports.typesCorsVersion = '~2.8.12';
54
- exports.moduleFederationNodeVersion = '^2.6.26';
55
- exports.moduleFederationEnhancedVersion = '^0.15.0';
54
+ exports.moduleFederationNodeVersion = '^2.7.9';
55
+ exports.moduleFederationEnhancedVersion = '^0.17.0';
56
56
  // style preprocessors
57
57
  exports.lessVersion = '3.12.2';
58
58
  exports.sassVersion = '^1.55.0';