@nx/react 16.6.0-beta.1 → 16.6.0-beta.3
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 +7 -7
- package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.js +27 -10
- package/src/generators/component-story/component-story.d.ts +3 -2
- package/src/generators/component-story/component-story.js +9 -15
- package/src/generators/component-story/files/jsx/__componentFileName__.stories.jsx__tmpl__ +29 -0
- package/src/generators/component-story/files/tsx/__componentFileName__.stories.tsx__tmpl__ +33 -0
- package/src/generators/component-story/schema.json +6 -0
- package/src/generators/stories/schema.json +10 -3
- package/src/generators/stories/stories.d.ts +3 -2
- package/src/generators/stories/stories.js +4 -2
- package/src/generators/storybook-configuration/configuration.js +13 -11
- package/src/generators/storybook-configuration/schema.d.ts +2 -2
- package/src/generators/storybook-configuration/schema.json +13 -12
- package/src/generators/component-story/files/__componentFileName__.stories.__fileExt__ +0 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/react",
|
|
3
|
-
"version": "16.6.0-beta.
|
|
3
|
+
"version": "16.6.0-beta.3",
|
|
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, 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": {
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
"migrations": "./migrations.json"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@nrwl/react": "16.6.0-beta.
|
|
35
|
-
"@nx/devkit": "16.6.0-beta.
|
|
36
|
-
"@nx/js": "16.6.0-beta.
|
|
37
|
-
"@nx/linter": "16.6.0-beta.
|
|
38
|
-
"@nx/web": "16.6.0-beta.
|
|
34
|
+
"@nrwl/react": "16.6.0-beta.3",
|
|
35
|
+
"@nx/devkit": "16.6.0-beta.3",
|
|
36
|
+
"@nx/js": "16.6.0-beta.3",
|
|
37
|
+
"@nx/linter": "16.6.0-beta.3",
|
|
38
|
+
"@nx/web": "16.6.0-beta.3",
|
|
39
39
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
40
40
|
"@svgr/webpack": "^8.0.1",
|
|
41
41
|
"chalk": "^4.1.0",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"types": "./index.d.ts",
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "cd8c61d7a3b8ab9bc7bab068f5ca49bbf14abbf5"
|
|
50
50
|
}
|
|
@@ -9,19 +9,37 @@ const chalk = require("chalk");
|
|
|
9
9
|
const wait_for_port_open_1 = require("@nx/web/src/utils/wait-for-port-open");
|
|
10
10
|
const find_matching_projects_1 = require("nx/src/utils/find-matching-projects");
|
|
11
11
|
const child_process_1 = require("child_process");
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const tsnode_register_1 = require("@nx/js/src/utils/typescript/tsnode-register");
|
|
14
|
+
function getBuildOptions(buildTarget, context) {
|
|
15
|
+
const target = (0, devkit_1.parseTargetString)(buildTarget, context.projectGraph);
|
|
16
|
+
const buildOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
17
|
+
return Object.assign({}, buildOptions);
|
|
18
|
+
}
|
|
19
|
+
function getModuleFederationConfig(tsconfigPath, workspaceRoot, projectRoot) {
|
|
20
|
+
const moduleFederationConfigPathJS = (0, path_1.join)(workspaceRoot, projectRoot, 'module-federation.config.js');
|
|
21
|
+
const moduleFederationConfigPathTS = (0, path_1.join)(workspaceRoot, projectRoot, 'module-federation.config.ts');
|
|
22
|
+
let moduleFederationConfigPath = moduleFederationConfigPathJS;
|
|
23
|
+
if ((0, fs_1.existsSync)(moduleFederationConfigPathTS)) {
|
|
24
|
+
(0, tsnode_register_1.tsNodeRegister)(moduleFederationConfigPathTS, tsconfigPath);
|
|
25
|
+
moduleFederationConfigPath = moduleFederationConfigPathTS;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const config = require(moduleFederationConfigPath);
|
|
29
|
+
return config.default || config;
|
|
30
|
+
}
|
|
31
|
+
catch (_a) {
|
|
32
|
+
throw new Error(`Could not load ${moduleFederationConfigPath}. Was this project generated with "@nx/react:host"?\nSee: https://nx.dev/recipes/module-federation/faster-builds`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
12
35
|
function moduleFederationDevServer(options, context) {
|
|
13
36
|
var _a, _b;
|
|
14
37
|
return tslib_1.__asyncGenerator(this, arguments, function* moduleFederationDevServer_1() {
|
|
38
|
+
const nxBin = require.resolve('nx');
|
|
15
39
|
const currIter = (0, dev_server_impl_1.default)(options, context);
|
|
16
40
|
const p = context.projectsConfigurations.projects[context.projectName];
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
moduleFederationConfig = require(moduleFederationConfigPath);
|
|
21
|
-
}
|
|
22
|
-
catch (_c) {
|
|
23
|
-
throw new Error(`Could not load ${moduleFederationConfigPath}. Was this project generated with "@nx/react:host"?\nSee: https://nx.dev/recipes/module-federation/faster-builds`);
|
|
24
|
-
}
|
|
41
|
+
const buildOptions = getBuildOptions(options.buildTarget, context);
|
|
42
|
+
const moduleFederationConfig = getModuleFederationConfig(buildOptions.tsConfig, context.root, p.root);
|
|
25
43
|
const remotesToSkip = new Set((_a = (0, find_matching_projects_1.findMatchingProjects)(options.skipRemotes, context.projectGraph.nodes)) !== null && _a !== void 0 ? _a : []);
|
|
26
44
|
if (remotesToSkip.size > 0) {
|
|
27
45
|
devkit_1.logger.info(`Remotes not served automatically: ${[...remotesToSkip.values()].join(', ')}`);
|
|
@@ -50,7 +68,6 @@ function moduleFederationDevServer(options, context) {
|
|
|
50
68
|
? (0, find_matching_projects_1.findMatchingProjects)(options.devRemotes, context.projectGraph.nodes)
|
|
51
69
|
: (0, find_matching_projects_1.findMatchingProjects)([options.devRemotes], context.projectGraph.nodes);
|
|
52
70
|
devkit_1.logger.info(`NX Starting module federation dev-server for ${chalk.bold(context.projectName)} with ${knownRemotes.length} remotes`);
|
|
53
|
-
const nxBin = require.resolve('nx');
|
|
54
71
|
const devRemoteIters = [];
|
|
55
72
|
let isCollectingStaticRemoteOutput = true;
|
|
56
73
|
for (const app of knownRemotes) {
|
|
@@ -110,7 +127,7 @@ function moduleFederationDevServer(options, context) {
|
|
|
110
127
|
devkit_1.logger.info(`NX All remotes started, server ready at http://localhost:${options.port}`);
|
|
111
128
|
next({ success: true, baseUrl: `http://localhost:${options.port}` });
|
|
112
129
|
}
|
|
113
|
-
catch (
|
|
130
|
+
catch (_c) {
|
|
114
131
|
throw new Error(`Timed out waiting for remote to start. Check above for any errors.`);
|
|
115
132
|
}
|
|
116
133
|
finally {
|
|
@@ -3,10 +3,11 @@ import type * as ts from 'typescript';
|
|
|
3
3
|
export interface CreateComponentStoriesFileSchema {
|
|
4
4
|
project: string;
|
|
5
5
|
componentPath: string;
|
|
6
|
+
interactionTests?: boolean;
|
|
6
7
|
skipFormat?: boolean;
|
|
7
8
|
}
|
|
8
|
-
export declare function createComponentStoriesFile(host: Tree, { project, componentPath }: CreateComponentStoriesFileSchema): void;
|
|
9
|
-
export declare function findPropsAndGenerateFile(host: Tree, sourceFile: ts.SourceFile, cmpDeclaration: ts.Node, componentDirectory: string, name: string,
|
|
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
11
|
export declare function componentStoryGenerator(host: Tree, schema: CreateComponentStoriesFileSchema): Promise<void>;
|
|
11
12
|
export default componentStoryGenerator;
|
|
12
13
|
export declare const componentStorySchematic: (generatorOptions: CreateComponentStoriesFileSchema) => (tree: any, context: any) => Promise<any>;
|
|
@@ -7,7 +7,7 @@ const ast_utils_1 = require("../../utils/ast-utils");
|
|
|
7
7
|
const component_props_1 = require("../../utils/component-props");
|
|
8
8
|
const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
|
|
9
9
|
let tsModule;
|
|
10
|
-
function createComponentStoriesFile(host, { project, componentPath }) {
|
|
10
|
+
function createComponentStoriesFile(host, { project, componentPath, interactionTests }) {
|
|
11
11
|
if (!tsModule) {
|
|
12
12
|
tsModule = (0, ensure_typescript_1.ensureTypescript)();
|
|
13
13
|
}
|
|
@@ -16,13 +16,6 @@ function createComponentStoriesFile(host, { project, componentPath }) {
|
|
|
16
16
|
const componentFilePath = (0, devkit_1.joinPathFragments)(sourceRoot, componentPath);
|
|
17
17
|
const componentDirectory = componentFilePath.replace(componentFilePath.slice(componentFilePath.lastIndexOf('/')), '');
|
|
18
18
|
const isPlainJs = componentFilePath.endsWith('.jsx') || componentFilePath.endsWith('.js');
|
|
19
|
-
let fileExt = 'tsx';
|
|
20
|
-
if (componentFilePath.endsWith('.jsx')) {
|
|
21
|
-
fileExt = 'jsx';
|
|
22
|
-
}
|
|
23
|
-
else if (componentFilePath.endsWith('.js')) {
|
|
24
|
-
fileExt = 'js';
|
|
25
|
-
}
|
|
26
19
|
const componentFileName = componentFilePath
|
|
27
20
|
.slice(componentFilePath.lastIndexOf('/') + 1)
|
|
28
21
|
.replace('.tsx', '')
|
|
@@ -39,7 +32,7 @@ function createComponentStoriesFile(host, { project, componentPath }) {
|
|
|
39
32
|
const componentNodes = (0, ast_utils_1.findExportDeclarationsForJsx)(sourceFile);
|
|
40
33
|
if (componentNodes === null || componentNodes === void 0 ? void 0 : componentNodes.length) {
|
|
41
34
|
componentNodes.forEach((declaration) => {
|
|
42
|
-
findPropsAndGenerateFile(host, sourceFile, declaration, componentDirectory, name,
|
|
35
|
+
findPropsAndGenerateFile(host, sourceFile, declaration, componentDirectory, name, interactionTests, isPlainJs, componentNodes.length > 1);
|
|
43
36
|
});
|
|
44
37
|
}
|
|
45
38
|
else {
|
|
@@ -47,13 +40,14 @@ function createComponentStoriesFile(host, { project, componentPath }) {
|
|
|
47
40
|
}
|
|
48
41
|
}
|
|
49
42
|
else {
|
|
50
|
-
findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name,
|
|
43
|
+
findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name, interactionTests, isPlainJs);
|
|
51
44
|
}
|
|
52
45
|
}
|
|
53
46
|
exports.createComponentStoriesFile = createComponentStoriesFile;
|
|
54
|
-
function findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name,
|
|
47
|
+
function findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDirectory, name, interactionTests, isPlainJs, fromNodeArray) {
|
|
55
48
|
const { propsTypeName, props, argTypes } = (0, component_props_1.getDefaultsForComponent)(sourceFile, cmpDeclaration);
|
|
56
|
-
(0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname,
|
|
49
|
+
(0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname, `./files${isPlainJs ? '/jsx' : '/tsx'}`), (0, devkit_1.normalizePath)(componentDirectory), {
|
|
50
|
+
tmpl: '',
|
|
57
51
|
componentFileName: fromNodeArray
|
|
58
52
|
? `${name}--${cmpDeclaration.name.text}`
|
|
59
53
|
: name,
|
|
@@ -62,14 +56,14 @@ function findPropsAndGenerateFile(host, sourceFile, cmpDeclaration, componentDir
|
|
|
62
56
|
props,
|
|
63
57
|
argTypes,
|
|
64
58
|
componentName: cmpDeclaration.name.text,
|
|
65
|
-
|
|
66
|
-
fileExt,
|
|
59
|
+
interactionTests,
|
|
67
60
|
});
|
|
68
61
|
}
|
|
69
62
|
exports.findPropsAndGenerateFile = findPropsAndGenerateFile;
|
|
70
63
|
function componentStoryGenerator(host, schema) {
|
|
64
|
+
var _a;
|
|
71
65
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
72
|
-
createComponentStoriesFile(host, schema);
|
|
66
|
+
createComponentStoriesFile(host, Object.assign(Object.assign({}, schema), { interactionTests: (_a = schema.interactionTests) !== null && _a !== void 0 ? _a : true }));
|
|
73
67
|
if (!schema.skipFormat) {
|
|
74
68
|
yield (0, devkit_1.formatFiles)(host);
|
|
75
69
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import componentName from './<%= componentImportFileName %>';
|
|
2
|
+
<% if ( interactionTests ) { %>
|
|
3
|
+
import { within } from '@storybook/testing-library';
|
|
4
|
+
import { expect } from '@storybook/jest';
|
|
5
|
+
<% } %>
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
component: <%= componentName %>,
|
|
9
|
+
title: '<%= componentName %>',<% if ( argTypes && argTypes.length > 0 ) { %>
|
|
10
|
+
argTypes: {<% for (let argType of argTypes) { %>
|
|
11
|
+
<%= argType.name %>: { <%- argType.type %> : "<%- argType.actionText %>" },<% } %>
|
|
12
|
+
}
|
|
13
|
+
<% } %>
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const Primary = {
|
|
17
|
+
args: {<% for (let prop of props) { %>
|
|
18
|
+
<%= prop.name %>: <%- prop.defaultValue %>,<% } %>
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
<% if ( interactionTests ) { %>
|
|
23
|
+
export const Heading: Story = {
|
|
24
|
+
play: async ({ canvasElement }) => {
|
|
25
|
+
const canvas = within(canvasElement);
|
|
26
|
+
expect(canvas.getByText(/Welcome to <%=componentName%>!/gi)).toBeTruthy();
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
<% } %>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { <%= componentName %> } from './<%= componentImportFileName %>';
|
|
3
|
+
<% if ( interactionTests ) { %>
|
|
4
|
+
import { within } from '@storybook/testing-library';
|
|
5
|
+
import { expect } from '@storybook/jest';
|
|
6
|
+
<% } %>
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof <%= componentName %>> = {
|
|
9
|
+
component: <%= componentName %>,
|
|
10
|
+
title: '<%= componentName %>',<% if ( argTypes && argTypes.length > 0 ) { %>
|
|
11
|
+
argTypes: {<% for (let argType of argTypes) { %>
|
|
12
|
+
<%= argType.name %>: { <%- argType.type %> : "<%- argType.actionText %>" },<% } %>
|
|
13
|
+
}
|
|
14
|
+
<% } %>
|
|
15
|
+
};
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story = StoryObj<typeof <%= componentName %>>;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export const Primary = {
|
|
21
|
+
args: {<% for (let prop of props) { %>
|
|
22
|
+
<%= prop.name %>: <%- prop.defaultValue %>,<% } %>
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
<% if ( interactionTests ) { %>
|
|
27
|
+
export const Heading: Story = {
|
|
28
|
+
play: async ({ canvasElement }) => {
|
|
29
|
+
const canvas = within(canvasElement);
|
|
30
|
+
expect(canvas.getByText(/Welcome to <%=componentName%>!/gi)).toBeTruthy();
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
<% } %>
|
|
@@ -30,6 +30,12 @@
|
|
|
30
30
|
"type": "boolean",
|
|
31
31
|
"default": false,
|
|
32
32
|
"x-priority": "internal"
|
|
33
|
+
},
|
|
34
|
+
"interactionTests": {
|
|
35
|
+
"type": "boolean",
|
|
36
|
+
"description": "Set up Storybook interaction tests.",
|
|
37
|
+
"default": true,
|
|
38
|
+
"x-priority": "important"
|
|
33
39
|
}
|
|
34
40
|
},
|
|
35
41
|
"required": ["project", "componentPath"]
|
|
@@ -20,12 +20,19 @@
|
|
|
20
20
|
"generateCypressSpecs": {
|
|
21
21
|
"type": "boolean",
|
|
22
22
|
"description": "Automatically generate `*.spec.ts` files in the cypress e2e app generated by the cypress-configure generator.",
|
|
23
|
-
"x-
|
|
24
|
-
"x-priority": "important"
|
|
23
|
+
"x-deprecated": "Please use Storybook interaction tests instead."
|
|
25
24
|
},
|
|
26
25
|
"cypressProject": {
|
|
27
26
|
"type": "string",
|
|
28
|
-
"description": "The Cypress project to generate the stories under. This is inferred from `project` by default."
|
|
27
|
+
"description": "The Cypress project to generate the stories under. This is inferred from `project` by default.",
|
|
28
|
+
"x-deprecated": "Please use Storybook interaction tests instead."
|
|
29
|
+
},
|
|
30
|
+
"interactionTests": {
|
|
31
|
+
"type": "boolean",
|
|
32
|
+
"description": "Set up Storybook interaction tests.",
|
|
33
|
+
"x-prompt": "Do you want to set up Storybook interaction tests?",
|
|
34
|
+
"x-priority": "important",
|
|
35
|
+
"default": true
|
|
29
36
|
},
|
|
30
37
|
"js": {
|
|
31
38
|
"type": "boolean",
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { ProjectConfiguration, Tree } from '@nx/devkit';
|
|
2
2
|
export interface StorybookStoriesSchema {
|
|
3
3
|
project: string;
|
|
4
|
-
|
|
4
|
+
interactionTests?: boolean;
|
|
5
5
|
js?: boolean;
|
|
6
6
|
cypressProject?: string;
|
|
7
|
+
generateCypressSpecs?: boolean;
|
|
7
8
|
ignorePaths?: string[];
|
|
8
9
|
skipFormat?: boolean;
|
|
9
10
|
}
|
|
10
11
|
export declare function projectRootPath(tree: Tree, config: ProjectConfiguration): Promise<string>;
|
|
11
12
|
export declare function containsComponentDeclaration(tree: Tree, componentPath: string): boolean;
|
|
12
|
-
export declare function createAllStories(tree: Tree, projectName: string,
|
|
13
|
+
export declare function createAllStories(tree: Tree, projectName: string, interactionTests: boolean, js: boolean, generateCypressSpecs?: boolean, cypressProject?: string, ignorePaths?: string[]): Promise<void>;
|
|
13
14
|
export declare function storiesGenerator(host: Tree, schema: StorybookStoriesSchema): Promise<void>;
|
|
14
15
|
export default storiesGenerator;
|
|
15
16
|
export declare const storiesSchematic: (generatorOptions: StorybookStoriesSchema) => (tree: any, context: any) => Promise<any>;
|
|
@@ -47,7 +47,7 @@ function containsComponentDeclaration(tree, componentPath) {
|
|
|
47
47
|
((_a = (0, ast_utils_1.findExportDeclarationsForJsx)(sourceFile)) === null || _a === void 0 ? void 0 : _a.length));
|
|
48
48
|
}
|
|
49
49
|
exports.containsComponentDeclaration = containsComponentDeclaration;
|
|
50
|
-
function createAllStories(tree, projectName,
|
|
50
|
+
function createAllStories(tree, projectName, interactionTests, js, generateCypressSpecs, cypressProject, ignorePaths) {
|
|
51
51
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
52
52
|
const { isTheFileAStory } = yield Promise.resolve().then(() => require('@nx/storybook/src/utils/utilities'));
|
|
53
53
|
const projects = (0, devkit_1.getProjects)(tree);
|
|
@@ -90,6 +90,7 @@ function createAllStories(tree, projectName, generateCypressSpecs, js, cypressPr
|
|
|
90
90
|
componentPath: relativeCmpDir,
|
|
91
91
|
project: projectName,
|
|
92
92
|
skipFormat: true,
|
|
93
|
+
interactionTests,
|
|
93
94
|
});
|
|
94
95
|
if (generateCypressSpecs && e2eProject) {
|
|
95
96
|
yield (0, component_cypress_spec_1.default)(tree, {
|
|
@@ -105,8 +106,9 @@ function createAllStories(tree, projectName, generateCypressSpecs, js, cypressPr
|
|
|
105
106
|
}
|
|
106
107
|
exports.createAllStories = createAllStories;
|
|
107
108
|
function storiesGenerator(host, schema) {
|
|
109
|
+
var _a;
|
|
108
110
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
109
|
-
yield createAllStories(host, schema.project, schema.
|
|
111
|
+
yield createAllStories(host, schema.project, (_a = schema.interactionTests) !== null && _a !== void 0 ? _a : true, schema.js, schema.generateCypressSpecs, schema.cypressProject, schema.ignorePaths);
|
|
110
112
|
if (!schema.skipFormat) {
|
|
111
113
|
yield (0, devkit_1.formatFiles)(host);
|
|
112
114
|
}
|
|
@@ -6,7 +6,9 @@ const stories_1 = require("../stories/stories");
|
|
|
6
6
|
const devkit_1 = require("@nx/devkit");
|
|
7
7
|
const versions_1 = require("../../utils/versions");
|
|
8
8
|
function generateStories(host, schema) {
|
|
9
|
+
var _a;
|
|
9
10
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
11
|
+
// TODO(katerina): remove Cypress for Nx 18
|
|
10
12
|
(0, devkit_1.ensurePackage)('@nx/cypress', versions_1.nxVersion);
|
|
11
13
|
const { getE2eProjectName } = yield Promise.resolve().then(() => require('@nx/cypress/src/utils/project-name'));
|
|
12
14
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(host, schema.name);
|
|
@@ -18,19 +20,21 @@ function generateStories(host, schema) {
|
|
|
18
20
|
cypressProject,
|
|
19
21
|
ignorePaths: schema.ignorePaths,
|
|
20
22
|
skipFormat: true,
|
|
23
|
+
interactionTests: (_a = schema.interactionTests) !== null && _a !== void 0 ? _a : true,
|
|
21
24
|
});
|
|
22
25
|
});
|
|
23
26
|
}
|
|
24
27
|
function storybookConfigurationGenerator(host, schema) {
|
|
25
|
-
var _a, _b;
|
|
28
|
+
var _a, _b, _c, _d, _e, _f;
|
|
26
29
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
27
30
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/storybook', versions_1.nxVersion);
|
|
28
|
-
let
|
|
31
|
+
let uiFramework = '@storybook/react-vite';
|
|
29
32
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(host, schema.name);
|
|
30
|
-
if (projectConfig.
|
|
31
|
-
((
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
if (((_a = projectConfig.targets['build']) === null || _a === void 0 ? void 0 : _a.executor) === '@nx/webpack:webpack' ||
|
|
34
|
+
((_b = projectConfig.targets['build']) === null || _b === void 0 ? void 0 : _b.executor) === '@nrwl/webpack:webpack' ||
|
|
35
|
+
((_c = projectConfig.targets['build']) === null || _c === void 0 ? void 0 : _c.executor) === '@nx/rollup:rollup' ||
|
|
36
|
+
((_d = projectConfig.targets['build']) === null || _d === void 0 ? void 0 : _d.executor) === '@nrwl/rollup:rollup') {
|
|
37
|
+
uiFramework = '@storybook/react-webpack5';
|
|
34
38
|
}
|
|
35
39
|
const installTask = yield configurationGenerator(host, {
|
|
36
40
|
name: schema.name,
|
|
@@ -38,12 +42,10 @@ function storybookConfigurationGenerator(host, schema) {
|
|
|
38
42
|
js: schema.js,
|
|
39
43
|
linter: schema.linter,
|
|
40
44
|
cypressDirectory: schema.cypressDirectory,
|
|
41
|
-
tsConfiguration: schema.tsConfiguration,
|
|
42
|
-
|
|
45
|
+
tsConfiguration: (_e = schema.tsConfiguration) !== null && _e !== void 0 ? _e : true,
|
|
46
|
+
interactionTests: (_f = schema.interactionTests) !== null && _f !== void 0 ? _f : true,
|
|
43
47
|
configureStaticServe: schema.configureStaticServe,
|
|
44
|
-
uiFramework:
|
|
45
|
-
? '@storybook/react-vite'
|
|
46
|
-
: '@storybook/react-webpack5',
|
|
48
|
+
uiFramework: uiFramework,
|
|
47
49
|
skipFormat: true,
|
|
48
50
|
});
|
|
49
51
|
if (schema.generateStories) {
|
|
@@ -2,14 +2,14 @@ import { Linter } from '@nx/linter';
|
|
|
2
2
|
|
|
3
3
|
export interface StorybookConfigureSchema {
|
|
4
4
|
name: string;
|
|
5
|
-
|
|
5
|
+
interactionTests?: boolean;
|
|
6
6
|
generateStories?: boolean;
|
|
7
|
+
configureCypress?: boolean;
|
|
7
8
|
generateCypressSpecs?: boolean;
|
|
8
9
|
js?: boolean;
|
|
9
10
|
tsConfiguration?: boolean;
|
|
10
11
|
linter?: Linter;
|
|
11
12
|
cypressDirectory?: string;
|
|
12
13
|
ignorePaths?: string[];
|
|
13
|
-
configureTestRunner?: boolean;
|
|
14
14
|
configureStaticServe?: boolean;
|
|
15
15
|
}
|
|
@@ -18,12 +18,18 @@
|
|
|
18
18
|
"x-dropdown": "projects",
|
|
19
19
|
"x-priority": "important"
|
|
20
20
|
},
|
|
21
|
+
"interactionTests": {
|
|
22
|
+
"type": "boolean",
|
|
23
|
+
"description": "Set up Storybook interaction tests.",
|
|
24
|
+
"x-prompt": "Do you want to set up Storybook interaction tests?",
|
|
25
|
+
"x-priority": "important",
|
|
26
|
+
"alias": ["configureTestRunner"],
|
|
27
|
+
"default": true
|
|
28
|
+
},
|
|
21
29
|
"configureCypress": {
|
|
22
30
|
"type": "boolean",
|
|
23
31
|
"description": "Run the cypress-configure generator.",
|
|
24
|
-
"x-
|
|
25
|
-
"default": true,
|
|
26
|
-
"x-priority": "important"
|
|
32
|
+
"x-deprecated": "Please use Storybook interaction tests instead."
|
|
27
33
|
},
|
|
28
34
|
"generateStories": {
|
|
29
35
|
"type": "boolean",
|
|
@@ -35,9 +41,7 @@
|
|
|
35
41
|
"generateCypressSpecs": {
|
|
36
42
|
"type": "boolean",
|
|
37
43
|
"description": "Automatically generate test files in the Cypress E2E app generated by the `cypress-configure` generator.",
|
|
38
|
-
"x-
|
|
39
|
-
"default": true,
|
|
40
|
-
"x-priority": "important"
|
|
44
|
+
"x-deprecated": "Please use Storybook interaction tests instead."
|
|
41
45
|
},
|
|
42
46
|
"configureStaticServe": {
|
|
43
47
|
"type": "boolean",
|
|
@@ -48,7 +52,8 @@
|
|
|
48
52
|
},
|
|
49
53
|
"cypressDirectory": {
|
|
50
54
|
"type": "string",
|
|
51
|
-
"description": "A directory where the Cypress project will be placed. Placed at the root by default."
|
|
55
|
+
"description": "A directory where the Cypress project will be placed. Placed at the root by default.",
|
|
56
|
+
"x-deprecated": "Please use Storybook interaction tests instead."
|
|
52
57
|
},
|
|
53
58
|
"js": {
|
|
54
59
|
"type": "boolean",
|
|
@@ -58,7 +63,7 @@
|
|
|
58
63
|
"tsConfiguration": {
|
|
59
64
|
"type": "boolean",
|
|
60
65
|
"description": "Configure your project with TypeScript. Generate main.ts and preview.ts files, instead of main.js and preview.js.",
|
|
61
|
-
"default":
|
|
66
|
+
"default": true
|
|
62
67
|
},
|
|
63
68
|
"linter": {
|
|
64
69
|
"description": "The tool to use for running lint checks.",
|
|
@@ -80,10 +85,6 @@
|
|
|
80
85
|
"**/**/src/**/*.other.*",
|
|
81
86
|
"libs/my-lib/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts"
|
|
82
87
|
]
|
|
83
|
-
},
|
|
84
|
-
"configureTestRunner": {
|
|
85
|
-
"type": "boolean",
|
|
86
|
-
"description": "Add a Storybook Test-Runner target."
|
|
87
88
|
}
|
|
88
89
|
},
|
|
89
90
|
"required": ["name"],
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<% if ( !isPlainJs ) { %>import type { Meta } from '@storybook/react';<% } %>
|
|
2
|
-
import<% if ( !isPlainJs ) { %> { <% } %> <%= componentName %> <% if ( !isPlainJs ) { %> } <% } %> from './<%= componentImportFileName %>';
|
|
3
|
-
|
|
4
|
-
<% if ( isPlainJs ) { %>
|
|
5
|
-
export default {
|
|
6
|
-
component: <%= componentName %>,
|
|
7
|
-
title: '<%= componentName %>',<% if ( argTypes && argTypes.length > 0 ) { %>
|
|
8
|
-
argTypes: {<% for (let argType of argTypes) { %>
|
|
9
|
-
<%= argType.name %>: { <%- argType.type %> : "<%- argType.actionText %>" },<% } %>
|
|
10
|
-
}
|
|
11
|
-
<% } %>
|
|
12
|
-
};
|
|
13
|
-
<% } %>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<% if ( !isPlainJs ) { %>
|
|
17
|
-
const Story: Meta<typeof <%= componentName %>> = {
|
|
18
|
-
component: <%= componentName %>,
|
|
19
|
-
title: '<%= componentName %>',<% if ( argTypes && argTypes.length > 0 ) { %>
|
|
20
|
-
argTypes: {<% for (let argType of argTypes) { %>
|
|
21
|
-
<%= argType.name %>: { <%- argType.type %> : "<%- argType.actionText %>" },<% } %>
|
|
22
|
-
}
|
|
23
|
-
<% } %>
|
|
24
|
-
};
|
|
25
|
-
export default Story;
|
|
26
|
-
<% } %>
|
|
27
|
-
|
|
28
|
-
export const Primary = {
|
|
29
|
-
args: {<% for (let prop of props) { %>
|
|
30
|
-
<%= prop.name %>: <%- prop.defaultValue %>,<% } %>
|
|
31
|
-
},
|
|
32
|
-
};
|