@nx/storybook 17.3.0-beta.3 → 17.3.0-beta.5
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 +6 -6
- package/src/generators/configuration/configuration.js +16 -7
- package/src/generators/configuration/lib/edit-root-tsconfig.d.ts +8 -0
- package/src/generators/configuration/lib/edit-root-tsconfig.js +35 -0
- package/src/generators/configuration/lib/ensure-dependencies.d.ts +6 -0
- package/src/generators/configuration/lib/ensure-dependencies.js +86 -0
- package/src/generators/configuration/lib/util-functions.d.ts +5 -2
- package/src/generators/configuration/lib/util-functions.js +7 -2
- package/src/generators/configuration/project-files/.storybook/main.js__tmpl__ +6 -1
- package/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ +5 -1
- package/src/generators/cypress-project/cypress-project.d.ts +3 -3
- package/src/generators/cypress-project/cypress-project.js +3 -8
- package/src/generators/init/init.js +25 -120
- package/src/generators/init/schema.d.ts +2 -4
- package/src/generators/init/schema.json +6 -33
- package/src/plugins/plugin.js +24 -35
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/storybook",
|
|
3
|
-
"version": "17.3.0-beta.
|
|
3
|
+
"version": "17.3.0-beta.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Nx Plugin for Storybook contains executors and generators for allowing your workspace to use the powerful Storybook integration testing & documenting capabilities.",
|
|
6
6
|
"repository": {
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"migrations": "./migrations.json"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@nx/devkit": "17.3.0-beta.
|
|
33
|
+
"@nx/devkit": "17.3.0-beta.5",
|
|
34
34
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
35
35
|
"semver": "7.5.3",
|
|
36
36
|
"tslib": "^2.3.0",
|
|
37
|
-
"@nx/cypress": "17.3.0-beta.
|
|
38
|
-
"@nx/js": "17.3.0-beta.
|
|
39
|
-
"@nx/eslint": "17.3.0-beta.
|
|
40
|
-
"@nrwl/storybook": "17.3.0-beta.
|
|
37
|
+
"@nx/cypress": "17.3.0-beta.5",
|
|
38
|
+
"@nx/js": "17.3.0-beta.5",
|
|
39
|
+
"@nx/eslint": "17.3.0-beta.5",
|
|
40
|
+
"@nrwl/storybook": "17.3.0-beta.5"
|
|
41
41
|
},
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.configurationGenerator = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const js_1 = require("@nx/js");
|
|
5
6
|
const cypress_project_1 = require("../cypress-project/cypress-project");
|
|
6
7
|
const init_1 = require("../init/init");
|
|
7
8
|
const util_functions_1 = require("./lib/util-functions");
|
|
@@ -9,6 +10,8 @@ const eslint_1 = require("@nx/eslint");
|
|
|
9
10
|
const utilities_1 = require("../../utils/utilities");
|
|
10
11
|
const versions_1 = require("../../utils/versions");
|
|
11
12
|
const interaction_testing_utils_1 = require("./lib/interaction-testing.utils");
|
|
13
|
+
const ensure_dependencies_1 = require("./lib/ensure-dependencies");
|
|
14
|
+
const edit_root_tsconfig_1 = require("./lib/edit-root-tsconfig");
|
|
12
15
|
async function configurationGenerator(tree, rawSchema) {
|
|
13
16
|
if ((0, utilities_1.storybookMajorVersion)() === 6) {
|
|
14
17
|
throw new Error((0, utilities_1.pleaseUpgrade)());
|
|
@@ -17,7 +20,9 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
17
20
|
const tasks = [];
|
|
18
21
|
const { projectType, targets, root } = (0, devkit_1.readProjectConfiguration)(tree, schema.project);
|
|
19
22
|
const { compiler } = (0, utilities_1.findStorybookAndBuildTargetsAndCompiler)(targets);
|
|
20
|
-
const
|
|
23
|
+
const viteConfig = (0, util_functions_1.findViteConfig)(tree, root);
|
|
24
|
+
const viteConfigFilePath = viteConfig?.fullConfigPath;
|
|
25
|
+
const viteConfigFileName = viteConfig?.viteConfigFileName;
|
|
21
26
|
const nextConfigFilePath = (0, util_functions_1.findNextConfig)(tree, root);
|
|
22
27
|
if (viteConfigFilePath) {
|
|
23
28
|
if (schema.uiFramework === '@storybook/react-webpack5') {
|
|
@@ -34,11 +39,15 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
34
39
|
if (nextConfigFilePath) {
|
|
35
40
|
schema.uiFramework = '@storybook/nextjs';
|
|
36
41
|
}
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
const jsInitTask = await (0, js_1.initGenerator)(tree, {
|
|
43
|
+
...schema,
|
|
44
|
+
skipFormat: true,
|
|
40
45
|
});
|
|
46
|
+
tasks.push(jsInitTask);
|
|
47
|
+
const initTask = await (0, init_1.initGenerator)(tree, { skipFormat: true });
|
|
41
48
|
tasks.push(initTask);
|
|
49
|
+
tasks.push((0, ensure_dependencies_1.ensureDependencies)(tree, { uiFramework: schema.uiFramework }));
|
|
50
|
+
(0, edit_root_tsconfig_1.editRootTsConfig)(tree);
|
|
42
51
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
43
52
|
const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
|
|
44
53
|
? p === '@nx/storybook/plugin'
|
|
@@ -46,8 +55,8 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
46
55
|
const mainDir = !!nextConfigFilePath && projectType === 'application'
|
|
47
56
|
? 'components'
|
|
48
57
|
: 'src';
|
|
49
|
-
const usesVite = !!viteConfigFilePath || schema.uiFramework
|
|
50
|
-
(0, util_functions_1.createProjectStorybookDir)(tree, schema.project, schema.uiFramework, schema.js, schema.tsConfiguration, root, projectType, (0, util_functions_1.projectIsRootProjectInStandaloneWorkspace)(root), schema.interactionTests, mainDir, !!nextConfigFilePath, compiler === 'swc', usesVite, viteConfigFilePath);
|
|
58
|
+
const usesVite = !!viteConfigFilePath || schema.uiFramework?.endsWith('-vite');
|
|
59
|
+
(0, util_functions_1.createProjectStorybookDir)(tree, schema.project, schema.uiFramework, schema.js, schema.tsConfiguration, root, projectType, (0, util_functions_1.projectIsRootProjectInStandaloneWorkspace)(root), schema.interactionTests, mainDir, !!nextConfigFilePath, compiler === 'swc', usesVite, viteConfigFilePath, hasPlugin, viteConfigFileName);
|
|
51
60
|
if (schema.uiFramework !== '@storybook/angular') {
|
|
52
61
|
(0, util_functions_1.createStorybookTsconfigFile)(tree, root, schema.uiFramework, (0, util_functions_1.projectIsRootProjectInStandaloneWorkspace)(root), mainDir);
|
|
53
62
|
}
|
|
@@ -112,7 +121,7 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
112
121
|
schema.uiFramework === '@storybook/react-webpack5') {
|
|
113
122
|
devDeps['core-js'] = versions_1.coreJsVersion;
|
|
114
123
|
}
|
|
115
|
-
if (schema.uiFramework
|
|
124
|
+
if (schema.uiFramework?.endsWith('-vite') && !viteConfigFilePath) {
|
|
116
125
|
// This means that the user has selected a Vite framework
|
|
117
126
|
// but the project does not have Vite configuration.
|
|
118
127
|
// We need to install the @nx/vite plugin in order to be able to use
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* This is a temporary fix for Storybook to support TypeScript configuration files.
|
|
4
|
+
* The issue is that if there is a root tsconfig.json file, Storybook will use it, and
|
|
5
|
+
* ignore the tsconfig.json file in the .storybook folder. This results in module being set
|
|
6
|
+
* to esnext, and Storybook does not recognise the main.ts code as a module.
|
|
7
|
+
*/
|
|
8
|
+
export declare function editRootTsConfig(tree: Tree): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.editRootTsConfig = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
/**
|
|
6
|
+
* This is a temporary fix for Storybook to support TypeScript configuration files.
|
|
7
|
+
* The issue is that if there is a root tsconfig.json file, Storybook will use it, and
|
|
8
|
+
* ignore the tsconfig.json file in the .storybook folder. This results in module being set
|
|
9
|
+
* to esnext, and Storybook does not recognise the main.ts code as a module.
|
|
10
|
+
*/
|
|
11
|
+
function editRootTsConfig(tree) {
|
|
12
|
+
if (!tree.exists('tsconfig.json')) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
(0, devkit_1.updateJson)(tree, 'tsconfig.json', (json) => {
|
|
16
|
+
if (json['ts-node']) {
|
|
17
|
+
json['ts-node'] = {
|
|
18
|
+
...json['ts-node'],
|
|
19
|
+
compilerOptions: {
|
|
20
|
+
...(json['ts-node'].compilerOptions ?? {}),
|
|
21
|
+
module: 'commonjs',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
json['ts-node'] = {
|
|
27
|
+
compilerOptions: {
|
|
28
|
+
module: 'commonjs',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return json;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
exports.editRootTsConfig = editRootTsConfig;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
|
+
import type { StorybookConfigureSchema } from '../schema';
|
|
3
|
+
export type EnsureDependenciesOptions = {
|
|
4
|
+
uiFramework?: StorybookConfigureSchema['uiFramework'];
|
|
5
|
+
};
|
|
6
|
+
export declare function ensureDependencies(tree: Tree, options: EnsureDependenciesOptions): import("@nx/devkit").GeneratorCallback;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureDependencies = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const semver_1 = require("semver");
|
|
6
|
+
const utilities_1 = require("../../../utils/utilities");
|
|
7
|
+
const versions_1 = require("../../../utils/versions");
|
|
8
|
+
function ensureDependencies(tree, options) {
|
|
9
|
+
let storybook7VersionToInstall = versions_1.storybookVersion;
|
|
10
|
+
if ((0, utilities_1.storybookMajorVersion)() >= 7 &&
|
|
11
|
+
(0, utilities_1.getInstalledStorybookVersion)() &&
|
|
12
|
+
(0, semver_1.gte)((0, utilities_1.getInstalledStorybookVersion)(), '7.0.0')) {
|
|
13
|
+
storybook7VersionToInstall = (0, utilities_1.getInstalledStorybookVersion)();
|
|
14
|
+
}
|
|
15
|
+
const dependencies = {};
|
|
16
|
+
const devDependencies = {
|
|
17
|
+
'@storybook/core-server': storybook7VersionToInstall,
|
|
18
|
+
'@storybook/addon-essentials': storybook7VersionToInstall,
|
|
19
|
+
};
|
|
20
|
+
const packageJson = (0, devkit_1.readJson)(tree, 'package.json');
|
|
21
|
+
packageJson.dependencies ??= {};
|
|
22
|
+
packageJson.devDependencies ??= {};
|
|
23
|
+
// Needed for Storybook 7
|
|
24
|
+
// https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#react-peer-dependencies-required
|
|
25
|
+
if (!packageJson.dependencies['react'] &&
|
|
26
|
+
!packageJson.devDependencies['react']) {
|
|
27
|
+
dependencies['react'] = versions_1.reactVersion;
|
|
28
|
+
}
|
|
29
|
+
if (!packageJson.dependencies['react-dom'] &&
|
|
30
|
+
!packageJson.devDependencies['react-dom']) {
|
|
31
|
+
dependencies['react-dom'] = versions_1.reactVersion;
|
|
32
|
+
}
|
|
33
|
+
if (options.uiFramework) {
|
|
34
|
+
if (options.uiFramework === '@storybook/react-native') {
|
|
35
|
+
devDependencies['@storybook/react-native'] = versions_1.storybookReactNativeVersion;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
devDependencies[options.uiFramework] = storybook7VersionToInstall;
|
|
39
|
+
const isPnpm = (0, devkit_1.detectPackageManager)(tree.root) === 'pnpm';
|
|
40
|
+
if (isPnpm) {
|
|
41
|
+
// If it's pnpm, it needs the framework without the builder
|
|
42
|
+
// as a dependency too (eg. @storybook/react)
|
|
43
|
+
const matchResult = options.uiFramework?.match(/^@storybook\/(\w+)/);
|
|
44
|
+
const uiFrameworkWithoutBuilder = matchResult ? matchResult[0] : null;
|
|
45
|
+
if (uiFrameworkWithoutBuilder) {
|
|
46
|
+
devDependencies[uiFrameworkWithoutBuilder] =
|
|
47
|
+
storybook7VersionToInstall;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (options.uiFramework === '@storybook/vue3-vite') {
|
|
52
|
+
if (!packageJson.dependencies['@storybook/vue3'] &&
|
|
53
|
+
!packageJson.devDependencies['@storybook/vue3']) {
|
|
54
|
+
devDependencies['@storybook/vue3'] = storybook7VersionToInstall;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (options.uiFramework === '@storybook/angular') {
|
|
58
|
+
if (!packageJson.dependencies['@angular/forms'] &&
|
|
59
|
+
!packageJson.devDependencies['@angular/forms']) {
|
|
60
|
+
devDependencies['@angular/forms'] = '*';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (options.uiFramework === '@storybook/web-components-vite' ||
|
|
64
|
+
options.uiFramework === '@storybook/web-components-webpack5') {
|
|
65
|
+
devDependencies['lit'] = versions_1.litVersion;
|
|
66
|
+
}
|
|
67
|
+
if (options.uiFramework === '@storybook/react-native') {
|
|
68
|
+
devDependencies['@storybook/addon-ondevice-actions'] =
|
|
69
|
+
versions_1.storybookReactNativeVersion;
|
|
70
|
+
devDependencies['@storybook/addon-ondevice-backgrounds'] =
|
|
71
|
+
versions_1.storybookReactNativeVersion;
|
|
72
|
+
devDependencies['@storybook/addon-ondevice-controls'] =
|
|
73
|
+
versions_1.storybookReactNativeVersion;
|
|
74
|
+
devDependencies['@storybook/addon-ondevice-notes'] =
|
|
75
|
+
versions_1.storybookReactNativeVersion;
|
|
76
|
+
}
|
|
77
|
+
if (options.uiFramework.endsWith('-vite')) {
|
|
78
|
+
if (!packageJson.dependencies['vite'] &&
|
|
79
|
+
!packageJson.devDependencies['vite']) {
|
|
80
|
+
devDependencies['vite'] = versions_1.viteVersion;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return (0, devkit_1.addDependenciesToPackageJson)(tree, dependencies, devDependencies);
|
|
85
|
+
}
|
|
86
|
+
exports.ensureDependencies = ensureDependencies;
|
|
@@ -18,13 +18,16 @@ export declare function configureTsSolutionConfig(tree: Tree, schema: StorybookC
|
|
|
18
18
|
export declare function updateLintConfig(tree: Tree, schema: StorybookConfigureSchema): void;
|
|
19
19
|
export declare function normalizeSchema(schema: StorybookConfigureSchema): StorybookConfigureSchema;
|
|
20
20
|
export declare function addStorybookToNamedInputs(tree: Tree): void;
|
|
21
|
-
export declare function createProjectStorybookDir(tree: Tree, projectName: string, uiFramework: UiFramework, js: boolean, tsConfiguration: boolean, root: string, projectType: string, projectIsRootProjectInStandaloneWorkspace: boolean, interactionTests: boolean, mainDir?: string, isNextJs?: boolean, usesSwc?: boolean, usesVite?: boolean, viteConfigFilePath?: string): void;
|
|
21
|
+
export declare function createProjectStorybookDir(tree: Tree, projectName: string, uiFramework: UiFramework, js: boolean, tsConfiguration: boolean, root: string, projectType: string, projectIsRootProjectInStandaloneWorkspace: boolean, interactionTests: boolean, mainDir?: string, isNextJs?: boolean, usesSwc?: boolean, usesVite?: boolean, viteConfigFilePath?: string, hasPlugin?: boolean, viteConfigFileName?: string): void;
|
|
22
22
|
export declare function getTsConfigPath(tree: Tree, projectName: string, path?: string): string;
|
|
23
23
|
export declare function addBuildStorybookToCacheableOperations(tree: Tree): void;
|
|
24
24
|
export declare function projectIsRootProjectInStandaloneWorkspace(projectRoot: string): boolean;
|
|
25
25
|
export declare function workspaceHasRootProject(tree: Tree): boolean;
|
|
26
26
|
export declare function rootFileIsTs(tree: Tree, rootFileName: string, tsConfiguration: boolean): boolean;
|
|
27
27
|
export declare function getE2EProjectName(tree: Tree, mainProject: string): Promise<string | undefined>;
|
|
28
|
-
export declare function findViteConfig(tree: Tree, projectRoot: string):
|
|
28
|
+
export declare function findViteConfig(tree: Tree, projectRoot: string): {
|
|
29
|
+
fullConfigPath: string | undefined;
|
|
30
|
+
viteConfigFileName: string | undefined;
|
|
31
|
+
};
|
|
29
32
|
export declare function findNextConfig(tree: Tree, projectRoot: string): string | undefined;
|
|
30
33
|
export declare function renameAndMoveOldTsConfig(projectRoot: string, pathToStorybookConfigFile: string, tree: Tree): void;
|
|
@@ -360,7 +360,7 @@ function addStorybookToNamedInputs(tree) {
|
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
362
|
exports.addStorybookToNamedInputs = addStorybookToNamedInputs;
|
|
363
|
-
function createProjectStorybookDir(tree, projectName, uiFramework, js, tsConfiguration, root, projectType, projectIsRootProjectInStandaloneWorkspace, interactionTests, mainDir, isNextJs, usesSwc, usesVite, viteConfigFilePath) {
|
|
363
|
+
function createProjectStorybookDir(tree, projectName, uiFramework, js, tsConfiguration, root, projectType, projectIsRootProjectInStandaloneWorkspace, interactionTests, mainDir, isNextJs, usesSwc, usesVite, viteConfigFilePath, hasPlugin, viteConfigFileName) {
|
|
364
364
|
let projectDirectory = projectType === 'application'
|
|
365
365
|
? isNextJs
|
|
366
366
|
? 'components'
|
|
@@ -391,6 +391,8 @@ function createProjectStorybookDir(tree, projectName, uiFramework, js, tsConfigu
|
|
|
391
391
|
usesVite,
|
|
392
392
|
isRootProject: projectIsRootProjectInStandaloneWorkspace,
|
|
393
393
|
viteConfigFilePath,
|
|
394
|
+
hasPlugin,
|
|
395
|
+
viteConfigFileName,
|
|
394
396
|
});
|
|
395
397
|
if (js) {
|
|
396
398
|
(0, devkit_1.toJS)(tree);
|
|
@@ -484,7 +486,10 @@ function findViteConfig(tree, projectRoot) {
|
|
|
484
486
|
for (const ext of allowsExt) {
|
|
485
487
|
const viteConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, `vite.config.${ext}`);
|
|
486
488
|
if (tree.exists(viteConfigPath)) {
|
|
487
|
-
return
|
|
489
|
+
return {
|
|
490
|
+
fullConfigPath: viteConfigPath,
|
|
491
|
+
viteConfigFileName: `vite.config.${ext}`,
|
|
492
|
+
};
|
|
488
493
|
}
|
|
489
494
|
}
|
|
490
495
|
}
|
|
@@ -13,7 +13,12 @@ const config = {
|
|
|
13
13
|
framework: {
|
|
14
14
|
name: '<%= uiFramework %>',
|
|
15
15
|
options: {
|
|
16
|
-
|
|
16
|
+
<% if (usesVite && viteConfigFilePath && hasPlugin) { %>
|
|
17
|
+
builder: {
|
|
18
|
+
viteConfigPath: '<%= viteConfigFileName %>',
|
|
19
|
+
},
|
|
20
|
+
<% } %>
|
|
21
|
+
<% if (usesVite && viteConfigFilePath && !hasPlugin) { %>
|
|
17
22
|
builder: {
|
|
18
23
|
viteConfigPath: '<%= viteConfigFilePath %>',
|
|
19
24
|
},
|
|
@@ -14,7 +14,11 @@ const config: StorybookConfig = {
|
|
|
14
14
|
framework: {
|
|
15
15
|
name: '<%= uiFramework %>',
|
|
16
16
|
options: {
|
|
17
|
-
<% if (usesVite && viteConfigFilePath) { %>
|
|
17
|
+
<% if (usesVite && viteConfigFilePath && hasPlugin) { %>
|
|
18
|
+
builder: {
|
|
19
|
+
viteConfigPath: '<%= viteConfigFileName %>',
|
|
20
|
+
},
|
|
21
|
+
<% } %><% if (usesVite && viteConfigFilePath && !hasPlugin) { %>
|
|
18
22
|
builder: {
|
|
19
23
|
viteConfigPath: '<%= viteConfigFilePath %>',
|
|
20
24
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tree } from '@nx/devkit';
|
|
2
2
|
import { Linter } from '@nx/eslint';
|
|
3
3
|
export interface CypressConfigureSchema {
|
|
4
4
|
name: string;
|
|
@@ -10,6 +10,6 @@ export interface CypressConfigureSchema {
|
|
|
10
10
|
skipFormat?: boolean;
|
|
11
11
|
projectNameAndRootFormat?: 'as-provided' | 'derived';
|
|
12
12
|
}
|
|
13
|
-
export declare function cypressProjectGenerator(tree: Tree, schema: CypressConfigureSchema): Promise<GeneratorCallback>;
|
|
14
|
-
export declare function cypressProjectGeneratorInternal(tree: Tree, schema: CypressConfigureSchema): Promise<GeneratorCallback>;
|
|
13
|
+
export declare function cypressProjectGenerator(tree: Tree, schema: CypressConfigureSchema): Promise<import("@nx/devkit").GeneratorCallback>;
|
|
14
|
+
export declare function cypressProjectGeneratorInternal(tree: Tree, schema: CypressConfigureSchema): Promise<import("@nx/devkit").GeneratorCallback>;
|
|
15
15
|
export default cypressProjectGenerator;
|
|
@@ -15,7 +15,7 @@ async function cypressProjectGenerator(tree, schema) {
|
|
|
15
15
|
}
|
|
16
16
|
exports.cypressProjectGenerator = cypressProjectGenerator;
|
|
17
17
|
async function cypressProjectGeneratorInternal(tree, schema) {
|
|
18
|
-
const { configurationGenerator
|
|
18
|
+
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/cypress', versions_1.nxVersion);
|
|
19
19
|
const e2eName = schema.name ? `${schema.name}-e2e` : undefined;
|
|
20
20
|
const { projectName, projectRoot } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(tree, {
|
|
21
21
|
name: e2eName,
|
|
@@ -26,10 +26,6 @@ async function cypressProjectGeneratorInternal(tree, schema) {
|
|
|
26
26
|
});
|
|
27
27
|
const libConfig = (0, devkit_1.readProjectConfiguration)(tree, schema.name);
|
|
28
28
|
const libRoot = libConfig.root;
|
|
29
|
-
const tasks = [];
|
|
30
|
-
if (!projectAlreadyHasCypress(tree)) {
|
|
31
|
-
tasks.push(await cypressInitGenerator(tree, {}));
|
|
32
|
-
}
|
|
33
29
|
(0, devkit_1.addProjectConfiguration)(tree, projectName, {
|
|
34
30
|
root: projectRoot,
|
|
35
31
|
projectType: 'application',
|
|
@@ -37,7 +33,7 @@ async function cypressProjectGeneratorInternal(tree, schema) {
|
|
|
37
33
|
targets: {},
|
|
38
34
|
implicitDependencies: [projectName],
|
|
39
35
|
});
|
|
40
|
-
const
|
|
36
|
+
const cypressTask = await configurationGenerator(tree, {
|
|
41
37
|
project: projectName,
|
|
42
38
|
js: schema.js,
|
|
43
39
|
linter: schema.linter,
|
|
@@ -45,7 +41,6 @@ async function cypressProjectGeneratorInternal(tree, schema) {
|
|
|
45
41
|
devServerTarget: `${schema.name}:storybook`,
|
|
46
42
|
skipFormat: true,
|
|
47
43
|
});
|
|
48
|
-
tasks.push(installTask);
|
|
49
44
|
const generatedCypressProjectName = (0, project_name_1.getE2eProjectName)(schema.name, libRoot, schema.directory);
|
|
50
45
|
removeUnneededFiles(tree, generatedCypressProjectName, schema.js);
|
|
51
46
|
addBaseUrlToCypressConfig(tree, generatedCypressProjectName);
|
|
@@ -57,7 +52,7 @@ async function cypressProjectGeneratorInternal(tree, schema) {
|
|
|
57
52
|
if (!schema.skipFormat) {
|
|
58
53
|
await (0, devkit_1.formatFiles)(tree);
|
|
59
54
|
}
|
|
60
|
-
return
|
|
55
|
+
return cypressTask;
|
|
61
56
|
}
|
|
62
57
|
exports.cypressProjectGeneratorInternal = cypressProjectGeneratorInternal;
|
|
63
58
|
function removeUnneededFiles(tree, projectName, js) {
|
|
@@ -2,91 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.initGenerator = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const js_1 = require("@nx/js");
|
|
6
|
-
const versions_1 = require("../../utils/versions");
|
|
7
|
-
const utilities_1 = require("../../utils/utilities");
|
|
8
5
|
const semver_1 = require("semver");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// base deps
|
|
16
|
-
devDependencies['@nx/storybook'] = versions_1.nxVersion;
|
|
17
|
-
let storybook7VersionToInstall = versions_1.storybookVersion;
|
|
18
|
-
if ((0, utilities_1.storybookMajorVersion)() >= 7 &&
|
|
19
|
-
(0, utilities_1.getInstalledStorybookVersion)() &&
|
|
20
|
-
(0, semver_1.gte)((0, utilities_1.getInstalledStorybookVersion)(), '7.0.0')) {
|
|
21
|
-
storybook7VersionToInstall = (0, utilities_1.getInstalledStorybookVersion)();
|
|
22
|
-
}
|
|
23
|
-
// Needed for Storybook 7
|
|
24
|
-
// https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#react-peer-dependencies-required
|
|
25
|
-
if (!packageJson.dependencies['react'] &&
|
|
26
|
-
!packageJson.devDependencies['react']) {
|
|
27
|
-
dependencies['react'] = versions_1.reactVersion;
|
|
28
|
-
}
|
|
29
|
-
if (!packageJson.dependencies['react-dom'] &&
|
|
30
|
-
!packageJson.devDependencies['react-dom']) {
|
|
31
|
-
dependencies['react-dom'] = versions_1.reactVersion;
|
|
32
|
-
}
|
|
6
|
+
const utilities_1 = require("../../utils/utilities");
|
|
7
|
+
const versions_1 = require("../../utils/versions");
|
|
8
|
+
function checkDependenciesInstalled(host) {
|
|
9
|
+
const devDependencies = {
|
|
10
|
+
'@nx/storybook': versions_1.nxVersion,
|
|
11
|
+
};
|
|
33
12
|
if (process.env.NX_PCV3 === 'true') {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (schema.uiFramework === '@storybook/react-native') {
|
|
40
|
-
devDependencies['@storybook/react-native'] = versions_1.storybookReactNativeVersion;
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
devDependencies[schema.uiFramework] = storybook7VersionToInstall;
|
|
44
|
-
const isPnpm = (0, devkit_1.detectPackageManager)(host.root) === 'pnpm';
|
|
45
|
-
if (isPnpm) {
|
|
46
|
-
// If it's pnpm, it needs the framework without the builder
|
|
47
|
-
// as a dependency too (eg. @storybook/react)
|
|
48
|
-
const matchResult = schema.uiFramework?.match(/^@storybook\/(\w+)/);
|
|
49
|
-
const uiFrameworkWithoutBuilder = matchResult ? matchResult[0] : null;
|
|
50
|
-
if (uiFrameworkWithoutBuilder) {
|
|
51
|
-
devDependencies[uiFrameworkWithoutBuilder] =
|
|
52
|
-
storybook7VersionToInstall;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (schema.uiFramework === '@storybook/vue3-vite') {
|
|
57
|
-
if (!packageJson.dependencies['@storybook/vue3'] &&
|
|
58
|
-
!packageJson.devDependencies['@storybook/vue3']) {
|
|
59
|
-
devDependencies['@storybook/vue3'] = storybook7VersionToInstall;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (schema.uiFramework === '@storybook/angular') {
|
|
63
|
-
if (!packageJson.dependencies['@angular/forms'] &&
|
|
64
|
-
!packageJson.devDependencies['@angular/forms']) {
|
|
65
|
-
devDependencies['@angular/forms'] = '*';
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (schema.uiFramework === '@storybook/web-components-vite' ||
|
|
69
|
-
schema.uiFramework === '@storybook/web-components-webpack5') {
|
|
70
|
-
devDependencies['lit'] = versions_1.litVersion;
|
|
71
|
-
}
|
|
72
|
-
if (schema.uiFramework === '@storybook/react-native') {
|
|
73
|
-
devDependencies['@storybook/addon-ondevice-actions'] =
|
|
74
|
-
versions_1.storybookReactNativeVersion;
|
|
75
|
-
devDependencies['@storybook/addon-ondevice-backgrounds'] =
|
|
76
|
-
versions_1.storybookReactNativeVersion;
|
|
77
|
-
devDependencies['@storybook/addon-ondevice-controls'] =
|
|
78
|
-
versions_1.storybookReactNativeVersion;
|
|
79
|
-
devDependencies['@storybook/addon-ondevice-notes'] =
|
|
80
|
-
versions_1.storybookReactNativeVersion;
|
|
81
|
-
}
|
|
82
|
-
if (schema.uiFramework.endsWith('-vite')) {
|
|
83
|
-
if (!packageJson.dependencies['vite'] &&
|
|
84
|
-
!packageJson.devDependencies['vite']) {
|
|
85
|
-
devDependencies['vite'] = versions_1.viteVersion;
|
|
86
|
-
}
|
|
13
|
+
let storybook7VersionToInstall = versions_1.storybookVersion;
|
|
14
|
+
if ((0, utilities_1.storybookMajorVersion)() >= 7 &&
|
|
15
|
+
(0, utilities_1.getInstalledStorybookVersion)() &&
|
|
16
|
+
(0, semver_1.gte)((0, utilities_1.getInstalledStorybookVersion)(), '7.0.0')) {
|
|
17
|
+
storybook7VersionToInstall = (0, utilities_1.getInstalledStorybookVersion)();
|
|
87
18
|
}
|
|
19
|
+
devDependencies['storybook'] = storybook7VersionToInstall;
|
|
88
20
|
}
|
|
89
|
-
return (0, devkit_1.addDependenciesToPackageJson)(host,
|
|
21
|
+
return (0, devkit_1.addDependenciesToPackageJson)(host, {}, devDependencies);
|
|
90
22
|
}
|
|
91
23
|
function addCacheableOperation(tree) {
|
|
92
24
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
@@ -100,6 +32,7 @@ function addCacheableOperation(tree) {
|
|
|
100
32
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
101
33
|
}
|
|
102
34
|
function moveToDevDependencies(tree) {
|
|
35
|
+
let updated = false;
|
|
103
36
|
(0, devkit_1.updateJson)(tree, 'package.json', (packageJson) => {
|
|
104
37
|
packageJson.dependencies = packageJson.dependencies || {};
|
|
105
38
|
packageJson.devDependencies = packageJson.devDependencies || {};
|
|
@@ -107,53 +40,25 @@ function moveToDevDependencies(tree) {
|
|
|
107
40
|
packageJson.devDependencies['@nx/storybook'] =
|
|
108
41
|
packageJson.dependencies['@nx/storybook'];
|
|
109
42
|
delete packageJson.dependencies['@nx/storybook'];
|
|
43
|
+
updated = true;
|
|
110
44
|
}
|
|
111
45
|
return packageJson;
|
|
112
46
|
});
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* This is a temporary fix for Storybook to support TypeScript configuration files.
|
|
116
|
-
* The issue is that if there is a root tsconfig.json file, Storybook will use it, and
|
|
117
|
-
* ignore the tsconfig.json file in the .storybook folder. This results in module being set
|
|
118
|
-
* to esnext, and Storybook does not recognise the main.ts code as a module.
|
|
119
|
-
*/
|
|
120
|
-
function editRootTsConfig(tree) {
|
|
121
|
-
if (tree.exists('tsconfig.json')) {
|
|
122
|
-
(0, devkit_1.updateJson)(tree, 'tsconfig.json', (json) => {
|
|
123
|
-
if (json['ts-node']) {
|
|
124
|
-
json['ts-node'] = {
|
|
125
|
-
...json['ts-node'],
|
|
126
|
-
compilerOptions: {
|
|
127
|
-
...(json['ts-node'].compilerOptions ?? {}),
|
|
128
|
-
module: 'commonjs',
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
json['ts-node'] = {
|
|
134
|
-
compilerOptions: {
|
|
135
|
-
module: 'commonjs',
|
|
136
|
-
},
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
return json;
|
|
140
|
-
});
|
|
141
|
-
}
|
|
47
|
+
return updated ? () => (0, devkit_1.installPackagesTask)(tree) : () => { };
|
|
142
48
|
}
|
|
143
49
|
async function initGenerator(tree, schema) {
|
|
144
|
-
const tasks = [];
|
|
145
|
-
tasks.push(await (0, js_1.initGenerator)(tree, {
|
|
146
|
-
...schema,
|
|
147
|
-
skipFormat: true,
|
|
148
|
-
}));
|
|
149
|
-
tasks.push(checkDependenciesInstalled(tree, schema));
|
|
150
|
-
moveToDevDependencies(tree);
|
|
151
|
-
editRootTsConfig(tree);
|
|
152
50
|
addCacheableOperation(tree);
|
|
153
|
-
|
|
154
|
-
if (addPlugins) {
|
|
51
|
+
if (process.env.NX_PCV3 === 'true') {
|
|
155
52
|
(0, utilities_1.addPlugin)(tree);
|
|
156
53
|
}
|
|
54
|
+
const tasks = [];
|
|
55
|
+
if (!schema.skipPackageJson) {
|
|
56
|
+
tasks.push(moveToDevDependencies(tree));
|
|
57
|
+
tasks.push(checkDependenciesInstalled(tree));
|
|
58
|
+
}
|
|
59
|
+
if (!schema.skipFormat) {
|
|
60
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
61
|
+
}
|
|
157
62
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
158
63
|
}
|
|
159
64
|
exports.initGenerator = initGenerator;
|
|
@@ -5,41 +5,14 @@
|
|
|
5
5
|
"$id": "init-storybook-plugin",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"@storybook/angular",
|
|
13
|
-
"@storybook/html-webpack5",
|
|
14
|
-
"@storybook/nextjs",
|
|
15
|
-
"@storybook/preact-webpack5",
|
|
16
|
-
"@storybook/react-webpack5",
|
|
17
|
-
"@storybook/react-vite",
|
|
18
|
-
"@storybook/server-webpack5",
|
|
19
|
-
"@storybook/svelte-webpack5",
|
|
20
|
-
"@storybook/svelte-vite",
|
|
21
|
-
"@storybook/sveltekit",
|
|
22
|
-
"@storybook/vue-webpack5",
|
|
23
|
-
"@storybook/vue-vite",
|
|
24
|
-
"@storybook/vue3-webpack5",
|
|
25
|
-
"@storybook/vue3-vite",
|
|
26
|
-
"@storybook/web-components-webpack5",
|
|
27
|
-
"@storybook/web-components-vite",
|
|
28
|
-
"@storybook/react",
|
|
29
|
-
"@storybook/html",
|
|
30
|
-
"@storybook/web-components",
|
|
31
|
-
"@storybook/vue",
|
|
32
|
-
"@storybook/vue3",
|
|
33
|
-
"@storybook/svelte",
|
|
34
|
-
"@storybook/react-native"
|
|
35
|
-
],
|
|
36
|
-
"x-prompt": "What UI framework plugin should storybook use?",
|
|
37
|
-
"x-priority": "important",
|
|
38
|
-
"aliases": ["storybook7UiFramework"]
|
|
8
|
+
"skipFormat": {
|
|
9
|
+
"description": "Skip formatting files.",
|
|
10
|
+
"type": "boolean",
|
|
11
|
+
"default": false
|
|
39
12
|
},
|
|
40
|
-
"
|
|
13
|
+
"skipPackageJson": {
|
|
14
|
+
"description": "Do not add dependencies to `package.json`.",
|
|
41
15
|
"type": "boolean",
|
|
42
|
-
"description": "Generate JavaScript story files rather than TypeScript story files.",
|
|
43
16
|
"default": false
|
|
44
17
|
}
|
|
45
18
|
}
|
package/src/plugins/plugin.js
CHANGED
|
@@ -60,7 +60,7 @@ exports.createNodes = [
|
|
|
60
60
|
},
|
|
61
61
|
};
|
|
62
62
|
// For root projects, the name is not inferred from root package.json, so we need to manually set it.
|
|
63
|
-
// TODO(
|
|
63
|
+
// TODO(katerina): Remove this workaround once Craigory's PR (https://github.com/nrwl/nx/pull/21125) is merged
|
|
64
64
|
if (projectRoot === '.') {
|
|
65
65
|
result.projects[projectRoot]['name'] = projectName;
|
|
66
66
|
}
|
|
@@ -73,23 +73,22 @@ function buildStorybookTargets(configFilePath, projectRoot, options, context, pr
|
|
|
73
73
|
const storybookFramework = getStorybookConfig(configFilePath, context);
|
|
74
74
|
const frameworkIsAngular = storybookFramework === "'@storybook/angular'";
|
|
75
75
|
const targets = {};
|
|
76
|
-
targets[options.buildStorybookTargetName] = buildTarget(namedInputs, buildOutputs,
|
|
77
|
-
targets[options.serveStorybookTargetName] = serveTarget(
|
|
78
|
-
targets[options.testStorybookTargetName] = testTarget(
|
|
76
|
+
targets[options.buildStorybookTargetName] = buildTarget(namedInputs, buildOutputs, projectRoot, frameworkIsAngular, projectName, configFilePath);
|
|
77
|
+
targets[options.serveStorybookTargetName] = serveTarget(projectRoot, frameworkIsAngular, projectName, configFilePath);
|
|
78
|
+
targets[options.testStorybookTargetName] = testTarget(projectRoot);
|
|
79
79
|
targets[options.staticStorybookTargetName] = serveStaticTarget(options, projectRoot);
|
|
80
80
|
return targets;
|
|
81
81
|
}
|
|
82
|
-
function buildTarget(namedInputs, outputs,
|
|
83
|
-
const outputDir = (0, devkit_1.joinPathFragments)('dist/storybook', projectRoot);
|
|
82
|
+
function buildTarget(namedInputs, outputs, projectRoot, frameworkIsAngular, projectName, configFilePath) {
|
|
84
83
|
let targetConfig;
|
|
85
84
|
if (frameworkIsAngular) {
|
|
86
85
|
targetConfig = {
|
|
87
86
|
executor: '@storybook/angular:build-storybook',
|
|
88
87
|
options: {
|
|
89
|
-
outputDir: `${outputDir}`,
|
|
90
88
|
configDir: `${(0, path_1.dirname)(configFilePath)}`,
|
|
91
89
|
browserTarget: `${projectName}:build-storybook`,
|
|
92
90
|
compodoc: false,
|
|
91
|
+
outputDir: (0, devkit_1.joinPathFragments)(projectRoot, 'static-storybook'),
|
|
93
92
|
},
|
|
94
93
|
cache: true,
|
|
95
94
|
outputs,
|
|
@@ -109,7 +108,8 @@ function buildTarget(namedInputs, outputs, configFilePath, projectRoot, framewor
|
|
|
109
108
|
}
|
|
110
109
|
else {
|
|
111
110
|
targetConfig = {
|
|
112
|
-
command: `storybook build
|
|
111
|
+
command: `storybook build`,
|
|
112
|
+
options: { cwd: projectRoot },
|
|
113
113
|
cache: true,
|
|
114
114
|
outputs,
|
|
115
115
|
inputs: [
|
|
@@ -124,7 +124,7 @@ function buildTarget(namedInputs, outputs, configFilePath, projectRoot, framewor
|
|
|
124
124
|
}
|
|
125
125
|
return targetConfig;
|
|
126
126
|
}
|
|
127
|
-
function serveTarget(
|
|
127
|
+
function serveTarget(projectRoot, frameworkIsAngular, projectName, configFilePath) {
|
|
128
128
|
if (frameworkIsAngular) {
|
|
129
129
|
return {
|
|
130
130
|
executor: '@storybook/angular:start-storybook',
|
|
@@ -137,13 +137,15 @@ function serveTarget(configFilePath, frameworkIsAngular, projectName) {
|
|
|
137
137
|
}
|
|
138
138
|
else {
|
|
139
139
|
return {
|
|
140
|
-
command: `storybook dev
|
|
140
|
+
command: `storybook dev`,
|
|
141
|
+
options: { cwd: projectRoot },
|
|
141
142
|
};
|
|
142
143
|
}
|
|
143
144
|
}
|
|
144
|
-
function testTarget(
|
|
145
|
+
function testTarget(projectRoot) {
|
|
145
146
|
const targetConfig = {
|
|
146
|
-
command: `test-storybook
|
|
147
|
+
command: `test-storybook`,
|
|
148
|
+
options: { cwd: projectRoot },
|
|
147
149
|
inputs: [
|
|
148
150
|
{
|
|
149
151
|
externalDependencies: ['storybook', '@storybook/test-runner'],
|
|
@@ -157,8 +159,7 @@ function serveStaticTarget(options, projectRoot) {
|
|
|
157
159
|
executor: '@nx/web:file-server',
|
|
158
160
|
options: {
|
|
159
161
|
buildTarget: `${options.buildStorybookTargetName}`,
|
|
160
|
-
|
|
161
|
-
staticFilePath: (0, devkit_1.joinPathFragments)('dist/storybook', projectRoot),
|
|
162
|
+
staticFilePath: (0, devkit_1.joinPathFragments)(projectRoot, 'static-storybook'),
|
|
162
163
|
},
|
|
163
164
|
};
|
|
164
165
|
return targetConfig;
|
|
@@ -194,33 +195,21 @@ function getStorybookConfig(configFilePath, context) {
|
|
|
194
195
|
return frameworkName;
|
|
195
196
|
}
|
|
196
197
|
function getOutputs(_projectRoot) {
|
|
197
|
-
// TODO(katerina): need to read the output from CLI args
|
|
198
|
-
// const outputPath = <output path as read from CLI>;
|
|
199
198
|
const normalizedOutputPath = normalizeOutputPath(undefined, _projectRoot);
|
|
200
|
-
const outputs = [
|
|
199
|
+
const outputs = [
|
|
200
|
+
normalizedOutputPath,
|
|
201
|
+
`{options.output-dir}`,
|
|
202
|
+
`{options.outputDir}`,
|
|
203
|
+
`{options.o}`,
|
|
204
|
+
];
|
|
201
205
|
return outputs;
|
|
202
206
|
}
|
|
203
207
|
function normalizeOutputPath(outputPath, projectRoot) {
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
return `{projectRoot}/dist/storybook`;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
return `{workspaceRoot}/dist/storybook/{projectRoot}`;
|
|
210
|
-
}
|
|
208
|
+
if (projectRoot === '.') {
|
|
209
|
+
return `{projectRoot}/static-storybook`;
|
|
211
210
|
}
|
|
212
211
|
else {
|
|
213
|
-
|
|
214
|
-
return `{workspaceRoot}/${(0, path_1.relative)(devkit_1.workspaceRoot, outputPath)}`;
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
if (outputPath.startsWith('..')) {
|
|
218
|
-
return (0, path_1.join)('{workspaceRoot}', (0, path_1.join)(projectRoot, outputPath));
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
return (0, path_1.join)('{projectRoot}', outputPath);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
212
|
+
return `{workspaceRoot}/{projectRoot}/static-storybook`;
|
|
224
213
|
}
|
|
225
214
|
}
|
|
226
215
|
function normalizeOptions(options) {
|