@nx/storybook 17.3.0-beta.2 → 17.3.0-beta.4
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/plugin.d.ts +1 -0
- package/plugin.js +6 -0
- package/src/generators/configuration/configuration.js +37 -22
- 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 +4 -3
- package/src/generators/configuration/lib/util-functions.js +24 -14
- 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 +28 -116
- package/src/generators/init/schema.d.ts +2 -4
- package/src/generators/init/schema.json +6 -33
- package/src/plugins/plugin.d.ts +9 -0
- package/src/plugins/plugin.js +247 -0
- package/src/utils/utilities.d.ts +1 -0
- package/src/utils/utilities.js +24 -1
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.4",
|
|
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.4",
|
|
33
34
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
34
35
|
"semver": "7.5.3",
|
|
35
36
|
"tslib": "^2.3.0",
|
|
36
|
-
"@nx/cypress": "17.3.0-beta.
|
|
37
|
-
"@nx/
|
|
38
|
-
"@nx/
|
|
39
|
-
"@
|
|
40
|
-
"@nrwl/storybook": "17.3.0-beta.2"
|
|
37
|
+
"@nx/cypress": "17.3.0-beta.4",
|
|
38
|
+
"@nx/js": "17.3.0-beta.4",
|
|
39
|
+
"@nx/eslint": "17.3.0-beta.4",
|
|
40
|
+
"@nrwl/storybook": "17.3.0-beta.4"
|
|
41
41
|
},
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
package/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createNodes, StorybookPluginOptions, createDependencies, } from './src/plugins/plugin';
|
package/plugin.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDependencies = exports.createNodes = void 0;
|
|
4
|
+
var plugin_1 = require("./src/plugins/plugin");
|
|
5
|
+
Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return plugin_1.createNodes; } });
|
|
6
|
+
Object.defineProperty(exports, "createDependencies", { enumerable: true, get: function () { return plugin_1.createDependencies; } });
|
|
@@ -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)());
|
|
@@ -16,12 +19,10 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
16
19
|
const schema = normalizeSchema(rawSchema);
|
|
17
20
|
const tasks = [];
|
|
18
21
|
const { projectType, targets, root } = (0, devkit_1.readProjectConfiguration)(tree, schema.project);
|
|
19
|
-
const {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
if (viteBuildTarget) {
|
|
22
|
+
const { compiler } = (0, utilities_1.findStorybookAndBuildTargetsAndCompiler)(targets);
|
|
23
|
+
const viteConfigFilePath = (0, util_functions_1.findViteConfig)(tree, root);
|
|
24
|
+
const nextConfigFilePath = (0, util_functions_1.findNextConfig)(tree, root);
|
|
25
|
+
if (viteConfigFilePath) {
|
|
25
26
|
if (schema.uiFramework === '@storybook/react-webpack5') {
|
|
26
27
|
devkit_1.logger.info(`Your project ${schema.project} uses Vite as a bundler.
|
|
27
28
|
Nx will configure Storybook for this project to use Vite as well.`);
|
|
@@ -33,17 +34,27 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
33
34
|
schema.uiFramework = '@storybook/web-components-vite';
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
|
-
if (
|
|
37
|
+
if (nextConfigFilePath) {
|
|
37
38
|
schema.uiFramework = '@storybook/nextjs';
|
|
38
39
|
}
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const jsInitTask = await (0, js_1.initGenerator)(tree, {
|
|
41
|
+
...schema,
|
|
42
|
+
skipFormat: true,
|
|
42
43
|
});
|
|
44
|
+
tasks.push(jsInitTask);
|
|
45
|
+
const initTask = await (0, init_1.initGenerator)(tree, { skipFormat: true });
|
|
43
46
|
tasks.push(initTask);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
tasks.push((0, ensure_dependencies_1.ensureDependencies)(tree, { uiFramework: schema.uiFramework }));
|
|
48
|
+
(0, edit_root_tsconfig_1.editRootTsConfig)(tree);
|
|
49
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
50
|
+
const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
|
|
51
|
+
? p === '@nx/storybook/plugin'
|
|
52
|
+
: p.plugin === '@nx/storybook/plugin');
|
|
53
|
+
const mainDir = !!nextConfigFilePath && projectType === 'application'
|
|
54
|
+
? 'components'
|
|
55
|
+
: 'src';
|
|
56
|
+
const usesVite = !!viteConfigFilePath || schema.uiFramework?.endsWith('-vite');
|
|
57
|
+
(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);
|
|
47
58
|
if (schema.uiFramework !== '@storybook/angular') {
|
|
48
59
|
(0, util_functions_1.createStorybookTsconfigFile)(tree, root, schema.uiFramework, (0, util_functions_1.projectIsRootProjectInStandaloneWorkspace)(root), mainDir);
|
|
49
60
|
}
|
|
@@ -53,14 +64,20 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
53
64
|
(0, util_functions_1.updateLintConfig)(tree, schema);
|
|
54
65
|
(0, util_functions_1.addBuildStorybookToCacheableOperations)(tree);
|
|
55
66
|
(0, util_functions_1.addStorybookToNamedInputs)(tree);
|
|
56
|
-
|
|
57
|
-
|
|
67
|
+
let devDeps = {};
|
|
68
|
+
if (!hasPlugin) {
|
|
69
|
+
if (schema.uiFramework === '@storybook/angular') {
|
|
70
|
+
(0, util_functions_1.addAngularStorybookTarget)(tree, schema.project, schema.interactionTests);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
(0, util_functions_1.addStorybookTarget)(tree, schema.project, schema.uiFramework, schema.interactionTests);
|
|
74
|
+
}
|
|
75
|
+
if (schema.configureStaticServe) {
|
|
76
|
+
(0, util_functions_1.addStaticTarget)(tree, schema);
|
|
77
|
+
}
|
|
58
78
|
}
|
|
59
79
|
else {
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
if (schema.configureStaticServe) {
|
|
63
|
-
(0, util_functions_1.addStaticTarget)(tree, schema);
|
|
80
|
+
devDeps['storybook'] = versions_1.storybookVersion;
|
|
64
81
|
}
|
|
65
82
|
// TODO(katerina): Nx 18 -> remove Cypress
|
|
66
83
|
if (schema.configureCypress) {
|
|
@@ -83,7 +100,6 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
83
100
|
devkit_1.logger.warn(`There is already an e2e project setup for ${schema.project}, called ${e2eProject}.`);
|
|
84
101
|
}
|
|
85
102
|
}
|
|
86
|
-
let devDeps = {};
|
|
87
103
|
if (schema.tsConfiguration) {
|
|
88
104
|
devDeps['ts-node'] = versions_1.tsNodeVersion;
|
|
89
105
|
}
|
|
@@ -103,8 +119,7 @@ async function configurationGenerator(tree, rawSchema) {
|
|
|
103
119
|
schema.uiFramework === '@storybook/react-webpack5') {
|
|
104
120
|
devDeps['core-js'] = versions_1.coreJsVersion;
|
|
105
121
|
}
|
|
106
|
-
if (schema.uiFramework
|
|
107
|
-
(!viteBuildTarget || !viteConfigFilePath)) {
|
|
122
|
+
if (schema.uiFramework?.endsWith('-vite') && !viteConfigFilePath) {
|
|
108
123
|
// This means that the user has selected a Vite framework
|
|
109
124
|
// but the project does not have Vite configuration.
|
|
110
125
|
// 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;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Tree } from '@nx/devkit';
|
|
2
2
|
import { StorybookConfigureSchema } from '../schema';
|
|
3
3
|
import { UiFramework } from '../../../utils/models';
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
4
|
+
export declare function addStorybookTarget(tree: Tree, projectName: string, uiFramework: UiFramework, interactionTests: boolean): void;
|
|
5
|
+
export declare function addAngularStorybookTarget(tree: Tree, projectName: string, interactionTests: boolean): void;
|
|
6
6
|
export declare function addStaticTarget(tree: Tree, opts: StorybookConfigureSchema): void;
|
|
7
7
|
export declare function createStorybookTsconfigFile(tree: Tree, projectRoot: string, uiFramework: UiFramework, isRootProject: boolean, mainDir: 'components' | 'src'): void;
|
|
8
8
|
export declare function editTsconfigBaseJson(tree: Tree): void;
|
|
@@ -25,5 +25,6 @@ export declare function projectIsRootProjectInStandaloneWorkspace(projectRoot: s
|
|
|
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
|
|
28
|
+
export declare function findViteConfig(tree: Tree, projectRoot: string): string | undefined;
|
|
29
|
+
export declare function findNextConfig(tree: Tree, projectRoot: string): string | undefined;
|
|
29
30
|
export declare function renameAndMoveOldTsConfig(projectRoot: string, pathToStorybookConfigFile: string, tree: Tree): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.renameAndMoveOldTsConfig = exports.
|
|
3
|
+
exports.renameAndMoveOldTsConfig = exports.findNextConfig = exports.findViteConfig = exports.getE2EProjectName = exports.rootFileIsTs = exports.workspaceHasRootProject = exports.projectIsRootProjectInStandaloneWorkspace = exports.addBuildStorybookToCacheableOperations = exports.getTsConfigPath = exports.createProjectStorybookDir = exports.addStorybookToNamedInputs = exports.normalizeSchema = exports.updateLintConfig = exports.configureTsSolutionConfig = exports.configureTsProjectConfig = exports.editTsconfigBaseJson = exports.createStorybookTsconfigFile = exports.addStaticTarget = exports.addAngularStorybookTarget = exports.addStorybookTarget = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
|
|
6
6
|
const eslint_1 = require("@nx/eslint");
|
|
@@ -10,7 +10,7 @@ const versions_1 = require("../../../utils/versions");
|
|
|
10
10
|
const eslint_file_1 = require("@nx/eslint/src/generators/utils/eslint-file");
|
|
11
11
|
const flat_config_1 = require("@nx/eslint/src/utils/flat-config");
|
|
12
12
|
const DEFAULT_PORT = 4400;
|
|
13
|
-
function
|
|
13
|
+
function addStorybookTarget(tree, projectName, uiFramework, interactionTests) {
|
|
14
14
|
if (uiFramework === '@storybook/react-native') {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
@@ -50,8 +50,8 @@ function addStorybookTask(tree, projectName, uiFramework, interactionTests) {
|
|
|
50
50
|
}
|
|
51
51
|
(0, devkit_1.updateProjectConfiguration)(tree, projectName, projectConfig);
|
|
52
52
|
}
|
|
53
|
-
exports.
|
|
54
|
-
function
|
|
53
|
+
exports.addStorybookTarget = addStorybookTarget;
|
|
54
|
+
function addAngularStorybookTarget(tree, projectName, interactionTests) {
|
|
55
55
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, projectName);
|
|
56
56
|
const { ngBuildTarget } = (0, utilities_1.findStorybookAndBuildTargetsAndCompiler)(projectConfig.targets);
|
|
57
57
|
projectConfig.targets['storybook'] = {
|
|
@@ -93,7 +93,7 @@ function addAngularStorybookTask(tree, projectName, interactionTests) {
|
|
|
93
93
|
}
|
|
94
94
|
(0, devkit_1.updateProjectConfiguration)(tree, projectName, projectConfig);
|
|
95
95
|
}
|
|
96
|
-
exports.
|
|
96
|
+
exports.addAngularStorybookTarget = addAngularStorybookTarget;
|
|
97
97
|
function addStaticTarget(tree, opts) {
|
|
98
98
|
const nrwlWeb = (0, devkit_1.ensurePackage)('@nx/web', versions_1.nxVersion);
|
|
99
99
|
nrwlWeb.webStaticServeGenerator(tree, {
|
|
@@ -479,16 +479,26 @@ async function getE2EProjectName(tree, mainProject) {
|
|
|
479
479
|
return e2eProject;
|
|
480
480
|
}
|
|
481
481
|
exports.getE2EProjectName = getE2EProjectName;
|
|
482
|
-
function
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
482
|
+
function findViteConfig(tree, projectRoot) {
|
|
483
|
+
const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
|
|
484
|
+
for (const ext of allowsExt) {
|
|
485
|
+
const viteConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, `vite.config.${ext}`);
|
|
486
|
+
if (tree.exists(viteConfigPath)) {
|
|
487
|
+
return viteConfigPath;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
exports.findViteConfig = findViteConfig;
|
|
492
|
+
function findNextConfig(tree, projectRoot) {
|
|
493
|
+
const allowsExt = ['js', 'mjs', 'cjs'];
|
|
494
|
+
for (const ext of allowsExt) {
|
|
495
|
+
const nextConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, `next.config.${ext}`);
|
|
496
|
+
if (tree.exists(nextConfigPath)) {
|
|
497
|
+
return nextConfigPath;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
490
500
|
}
|
|
491
|
-
exports.
|
|
501
|
+
exports.findNextConfig = findNextConfig;
|
|
492
502
|
function renameAndMoveOldTsConfig(projectRoot, pathToStorybookConfigFile, tree) {
|
|
493
503
|
if (pathToStorybookConfigFile && tree.exists(pathToStorybookConfigFile)) {
|
|
494
504
|
(0, devkit_1.updateJson)(tree, pathToStorybookConfigFile, (json) => {
|
|
@@ -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,88 +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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
}
|
|
33
|
-
devDependencies['@storybook/core-server'] = storybook7VersionToInstall;
|
|
34
|
-
devDependencies['@storybook/addon-essentials'] = storybook7VersionToInstall;
|
|
35
|
-
if (schema.uiFramework) {
|
|
36
|
-
if (schema.uiFramework === '@storybook/react-native') {
|
|
37
|
-
devDependencies['@storybook/react-native'] = versions_1.storybookReactNativeVersion;
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
devDependencies[schema.uiFramework] = storybook7VersionToInstall;
|
|
41
|
-
const isPnpm = (0, devkit_1.detectPackageManager)(host.root) === 'pnpm';
|
|
42
|
-
if (isPnpm) {
|
|
43
|
-
// If it's pnpm, it needs the framework without the builder
|
|
44
|
-
// as a dependency too (eg. @storybook/react)
|
|
45
|
-
const matchResult = schema.uiFramework?.match(/^@storybook\/(\w+)/);
|
|
46
|
-
const uiFrameworkWithoutBuilder = matchResult ? matchResult[0] : null;
|
|
47
|
-
if (uiFrameworkWithoutBuilder) {
|
|
48
|
-
devDependencies[uiFrameworkWithoutBuilder] =
|
|
49
|
-
storybook7VersionToInstall;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (schema.uiFramework === '@storybook/vue3-vite') {
|
|
54
|
-
if (!packageJson.dependencies['@storybook/vue3'] &&
|
|
55
|
-
!packageJson.devDependencies['@storybook/vue3']) {
|
|
56
|
-
devDependencies['@storybook/vue3'] = storybook7VersionToInstall;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (schema.uiFramework === '@storybook/angular') {
|
|
60
|
-
if (!packageJson.dependencies['@angular/forms'] &&
|
|
61
|
-
!packageJson.devDependencies['@angular/forms']) {
|
|
62
|
-
devDependencies['@angular/forms'] = '*';
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (schema.uiFramework === '@storybook/web-components-vite' ||
|
|
66
|
-
schema.uiFramework === '@storybook/web-components-webpack5') {
|
|
67
|
-
devDependencies['lit'] = versions_1.litVersion;
|
|
68
|
-
}
|
|
69
|
-
if (schema.uiFramework === '@storybook/react-native') {
|
|
70
|
-
devDependencies['@storybook/addon-ondevice-actions'] =
|
|
71
|
-
versions_1.storybookReactNativeVersion;
|
|
72
|
-
devDependencies['@storybook/addon-ondevice-backgrounds'] =
|
|
73
|
-
versions_1.storybookReactNativeVersion;
|
|
74
|
-
devDependencies['@storybook/addon-ondevice-controls'] =
|
|
75
|
-
versions_1.storybookReactNativeVersion;
|
|
76
|
-
devDependencies['@storybook/addon-ondevice-notes'] =
|
|
77
|
-
versions_1.storybookReactNativeVersion;
|
|
78
|
-
}
|
|
79
|
-
if (schema.uiFramework.endsWith('-vite')) {
|
|
80
|
-
if (!packageJson.dependencies['vite'] &&
|
|
81
|
-
!packageJson.devDependencies['vite']) {
|
|
82
|
-
devDependencies['vite'] = versions_1.viteVersion;
|
|
83
|
-
}
|
|
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
|
+
};
|
|
12
|
+
if (process.env.NX_PCV3 === 'true') {
|
|
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)();
|
|
84
18
|
}
|
|
19
|
+
devDependencies['storybook'] = storybook7VersionToInstall;
|
|
85
20
|
}
|
|
86
|
-
return (0, devkit_1.addDependenciesToPackageJson)(host,
|
|
21
|
+
return (0, devkit_1.addDependenciesToPackageJson)(host, {}, devDependencies);
|
|
87
22
|
}
|
|
88
23
|
function addCacheableOperation(tree) {
|
|
89
24
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
@@ -97,6 +32,7 @@ function addCacheableOperation(tree) {
|
|
|
97
32
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
98
33
|
}
|
|
99
34
|
function moveToDevDependencies(tree) {
|
|
35
|
+
let updated = false;
|
|
100
36
|
(0, devkit_1.updateJson)(tree, 'package.json', (packageJson) => {
|
|
101
37
|
packageJson.dependencies = packageJson.dependencies || {};
|
|
102
38
|
packageJson.devDependencies = packageJson.devDependencies || {};
|
|
@@ -104,49 +40,25 @@ function moveToDevDependencies(tree) {
|
|
|
104
40
|
packageJson.devDependencies['@nx/storybook'] =
|
|
105
41
|
packageJson.dependencies['@nx/storybook'];
|
|
106
42
|
delete packageJson.dependencies['@nx/storybook'];
|
|
43
|
+
updated = true;
|
|
107
44
|
}
|
|
108
45
|
return packageJson;
|
|
109
46
|
});
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* This is a temporary fix for Storybook to support TypeScript configuration files.
|
|
113
|
-
* The issue is that if there is a root tsconfig.json file, Storybook will use it, and
|
|
114
|
-
* ignore the tsconfig.json file in the .storybook folder. This results in module being set
|
|
115
|
-
* to esnext, and Storybook does not recognise the main.ts code as a module.
|
|
116
|
-
*/
|
|
117
|
-
function editRootTsConfig(tree) {
|
|
118
|
-
if (tree.exists('tsconfig.json')) {
|
|
119
|
-
(0, devkit_1.updateJson)(tree, 'tsconfig.json', (json) => {
|
|
120
|
-
if (json['ts-node']) {
|
|
121
|
-
json['ts-node'] = {
|
|
122
|
-
...json['ts-node'],
|
|
123
|
-
compilerOptions: {
|
|
124
|
-
...(json['ts-node'].compilerOptions ?? {}),
|
|
125
|
-
module: 'commonjs',
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
json['ts-node'] = {
|
|
131
|
-
compilerOptions: {
|
|
132
|
-
module: 'commonjs',
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
return json;
|
|
137
|
-
});
|
|
138
|
-
}
|
|
47
|
+
return updated ? () => (0, devkit_1.installPackagesTask)(tree) : () => { };
|
|
139
48
|
}
|
|
140
49
|
async function initGenerator(tree, schema) {
|
|
141
|
-
const tasks = [];
|
|
142
|
-
tasks.push(await (0, js_1.initGenerator)(tree, {
|
|
143
|
-
...schema,
|
|
144
|
-
skipFormat: true,
|
|
145
|
-
}));
|
|
146
|
-
tasks.push(checkDependenciesInstalled(tree, schema));
|
|
147
|
-
moveToDevDependencies(tree);
|
|
148
|
-
editRootTsConfig(tree);
|
|
149
50
|
addCacheableOperation(tree);
|
|
51
|
+
if (process.env.NX_PCV3 === 'true') {
|
|
52
|
+
(0, utilities_1.addPlugin)(tree);
|
|
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
|
+
}
|
|
150
62
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
151
63
|
}
|
|
152
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
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CreateDependencies, CreateNodes } from '@nx/devkit';
|
|
2
|
+
export interface StorybookPluginOptions {
|
|
3
|
+
buildStorybookTargetName?: string;
|
|
4
|
+
serveStorybookTargetName?: string;
|
|
5
|
+
staticStorybookTargetName?: string;
|
|
6
|
+
testStorybookTargetName?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const createDependencies: CreateDependencies;
|
|
9
|
+
export declare const createNodes: CreateNodes<StorybookPluginOptions>;
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodes = exports.createDependencies = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
|
|
9
|
+
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
10
|
+
const js_1 = require("@nx/js");
|
|
11
|
+
const tsquery_1 = require("@phenomnomnominal/tsquery");
|
|
12
|
+
const cachePath = (0, path_1.join)(cache_directory_1.projectGraphCacheDirectory, 'storybook.hash');
|
|
13
|
+
const targetsCache = (0, fs_1.existsSync)(cachePath) ? readTargetsCache() : {};
|
|
14
|
+
const calculatedTargets = {};
|
|
15
|
+
function readTargetsCache() {
|
|
16
|
+
return (0, devkit_1.readJsonFile)(cachePath);
|
|
17
|
+
}
|
|
18
|
+
function writeTargetsToCache(targets) {
|
|
19
|
+
(0, devkit_1.writeJsonFile)(cachePath, targets);
|
|
20
|
+
}
|
|
21
|
+
const createDependencies = () => {
|
|
22
|
+
writeTargetsToCache(calculatedTargets);
|
|
23
|
+
return [];
|
|
24
|
+
};
|
|
25
|
+
exports.createDependencies = createDependencies;
|
|
26
|
+
exports.createNodes = [
|
|
27
|
+
'**/.storybook/main.{js,ts,mjs,mts,cjs,cts}',
|
|
28
|
+
(configFilePath, options, context) => {
|
|
29
|
+
let projectRoot = '';
|
|
30
|
+
if (configFilePath.includes('/.storybook')) {
|
|
31
|
+
projectRoot = (0, path_1.dirname)(configFilePath).replace('/.storybook', '');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
projectRoot = (0, path_1.dirname)(configFilePath).replace('.storybook', '');
|
|
35
|
+
}
|
|
36
|
+
if (projectRoot === '') {
|
|
37
|
+
projectRoot = '.';
|
|
38
|
+
}
|
|
39
|
+
// Do not create a project if package.json and project.json isn't there.
|
|
40
|
+
const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
|
|
41
|
+
if (!siblingFiles.includes('package.json') &&
|
|
42
|
+
!siblingFiles.includes('project.json')) {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
options = normalizeOptions(options);
|
|
46
|
+
const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context, [
|
|
47
|
+
(0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)),
|
|
48
|
+
]);
|
|
49
|
+
const projectName = buildProjectName(projectRoot, context.workspaceRoot);
|
|
50
|
+
const targets = targetsCache[hash]
|
|
51
|
+
? targetsCache[hash]
|
|
52
|
+
: buildStorybookTargets(configFilePath, projectRoot, options, context, projectName);
|
|
53
|
+
calculatedTargets[hash] = targets;
|
|
54
|
+
const result = {
|
|
55
|
+
projects: {
|
|
56
|
+
[projectRoot]: {
|
|
57
|
+
root: projectRoot,
|
|
58
|
+
targets,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
// For root projects, the name is not inferred from root package.json, so we need to manually set it.
|
|
63
|
+
// TODO(jack): We should handle this in core and remove this workaround.
|
|
64
|
+
if (projectRoot === '.') {
|
|
65
|
+
result.projects[projectRoot]['name'] = projectName;
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
function buildStorybookTargets(configFilePath, projectRoot, options, context, projectName) {
|
|
71
|
+
const buildOutputs = getOutputs(projectRoot);
|
|
72
|
+
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
73
|
+
const storybookFramework = getStorybookConfig(configFilePath, context);
|
|
74
|
+
const frameworkIsAngular = storybookFramework === "'@storybook/angular'";
|
|
75
|
+
const targets = {};
|
|
76
|
+
targets[options.buildStorybookTargetName] = buildTarget(namedInputs, buildOutputs, configFilePath, projectRoot, frameworkIsAngular, projectName);
|
|
77
|
+
targets[options.serveStorybookTargetName] = serveTarget(configFilePath, frameworkIsAngular, projectName);
|
|
78
|
+
targets[options.testStorybookTargetName] = testTarget(configFilePath);
|
|
79
|
+
targets[options.staticStorybookTargetName] = serveStaticTarget(options, projectRoot);
|
|
80
|
+
return targets;
|
|
81
|
+
}
|
|
82
|
+
function buildTarget(namedInputs, outputs, configFilePath, projectRoot, frameworkIsAngular, projectName) {
|
|
83
|
+
const outputDir = (0, devkit_1.joinPathFragments)('dist/storybook', projectRoot);
|
|
84
|
+
let targetConfig;
|
|
85
|
+
if (frameworkIsAngular) {
|
|
86
|
+
targetConfig = {
|
|
87
|
+
executor: '@storybook/angular:build-storybook',
|
|
88
|
+
options: {
|
|
89
|
+
outputDir: `${outputDir}`,
|
|
90
|
+
configDir: `${(0, path_1.dirname)(configFilePath)}`,
|
|
91
|
+
browserTarget: `${projectName}:build-storybook`,
|
|
92
|
+
compodoc: false,
|
|
93
|
+
},
|
|
94
|
+
cache: true,
|
|
95
|
+
outputs,
|
|
96
|
+
inputs: [
|
|
97
|
+
...('production' in namedInputs
|
|
98
|
+
? ['production', '^production']
|
|
99
|
+
: ['default', '^default']),
|
|
100
|
+
{
|
|
101
|
+
externalDependencies: [
|
|
102
|
+
'storybook',
|
|
103
|
+
'@storybook/angular',
|
|
104
|
+
'@storybook/test-runner',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
targetConfig = {
|
|
112
|
+
command: `storybook build --config-dir ${(0, path_1.dirname)(configFilePath)} --output-dir ${outputDir}`,
|
|
113
|
+
cache: true,
|
|
114
|
+
outputs,
|
|
115
|
+
inputs: [
|
|
116
|
+
...('production' in namedInputs
|
|
117
|
+
? ['production', '^production']
|
|
118
|
+
: ['default', '^default']),
|
|
119
|
+
{
|
|
120
|
+
externalDependencies: ['storybook', '@storybook/test-runner'],
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return targetConfig;
|
|
126
|
+
}
|
|
127
|
+
function serveTarget(configFilePath, frameworkIsAngular, projectName) {
|
|
128
|
+
if (frameworkIsAngular) {
|
|
129
|
+
return {
|
|
130
|
+
executor: '@storybook/angular:start-storybook',
|
|
131
|
+
options: {
|
|
132
|
+
configDir: `${(0, path_1.dirname)(configFilePath)}`,
|
|
133
|
+
browserTarget: `${projectName}:build-storybook`,
|
|
134
|
+
compodoc: false,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return {
|
|
140
|
+
command: `storybook dev --config-dir ${(0, path_1.dirname)(configFilePath)}`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function testTarget(configFilePath) {
|
|
145
|
+
const targetConfig = {
|
|
146
|
+
command: `test-storybook --config-dir ${(0, path_1.dirname)(configFilePath)}`,
|
|
147
|
+
inputs: [
|
|
148
|
+
{
|
|
149
|
+
externalDependencies: ['storybook', '@storybook/test-runner'],
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
return targetConfig;
|
|
154
|
+
}
|
|
155
|
+
function serveStaticTarget(options, projectRoot) {
|
|
156
|
+
const targetConfig = {
|
|
157
|
+
executor: '@nx/web:file-server',
|
|
158
|
+
options: {
|
|
159
|
+
buildTarget: `${options.buildStorybookTargetName}`,
|
|
160
|
+
// TODO(katerina): need to read the output from CLI args
|
|
161
|
+
staticFilePath: (0, devkit_1.joinPathFragments)('dist/storybook', projectRoot),
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
return targetConfig;
|
|
165
|
+
}
|
|
166
|
+
function getStorybookConfig(configFilePath, context) {
|
|
167
|
+
const resolvedPath = (0, path_1.join)(context.workspaceRoot, configFilePath);
|
|
168
|
+
const mainTsJs = (0, fs_1.readFileSync)(resolvedPath, 'utf-8');
|
|
169
|
+
const importDeclarations = tsquery_1.tsquery.query(mainTsJs, 'ImportDeclaration:has(ImportSpecifier:has([text="StorybookConfig"]))')?.[0];
|
|
170
|
+
const storybookConfigImportPackage = tsquery_1.tsquery.query(importDeclarations, 'StringLiteral')?.[0];
|
|
171
|
+
let frameworkName;
|
|
172
|
+
if (storybookConfigImportPackage?.getText() === `'@storybook/core-common'`) {
|
|
173
|
+
const frameworkPropertyAssignment = tsquery_1.tsquery.query(mainTsJs, `PropertyAssignment:has(Identifier:has([text="framework"]))`)?.[0];
|
|
174
|
+
if (!frameworkPropertyAssignment) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const propertyAssignments = tsquery_1.tsquery.query(frameworkPropertyAssignment, `PropertyAssignment:has(Identifier:has([text="name"]))`);
|
|
178
|
+
const namePropertyAssignment = propertyAssignments?.find((expression) => {
|
|
179
|
+
return expression.getText().startsWith('name');
|
|
180
|
+
});
|
|
181
|
+
if (!namePropertyAssignment) {
|
|
182
|
+
const storybookConfigImportPackage = tsquery_1.tsquery.query(frameworkPropertyAssignment, 'StringLiteral')?.[0];
|
|
183
|
+
frameworkName = storybookConfigImportPackage?.getText();
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
frameworkName = tsquery_1.tsquery
|
|
187
|
+
.query(namePropertyAssignment, `StringLiteral`)?.[0]
|
|
188
|
+
?.getText();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
frameworkName = storybookConfigImportPackage?.getText();
|
|
193
|
+
}
|
|
194
|
+
return frameworkName;
|
|
195
|
+
}
|
|
196
|
+
function getOutputs(_projectRoot) {
|
|
197
|
+
// TODO(katerina): need to read the output from CLI args
|
|
198
|
+
// const outputPath = <output path as read from CLI>;
|
|
199
|
+
const normalizedOutputPath = normalizeOutputPath(undefined, _projectRoot);
|
|
200
|
+
const outputs = [normalizedOutputPath];
|
|
201
|
+
return outputs;
|
|
202
|
+
}
|
|
203
|
+
function normalizeOutputPath(outputPath, projectRoot) {
|
|
204
|
+
if (!outputPath) {
|
|
205
|
+
if (projectRoot === '.') {
|
|
206
|
+
return `{projectRoot}/dist/storybook`;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
return `{workspaceRoot}/dist/storybook/{projectRoot}`;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
if ((0, path_1.isAbsolute)(outputPath)) {
|
|
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
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function normalizeOptions(options) {
|
|
227
|
+
options ??= {};
|
|
228
|
+
options.buildStorybookTargetName = 'build-storybook';
|
|
229
|
+
options.serveStorybookTargetName = 'storybook';
|
|
230
|
+
options.testStorybookTargetName = 'test-storybook';
|
|
231
|
+
options.staticStorybookTargetName = 'static-storybook';
|
|
232
|
+
return options;
|
|
233
|
+
}
|
|
234
|
+
function buildProjectName(projectRoot, workspaceRoot) {
|
|
235
|
+
const packageJsonPath = (0, path_1.join)(workspaceRoot, projectRoot, 'package.json');
|
|
236
|
+
const projectJsonPath = (0, path_1.join)(workspaceRoot, projectRoot, 'project.json');
|
|
237
|
+
let name;
|
|
238
|
+
if ((0, fs_1.existsSync)(projectJsonPath)) {
|
|
239
|
+
const projectJson = (0, devkit_1.parseJson)((0, fs_1.readFileSync)(projectJsonPath, 'utf-8'));
|
|
240
|
+
name = projectJson.name;
|
|
241
|
+
}
|
|
242
|
+
else if ((0, fs_1.existsSync)(packageJsonPath)) {
|
|
243
|
+
const packageJson = (0, devkit_1.parseJson)((0, fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
244
|
+
name = packageJson.name;
|
|
245
|
+
}
|
|
246
|
+
return name ?? projectRoot;
|
|
247
|
+
}
|
package/src/utils/utilities.d.ts
CHANGED
|
@@ -40,3 +40,4 @@ export declare function findStorybookAndBuildTargetsAndCompiler(targets: {
|
|
|
40
40
|
export declare function isTheFileAStory(tree: Tree, path: string): boolean;
|
|
41
41
|
export declare function getTsSourceFile(host: Tree, path: string): ts.SourceFile;
|
|
42
42
|
export declare function pleaseUpgrade(): string;
|
|
43
|
+
export declare function addPlugin(tree: Tree): void;
|
package/src/utils/utilities.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pleaseUpgrade = exports.getTsSourceFile = exports.isTheFileAStory = exports.findStorybookAndBuildTargetsAndCompiler = exports.dedupe = exports.storybookConfigExistsCheck = exports.safeFileDelete = exports.getInstalledStorybookVersion = exports.storybookMajorVersion = exports.Constants = void 0;
|
|
3
|
+
exports.addPlugin = exports.pleaseUpgrade = exports.getTsSourceFile = exports.isTheFileAStory = exports.findStorybookAndBuildTargetsAndCompiler = exports.dedupe = exports.storybookConfigExistsCheck = exports.safeFileDelete = exports.getInstalledStorybookVersion = exports.storybookMajorVersion = exports.Constants = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
4
5
|
const fs_1 = require("fs");
|
|
5
6
|
const js_1 = require("@nx/js");
|
|
6
7
|
const ts = require("typescript");
|
|
@@ -222,3 +223,25 @@ function pleaseUpgrade() {
|
|
|
222
223
|
`;
|
|
223
224
|
}
|
|
224
225
|
exports.pleaseUpgrade = pleaseUpgrade;
|
|
226
|
+
function addPlugin(tree) {
|
|
227
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
228
|
+
nxJson.plugins ??= [];
|
|
229
|
+
for (const plugin of nxJson.plugins) {
|
|
230
|
+
if (typeof plugin === 'string'
|
|
231
|
+
? plugin === '@nx/storybook/plugin'
|
|
232
|
+
: plugin.plugin === '@nx/storybook/plugin') {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
nxJson.plugins.push({
|
|
237
|
+
plugin: '@nx/storybook/plugin',
|
|
238
|
+
options: {
|
|
239
|
+
buildStorybookTargetName: 'build-storybook',
|
|
240
|
+
serveStorybookTargetName: 'storybook',
|
|
241
|
+
testStorybookTargetName: 'test-storybook',
|
|
242
|
+
staticStorybookTargetName: 'static-storybook',
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
246
|
+
}
|
|
247
|
+
exports.addPlugin = addPlugin;
|