feat(storybook): version 7 generators (#14308)
This commit is contained in:
parent
3d5d97277b
commit
e5edcb84db
@ -5764,6 +5764,22 @@
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Storybook 7 setup guide",
|
||||
"path": "/packages/storybook/documents/storybook-7-setup",
|
||||
"id": "storybook-7-setup",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Migrate Storybook to version 7",
|
||||
"path": "/packages/storybook/documents/migrate-storybook-7",
|
||||
"id": "migrate-storybook-7",
|
||||
"isExternal": false,
|
||||
"children": [],
|
||||
"disableCollapsible": false
|
||||
},
|
||||
{
|
||||
"name": "Storybook best practices for making the most out of Nx",
|
||||
"path": "/packages/storybook/documents/best-practices",
|
||||
|
||||
@ -2390,6 +2390,28 @@
|
||||
"tags": [],
|
||||
"originalFilePath": "shared/packages/storybook/plugin-angular"
|
||||
},
|
||||
"/packages/storybook/documents/storybook-7-setup": {
|
||||
"id": "storybook-7-setup",
|
||||
"name": "Storybook 7 setup guide",
|
||||
"description": "The Nx Plugin for Storybook contains executors and generators for allowing your workspace to use the powerful Storybook integration testing & documenting capabilities.",
|
||||
"file": "generated/packages/storybook/documents/storybook-7-setup",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/packages/storybook/documents/storybook-7-setup",
|
||||
"tags": [],
|
||||
"originalFilePath": "shared/packages/storybook/storybook-7-setup"
|
||||
},
|
||||
"/packages/storybook/documents/migrate-storybook-7": {
|
||||
"id": "migrate-storybook-7",
|
||||
"name": "Migrate Storybook to version 7",
|
||||
"description": "The Nx Plugin for Storybook contains executors and generators for allowing your workspace to use the powerful Storybook integration testing & documenting capabilities.",
|
||||
"file": "generated/packages/storybook/documents/migrate-storybook-7",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "/packages/storybook/documents/migrate-storybook-7",
|
||||
"tags": [],
|
||||
"originalFilePath": "shared/packages/storybook/migrate-storybook-7"
|
||||
},
|
||||
"/packages/storybook/documents/best-practices": {
|
||||
"id": "best-practices",
|
||||
"name": "Storybook best practices for making the most out of Nx",
|
||||
|
||||
@ -2363,6 +2363,28 @@
|
||||
"tags": [],
|
||||
"originalFilePath": "shared/packages/storybook/plugin-angular"
|
||||
},
|
||||
{
|
||||
"id": "storybook-7-setup",
|
||||
"name": "Storybook 7 setup guide",
|
||||
"description": "The Nx Plugin for Storybook contains executors and generators for allowing your workspace to use the powerful Storybook integration testing & documenting capabilities.",
|
||||
"file": "generated/packages/storybook/documents/storybook-7-setup",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "storybook/documents/storybook-7-setup",
|
||||
"tags": [],
|
||||
"originalFilePath": "shared/packages/storybook/storybook-7-setup"
|
||||
},
|
||||
{
|
||||
"id": "migrate-storybook-7",
|
||||
"name": "Migrate Storybook to version 7",
|
||||
"description": "The Nx Plugin for Storybook contains executors and generators for allowing your workspace to use the powerful Storybook integration testing & documenting capabilities.",
|
||||
"file": "generated/packages/storybook/documents/migrate-storybook-7",
|
||||
"itemList": [],
|
||||
"isExternal": false,
|
||||
"path": "storybook/documents/migrate-storybook-7",
|
||||
"tags": [],
|
||||
"originalFilePath": "shared/packages/storybook/migrate-storybook-7"
|
||||
},
|
||||
{
|
||||
"id": "best-practices",
|
||||
"name": "Storybook best practices for making the most out of Nx",
|
||||
|
||||
@ -75,11 +75,16 @@
|
||||
"configureTestRunner": {
|
||||
"type": "boolean",
|
||||
"description": "Add a Storybook Test-Runner target."
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["name"],
|
||||
"examplesFile": "This generator will set up Storybook for your Angular project.\n\n```bash\nnx g @nrwl/angular:storybook-configuration project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for Angular overview page](/packages/storybook/documents/overview-angular#generate-storybook-configuration-for-an-angular-project).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to `configureCypress`. If you choose `yes`, a Cypress e2e app will be created (or configured) to run against the project's Storybook instance. You can read more about this in the [Storybook for Angular - Cypress section](/packages/storybook/documents/overview-angular#cypress-tests-for-stories).\n- Whether you want to `generateStories` for the components in your project. If you choose `yes`, a `.stories.ts` file will be generated next to each of your components in your project.\n- Whether you want to `generateCypressSpecs`. If you choose `yes`, a test file is going to be generated in the project's Cypress e2e app for each of your components.\n- Whether you want to `configureTestRunner`. If you choose `yes`, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/react/writing-tests/test-runner).\n\nYou must provide a `name` for the generator to work.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Generate Storybook configuration using TypeScript\n\n```bash\nnx g @nrwl/angular:storybook-configuration ui --tsConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory).\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nrwl/angular:storybook-configuration ui --generateStories=true --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts\n```\n\nThis will generate a Storybook configuration for the `ui` project and generate stories for all components in the `libs/ui/src/lib` directory, except for the ones in the `libs/ui/src/not-stories` directory, and the ones in the `apps/my-app` directory that end with `.something.ts`, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n",
|
||||
"examplesFile": "This generator will set up Storybook for your Angular project.\n\n```bash\nnx g @nrwl/angular:storybook-configuration project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for Angular overview page](/packages/storybook/documents/overview-angular#generate-storybook-configuration-for-an-angular-project).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to `configureCypress`. If you choose `yes`, a Cypress e2e app will be created (or configured) to run against the project's Storybook instance. You can read more about this in the [Storybook for Angular - Cypress section](/packages/storybook/documents/overview-angular#cypress-tests-for-stories).\n- Whether you want to `generateStories` for the components in your project. If you choose `yes`, a `.stories.ts` file will be generated next to each of your components in your project.\n- Whether you want to `generateCypressSpecs`. If you choose `yes`, a test file is going to be generated in the project's Cypress e2e app for each of your components.\n- Whether you want to `configureTestRunner`. If you choose `yes`, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/react/writing-tests/test-runner).\n\nYou must provide a `name` for the generator to work.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Generate Storybook configuration using TypeScript\n\n```bash\nnx g @nrwl/angular:storybook-configuration ui --tsConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory).\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nrwl/angular:storybook-configuration ui --generateStories=true --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts\n```\n\nThis will generate a Storybook configuration for the `ui` project and generate stories for all components in the `libs/ui/src/lib` directory, except for the ones in the `libs/ui/src/not-stories` directory, and the ones in the `apps/my-app` directory that end with `.something.ts`, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n\n### Generate Storybook configuration for Storybook version 7\n\n```bash\nnx g @nrwl/angular:storybook-configuration ui --storybook7betaConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using Storybook version 7. It will install the Storybook version 7 dependencies and configure the Storybook configuration files (the files inside the `.storybook` directory) to use Storybook version 7. You can read more about Storybook 7 Nx support in the [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).\n",
|
||||
"presets": []
|
||||
},
|
||||
"description": "Adds Storybook configuration to a project.",
|
||||
|
||||
@ -83,10 +83,16 @@
|
||||
"description": "The Storybook builder to use.",
|
||||
"enum": ["vite", "webpack"],
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "important"
|
||||
}
|
||||
},
|
||||
"required": ["name"],
|
||||
"examplesFile": "This generator will set up Storybook for your React project.\n\n```bash\nnx g @nrwl/react:storybook-configuration project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for React overview page](/packages/storybook/documents/overview-react#generate-storybook-configuration-for-an-react-project).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to `configureCypress`. If you choose `yes`, a Cypress e2e app will be created (or configured) to run against the project's Storybook instance. You can read more about this in the [Storybook for React - Cypress section](/packages/storybook/documents/overview-react#cypress-tests-for-stories).\n- Whether you want to `generateStories` for the components in your project. If you choose `yes`, a `.stories.ts` file will be generated next to each of your components in your project.\n- Whether you want to `generateCypressSpecs`. If you choose `yes`, a test file is going to be generated in the project's Cypress e2e app for each of your components.\n- Whether you want to `configureTestRunner`. If you choose `yes`, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/react/writing-tests/test-runner).\n\nYou must provide a `name` for the generator to work.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Generate Storybook configuration using TypeScript\n\n```bash\nnx g @nrwl/react:storybook-configuration ui --tsConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory).\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nrwl/react:storybook-configuration ui --generateStories=true --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts\n```\n\nThis will generate a Storybook configuration for the `ui` project and generate stories for all components in the `libs/ui/src/lib` directory, except for the ones in the `libs/ui/src/not-stories` directory, and the ones in the `apps/my-app` directory that end with `.something.ts`, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n\n### Generate stories using JavaScript instead of TypeScript\n\n```bash\nnx g @nrwl/react:storybook-configuration ui --generateStories=true --js=true\n```\n\nThis will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.\n",
|
||||
"examplesFile": "This generator will set up Storybook for your **React** project. You can also use this generator to generate Storybook configuration for your **Next.js** project.\n\n```bash\nnx g @nrwl/react:storybook-configuration project-name\n```\n\nYou can read more about how this generator works, in the [Storybook for React overview page](/packages/storybook/documents/overview-react#generate-storybook-configuration-for-an-react-project).\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- Whether you want to `configureCypress`. If you choose `yes`, a Cypress e2e app will be created (or configured) to run against the project's Storybook instance. You can read more about this in the [Storybook for React - Cypress section](/packages/storybook/documents/overview-react#cypress-tests-for-stories).\n- Whether you want to `generateStories` for the components in your project. If you choose `yes`, a `.stories.ts` file will be generated next to each of your components in your project.\n- Whether you want to `generateCypressSpecs`. If you choose `yes`, a test file is going to be generated in the project's Cypress e2e app for each of your components.\n- Whether you want to `configureTestRunner`. If you choose `yes`, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/react/writing-tests/test-runner).\n\nYou must provide a `name` for the generator to work.\n\nThere are a number of other options available. Let's take a look at some examples.\n\n## Examples\n\n### Generate Storybook configuration using TypeScript\n\n```bash\nnx g @nrwl/react:storybook-configuration ui --tsConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory).\n\n### Ignore certain paths when generating stories\n\n```bash\nnx g @nrwl/react:storybook-configuration ui --generateStories=true --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts\n```\n\nThis will generate a Storybook configuration for the `ui` project and generate stories for all components in the `libs/ui/src/lib` directory, except for the ones in the `libs/ui/src/not-stories` directory, and the ones in the `apps/my-app` directory that end with `.something.ts`, and also for components that their file name is of the pattern `*.other.*`.\n\nThis is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.\n\n### Generate stories using JavaScript instead of TypeScript\n\n```bash\nnx g @nrwl/react:storybook-configuration ui --generateStories=true --js=true\n```\n\nThis will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.\n\n### Generate Storybook configuration for Storybook version 7\n\n```bash\nnx g @nrwl/react:storybook-configuration ui --storybook7betaConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using Storybook version 7. It will install the Storybook version 7 dependencies and configure the Storybook configuration files (the files inside the `.storybook` directory) to use Storybook version 7. You can read more about Storybook 7 Nx support in the [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).\n",
|
||||
"presets": []
|
||||
},
|
||||
"description": "Set up storybook for a React app or library.",
|
||||
|
||||
@ -0,0 +1,264 @@
|
||||
# Migrate to Storybook to version 7
|
||||
|
||||
{% callout type="warning" title="Storybook 7 is in beta" %}
|
||||
[Storybook version 7 is still in beta](https://storybook.js.org/blog/7-0-beta/). Things are evolving dynamically, so it would be better to _avoid using in production_. If you want to use the stable, [6.5 version](https://storybook.js.org/releases/6.5), please go to the [Storybook plugin overview guide](/packages/storybook) to get started.
|
||||
{% /callout %}
|
||||
|
||||
{% callout type="info" title="Setting up Storybook 7 in a new workspace" %}
|
||||
For settin up Storybook version 7 in a new Nx workspace, or a workspace that does NOT already have Storybook configured already, please refer to our [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).
|
||||
{% /callout %}
|
||||
|
||||
Storybook 7 is a major release that brings a lot of new features and improvements. You can read more about it in the [Storybook 7 beta announcement blog post](https://storybook.js.org/blog/7-0-beta/). Apart from the new features and improvements it introduces, it also brings some breaking changes. You can read more about them in the [Storybook 7 migration docs](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-65x-to-700) and the [Storybook 7 migration guide](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937). Do note that _version 7 is still in beta_, and things are evolving dynamically, so it would be better to _avoid using in production_.
|
||||
|
||||
You can now migrate your existing Nx workspace with Storybook configuration to use Storybook version 7. This guide will show you how to do that.
|
||||
|
||||
## Use the Storybook CLI to upgrade
|
||||
|
||||
You can take advantage of the Storybook CLI to automatically migrate some settings of your Storybook setup. For a full guide to migration using the Storybook CLI, please refer to the [Storybook 7 migration guide](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937).
|
||||
|
||||
The Storybook migration scripts do not work perfectly with Nx, however we can use them to get the latest beta versions of our packages, remove some unused packages, and get a hint of some settings that we will need to change manually, eventually.
|
||||
|
||||
{% callout type="warning" title="Don't use in production" %}
|
||||
Please take extra care when migrating your existing Storybook setup to version 7. Do not use in production, since it's still in beta.
|
||||
{% /callout %}
|
||||
|
||||
Let's see the steps we can make to migrate our Storybook setup to version 7.
|
||||
|
||||
### 1. Run the `upgrade` command of the Storybook CLI
|
||||
|
||||
```bash
|
||||
npx storybook@next upgrade --prerelease
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
- Upgrade your dependencies to the latest prerelease version
|
||||
- Run a number of migration scripts (code generators and modifiers) - upon approval
|
||||
|
||||
For more info, see [here](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937).
|
||||
|
||||
### 2. Click yes to the automigration prompts
|
||||
|
||||
The Storybook CLI will prompt you to run some code generators and modifiers.
|
||||
|
||||
Click `yes` to the following:
|
||||
|
||||
- `mainjsFramework`: It will add the `framework` field in your root `.storybook/main.js|ts` file. We are going to delete it since it's not needed in the root file, but it's handy to have it ready to copy. Also, it shows you an indication of what it looks like.
|
||||
- `eslintPlugin`: installs the `eslint-plugin-storybook`
|
||||
- `storybook-binary`: installs Storybook's `storybook` binary
|
||||
- `newFrameworks`: removed unused dependencies (eg. `@storybook/builder-webpack5`, `@storybook/manager-webpack5`, `@storybook/builder-vite`)
|
||||
|
||||
Click `no` to the following:
|
||||
|
||||
- `autodocsTrue`: we don't need it and it can potentially cause issues with missing dependencies
|
||||
|
||||
### 3. Restore the root `.storybook/main.js|ts` file
|
||||
|
||||
You will have noticed that the Storybook automigrator added the `framework` option to your root `.storybook/main.js|ts` file. Let's remove that, along with the `autodocs` option.
|
||||
|
||||
So, remove:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
from your root `.storybook/main.js|ts` file.
|
||||
|
||||
### 3. Edit all the project-level `.storybook/main.js|ts` files
|
||||
|
||||
Find all your project-level `.storybook/main.js|ts` files and edit them to add the `framework` option. While you are at it, remove the `builder` from `core` options.
|
||||
|
||||
#### Remove builder
|
||||
|
||||
In your project-level `.storybook/main.js|ts` files, remove the `builder` from `core` options.
|
||||
|
||||
Your core options most probably look like this:
|
||||
|
||||
```ts
|
||||
core: { ...rootMain.core, builder: '@storybook/builder-vite' },
|
||||
```
|
||||
|
||||
You must remove the `builder`, or you can also delete the `core` object entirely.
|
||||
|
||||
#### Add framework
|
||||
|
||||
Choose the `framework` carefully. The list of available frameworks is:
|
||||
|
||||
- `@storybook/angular`
|
||||
- `@storybook/html-webpack5`
|
||||
- `@storybook/nextjs`
|
||||
- `@storybook/preact-webpack5`
|
||||
- `@storybook/react-webpack5`
|
||||
- `@storybook/react-vite`
|
||||
- `@storybook/server-webpack5`
|
||||
- `@storybook/svelte-webpack5`
|
||||
- `@storybook/svelte-vite`
|
||||
- `@storybook/sveltekit`
|
||||
- `@storybook/vue-webpack5`
|
||||
- `@storybook/vue-vite`
|
||||
- `@storybook/vue3-webpack5`
|
||||
- `@storybook/vue3-vite`
|
||||
- `@storybook/web-components-webpack5`
|
||||
- `@storybook/web-components-vite`
|
||||
|
||||
#### For Angular projects
|
||||
|
||||
Choose the `@storybook/angular` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For React projects using `'@storybook/builder-vite'`
|
||||
|
||||
Choose the `@storybook/react-vite` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For React projects using `'@storybook/builder-webpack5'`
|
||||
|
||||
Choose the `@storybook/react-webpack5` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/react-webpack5',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For Next.js projects
|
||||
|
||||
Choose the `@storybook/nextjs` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/nextjs',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For Web Components projects using `'@storybook/builder-vite'`
|
||||
|
||||
Choose the `@storybook/web-components-vite` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/web-components-vite',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For Web Components projects using `'@storybook/builder-webpack5'`
|
||||
|
||||
Choose the `@storybook/web-components-webpack5` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/web-components-webpack5',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For the rest of the projects
|
||||
|
||||
You can easily find the correct framework by looking at the `builder` option in your project-level `.storybook/main.js|ts` file.
|
||||
|
||||
#### Resulting project-level `.storybook/main.js|ts` file
|
||||
|
||||
Here is an example of a project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
const rootMain = require('../../../.storybook/main');
|
||||
|
||||
module.exports = {
|
||||
...rootMain,
|
||||
stories: [
|
||||
...rootMain.stories,
|
||||
'../src/app/**/*.stories.mdx',
|
||||
'../src/app/**/*.stories.@(js|jsx|ts|tsx)',
|
||||
],
|
||||
addons: [...rootMain.addons],
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 4. For Vite.js projects
|
||||
|
||||
Make sure to add the `viteFinal` option to your project-level `.storybook/main.js|ts` files.
|
||||
|
||||
```ts
|
||||
async viteFinal(config, { configType }) {
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
viteTsConfigPaths({
|
||||
root: '<PATH_TO_PROJECT_ROOT>',
|
||||
}),
|
||||
],
|
||||
});
|
||||
},
|
||||
```
|
||||
|
||||
This will take care of any path resolution issues.
|
||||
|
||||
An example of a project-level `.storybook/main.js|ts` file for a Vite.js project:
|
||||
|
||||
```ts
|
||||
const { mergeConfig } = require('vite');
|
||||
const viteTsConfigPaths = require('vite-tsconfig-paths').default;
|
||||
const rootMain = require('../../../.storybook/main');
|
||||
|
||||
module.exports = {
|
||||
...rootMain,
|
||||
stories: [
|
||||
...rootMain.stories,
|
||||
'../src/app/**/*.stories.mdx',
|
||||
'../src/app/**/*.stories.@(js|jsx|ts|tsx)',
|
||||
],
|
||||
addons: [...rootMain.addons],
|
||||
async viteFinal(config, { configType }) {
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
viteTsConfigPaths({
|
||||
root: '../../../',
|
||||
}),
|
||||
],
|
||||
});
|
||||
},
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Use Storybook 7 beta
|
||||
|
||||
You can now use Storybook 7 beta! 🎉
|
||||
|
||||
```bash
|
||||
npx nx build-storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```bash
|
||||
npx nx storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
## Report any issues and bugs
|
||||
|
||||
Since this is a beta version, there are bound to be some issues and bugs. Please report any issues and bugs you find [on the Nx GitHub page](https://github.com/nrwl/nx/issues/new/choose) or on the [Storybook GitHub page](https://github.com/storybookjs/storybook/issues/new/choose).
|
||||
@ -2,14 +2,31 @@
|
||||
|
||||
This guide will briefly walk you through using Storybook within an Nx workspace.
|
||||
|
||||
{% callout type="info" title="Try out Storybook 7 beta" %}
|
||||
[Storybook version 7 is still in beta](https://storybook.js.org/blog/7-0-beta/). However, you can try it out with Nx by following the instructions in the [Storybook 7 setup](/packages/storybook/documents/storybook-7-setup) guide.
|
||||
{% /callout %}
|
||||
|
||||
## Setting Up Storybook
|
||||
|
||||
### Add the Storybook plugin
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="yarn" %}
|
||||
|
||||
```shell
|
||||
yarn add --dev @nrwl/storybook
|
||||
yarn add -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% tab label="npm" %}
|
||||
|
||||
```shell
|
||||
npm install -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
## Using Storybook
|
||||
|
||||
### Generating Storybook Configuration
|
||||
|
||||
116
docs/generated/packages/storybook/documents/storybook-7-setup.md
Normal file
116
docs/generated/packages/storybook/documents/storybook-7-setup.md
Normal file
@ -0,0 +1,116 @@
|
||||
# Storybook 7 is here - and Nx is ready
|
||||
|
||||
{% callout type="warning" title="Storybook 7 is in beta" %}
|
||||
[Storybook version 7 is still in beta](https://storybook.js.org/blog/7-0-beta/). Things are evolving dynamically, so it would be better to _avoid using in production_. If you want to use the stable, [6.5 version](https://storybook.js.org/releases/6.5), please go to the [Storybook plugin overview guide](/packages/storybook) to get started.
|
||||
{% /callout %}
|
||||
|
||||
Storybook 7 is a major release that brings a lot of new features and improvements. You can read more about it in the [Storybook 7 beta announcement blog post](https://storybook.js.org/blog/7-0-beta/). Apart from the new features and improvements it introduces, it also brings some breaking changes. You can read more about them in the [Storybook 7 migration docs](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-65x-to-700) and the [Storybook 7 migration guide](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937). Do note that _version 7 is still in beta_, and things are evolving dynamically, so it would be better to _avoid using in production_.
|
||||
|
||||
Nx provides new generators that allow you to generate Storybook 7 configuration for your projects, by installing the correct dependencies, and creating the corresponding version 7 configuration files.
|
||||
|
||||
So, let's see how to get started with Storybook 7 and Nx.
|
||||
|
||||
## Setting Up Storybook 7 in a _new_ Nx Workspace
|
||||
|
||||
In this guide we will see how to set up Storybook version 7 in a new Nx workspace, or a workspace that does NOT already have Storybook configured.
|
||||
|
||||
{% callout type="warning" title="Migrating existing Storybook configuration" %}
|
||||
For migrating your existing Nx workspace with existing Storybook configuration to use Storybook version 7, please refer to our [Storybook 7 migration guide](/packages/storybook/documents/migrate-storybook-7).
|
||||
{% /callout %}
|
||||
|
||||
### Add the Storybook plugin
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="yarn" %}
|
||||
|
||||
```shell
|
||||
yarn add -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% tab label="npm" %}
|
||||
|
||||
```shell
|
||||
npm install -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
## Using Storybook
|
||||
|
||||
### Generating Storybook Configuration
|
||||
|
||||
You can generate Storybook configuration for an individual project with this command:
|
||||
|
||||
```shell
|
||||
nx g @nrwl/storybook:configuration project-name --storybook7betaConfiguration --storybook7UiFramework=@storybook/react-webpack5
|
||||
```
|
||||
|
||||
In the field `storybook7UiFramework` you must choose one of the following Storybook frameworks:
|
||||
|
||||
- `@storybook/angular`
|
||||
- `@storybook/html-webpack5`
|
||||
- `@storybook/nextjs`
|
||||
- `@storybook/preact-webpack5`
|
||||
- `@storybook/react-webpack5`
|
||||
- `@storybook/react-vite`
|
||||
- `@storybook/server-webpack5`
|
||||
- `@storybook/svelte-webpack5`
|
||||
- `@storybook/svelte-vite`
|
||||
- `@storybook/sveltekit`
|
||||
- `@storybook/vue-webpack5`
|
||||
- `@storybook/vue-vite`
|
||||
- `@storybook/vue3-webpack5`
|
||||
- `@storybook/vue3-vite`
|
||||
- `@storybook/web-components-webpack5`
|
||||
- `@storybook/web-components-vite`
|
||||
|
||||
In Storybook 7, [the `framework` field in `.storybook/main.js|ts` is mandatory](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-field-mandatory). You must choose one of the above frameworks when setting up your application.
|
||||
|
||||
If you are using one of the framework-specific generators (e.g. [`@nrwl/angular:storybook-configuration`](/packages/angular/generators/storybook-configuration), or [`@nrwl/react:storybook-configuration`](/packages/react/generators/storybook-configuration) for React and Nextjs projects, or [`@nrwl/react-native:storybook-configuration`](<(/packages/react-native/generators/storybook-configuration)>)), the generator will automatically choose the correct framework for you.
|
||||
|
||||
Choosing one of these frameworks will have the following effects on your workspace:
|
||||
|
||||
1. Nx will install all the required Storybook packages that go with it.
|
||||
|
||||
2. Nx will generate a root `.storybook` folder and a project-level `.storybook` folder (located under `libs/your-project/.storybook` or `apps/your-project/.storybook`) containing the essential configuration files for Storybook.
|
||||
|
||||
3. If you are working on an Angular, a React or a React Native project (and you choose `@storybook/angular`, `@storybook/react` or `@storybook/react-native`) the Nx generator will also generate stories for all the components in your project.
|
||||
|
||||
4. Nx will create new `targets` in your project's `project.json`, called `storybook` and `build-storybook`, containing all the necessary configuration to serve and build Storybook.
|
||||
|
||||
5. Nx will generate a new Cypress e2e app for your project (if there isn't one already) to run against the Storybook instance.
|
||||
|
||||
### Changes from the v6.5 Storybook configuration
|
||||
|
||||
The Storybook configuration generated by Nx for Storybook 7 is very similar to the one generated for Storybook 6.5. Here are the new things that you should expect to see:
|
||||
|
||||
#### Changes in `.storybook/main.js|ts` file
|
||||
|
||||
- No longer set the `core` field which contains the `builder` option.
|
||||
- The `framework` field is now mandatory, and it "replaces" the `builder` configuration. You can read more [in the Storybook docs](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#mainjs-framework-field).
|
||||
- Nx no longer adds the `webpackFinal` field to the `.storybook/main.js|ts` files. This is just for the sake of simplicity. You can still edit your webpack configuration by using the `webpackFinal` field, just as you can edit your Vite configuration by using the `viteFinal` field. You can read more about how to customize your webpack configuration [in the Storybook webpack docs](https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config), and you can read more about how to customize your Vite configuration [in the Storybook Vite docs](https://storybook.js.org/docs/react/builders/vite#configuration).
|
||||
|
||||
#### Changes in the `storybook` and `build-storybook` targets
|
||||
|
||||
- The `uiFramework` field is not needed any more, thus it is not set. Nx was using the `uiFramework` field to load any framework specific options for the Storybook builder. This is no longer needed, since the `framework` set in `.storybook/main.js|ts` takes care of that.
|
||||
- More options from the Storybook CLI are now exposed in the executors. You can see these in the [`@nrwl/storybook:storybook`](/packages/storybook/executors/storybook) and [`@nrwl/storybook:build`](/packages/storybook/executors/build) executor schemas. You can read more about these options in the [Storybook 7 CLI docs](https://storybook.js.org/docs/7.0/react/api/cli-options). If there's an option you need to pass but it's not in the executor schema, you can always pass it, since the executors are just passing the options to the Storybook CLI.
|
||||
|
||||
## Use Storybook 7 beta
|
||||
|
||||
You can now use Storybook 7 beta! 🎉
|
||||
|
||||
```bash
|
||||
npx nx build-storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```bash
|
||||
npx nx storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
## Report any issues and bugs
|
||||
|
||||
Since this is a beta version, there are bound to be some issues and bugs. Please report any issues and bugs you find [on the Nx GitHub page](https://github.com/nrwl/nx/issues/new/choose) or on the [Storybook GitHub page](https://github.com/storybookjs/storybook/issues/new/choose).
|
||||
@ -76,10 +76,38 @@
|
||||
"x-prompt": "Which Storybook builder do you want to use?",
|
||||
"default": "webpack",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7UiFramework": {
|
||||
"type": "string",
|
||||
"description": "Storybook UI Framework to use.",
|
||||
"enum": [
|
||||
"@storybook/angular",
|
||||
"@storybook/html-webpack5",
|
||||
"@storybook/nextjs",
|
||||
"@storybook/preact-webpack5",
|
||||
"@storybook/react-webpack5",
|
||||
"@storybook/react-vite",
|
||||
"@storybook/server-webpack5",
|
||||
"@storybook/svelte-webpack5",
|
||||
"@storybook/svelte-vite",
|
||||
"@storybook/sveltekit",
|
||||
"@storybook/vue-webpack5",
|
||||
"@storybook/vue-vite",
|
||||
"@storybook/vue3-webpack5",
|
||||
"@storybook/vue3-vite",
|
||||
"@storybook/web-components-webpack5",
|
||||
"@storybook/web-components-vite"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["name"],
|
||||
"examplesFile": "This is a framework-agnostic generator for setting up Storybook configuration for a project.\n\n```bash\nnx g @nrwl/storybook:configuration\n```\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- The `uiFramework` you want to use. Supported values are: `\"@storybook/angular\"`, `\"@storybook/react\"`, `\"@storybook/react-native\"`, `\"@storybook/html\"`, `\"@storybook/web-components\"`, `\"@storybook/vue\"`, `\"@storybook/vue3\"` and `\"@storybook/svelte\"`.\n- Whether you want to `configureCypress`. If you choose `yes`, a Cypress e2e app will be created (or configured) to run against the project's Storybook instance.\n- Whether you want to `configureTestRunner`. If you choose `yes`, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/react/writing-tests/test-runner).\n\nYou must provide a `name` and a `uiFramework` for the generator to work.\n\nYou can read more about how this generator works, in the [Storybook package overview page](https://nx.dev/packages/storybook#generating-storybook-configuration).\n\nIf you are using Angular, React, React Native or Next.js in your project, it's best to use the framework specific generator:\n\n- [React Storybook Configuration Generator](/packages/react/generators/storybook-configuration) (React and Next.js projects)\n\n- [Angular Storybook Configuration Generator](/packages/angular/generators/storybook-configuration)\n\n- [React Native Storybook Configuration Generator](/packages/react-native/generators/storybook-configuration)\n\n## Examples\n\n### Generate Storybook configuration using TypeScript\n\n```bash\nnx g @nrwl/storybook:configuration ui --uiFramework=@storybook/web-components --tsConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory).\n",
|
||||
"examplesFile": "This is a framework-agnostic generator for setting up Storybook configuration for a project.\n\n```bash\nnx g @nrwl/storybook:configuration\n```\n\nWhen running this generator, you will be prompted to provide the following:\n\n- The `name` of the project you want to generate the configuration for.\n- The `uiFramework` you want to use. Supported values are: `\"@storybook/angular\"`, `\"@storybook/react\"`, `\"@storybook/react-native\"`, `\"@storybook/html\"`, `\"@storybook/web-components\"`, `\"@storybook/vue\"`, `\"@storybook/vue3\"` and `\"@storybook/svelte\"`.\n- Whether you want to `configureCypress`. If you choose `yes`, a Cypress e2e app will be created (or configured) to run against the project's Storybook instance.\n- Whether you want to `configureTestRunner`. If you choose `yes`, a `test-storybook` target will be generated in your project's `project.json`, with a command to invoke the [Storybook `test-runner`](https://storybook.js.org/docs/react/writing-tests/test-runner).\n\nYou must provide a `name` and a `uiFramework` for the generator to work.\n\nYou can read more about how this generator works, in the [Storybook package overview page](https://nx.dev/packages/storybook#generating-storybook-configuration).\n\nIf you are using Angular, React, React Native or Next.js in your project, it's best to use the framework specific generator:\n\n- [React Storybook Configuration Generator](/packages/react/generators/storybook-configuration) (React and Next.js projects)\n\n- [Angular Storybook Configuration Generator](/packages/angular/generators/storybook-configuration)\n\n- [React Native Storybook Configuration Generator](/packages/react-native/generators/storybook-configuration)\n\n## Examples\n\n### Generate Storybook configuration using TypeScript\n\n```bash\nnx g @nrwl/storybook:configuration ui --uiFramework=@storybook/web-components --tsConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory).\n\n### Generate Storybook configuration for Storybook version 7\n\n```bash\nnx g @nrwl/storybook:configuration ui --uiFramework=@storybook/react --storybook7betaConfiguration=true\n```\n\nOR\n\n```bash\nnx g @nrwl/storybook:configuration ui --storybook7UiFramework=@storybook/react-vite --storybook7betaConfiguration=true\n```\n\nThis will generate a Storybook configuration for the `ui` project using Storybook version 7. It will install the Storybook version 7 dependencies and configure the Storybook configuration files (the files inside the `.storybook` directory) to use Storybook version 7. You can read more about Storybook 7 Nx support in the [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).\n",
|
||||
"presets": []
|
||||
},
|
||||
"description": "Add Storybook configuration to a UI library or an application.",
|
||||
|
||||
@ -13,6 +13,21 @@
|
||||
"description": "Storybook UI Framework to use.",
|
||||
"enum": [
|
||||
"@storybook/angular",
|
||||
"@storybook/html-webpack5",
|
||||
"@storybook/nextjs",
|
||||
"@storybook/preact-webpack5",
|
||||
"@storybook/react-webpack5",
|
||||
"@storybook/react-vite",
|
||||
"@storybook/server-webpack5",
|
||||
"@storybook/svelte-webpack5",
|
||||
"@storybook/svelte-vite",
|
||||
"@storybook/sveltekit",
|
||||
"@storybook/vue-webpack5",
|
||||
"@storybook/vue-vite",
|
||||
"@storybook/vue3-webpack5",
|
||||
"@storybook/vue3-vite",
|
||||
"@storybook/web-components-webpack5",
|
||||
"@storybook/web-components-vite",
|
||||
"@storybook/react",
|
||||
"@storybook/html",
|
||||
"@storybook/web-components",
|
||||
@ -31,6 +46,12 @@
|
||||
"x-prompt": "Which bundler do you want to use?",
|
||||
"default": "webpack",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "important"
|
||||
}
|
||||
},
|
||||
"presets": []
|
||||
|
||||
@ -1664,6 +1664,16 @@
|
||||
"name": "Set up Storybook for Angular Projects",
|
||||
"file": "shared/packages/storybook/plugin-angular"
|
||||
},
|
||||
{
|
||||
"id": "storybook-7-setup",
|
||||
"name": "Storybook 7 setup guide",
|
||||
"file": "shared/packages/storybook/storybook-7-setup"
|
||||
},
|
||||
{
|
||||
"id": "migrate-storybook-7",
|
||||
"name": "Migrate Storybook to version 7",
|
||||
"file": "shared/packages/storybook/migrate-storybook-7"
|
||||
},
|
||||
{
|
||||
"id": "best-practices",
|
||||
"name": "Storybook best practices for making the most out of Nx",
|
||||
|
||||
264
docs/shared/packages/storybook/migrate-storybook-7.md
Normal file
264
docs/shared/packages/storybook/migrate-storybook-7.md
Normal file
@ -0,0 +1,264 @@
|
||||
# Migrate to Storybook to version 7
|
||||
|
||||
{% callout type="warning" title="Storybook 7 is in beta" %}
|
||||
[Storybook version 7 is still in beta](https://storybook.js.org/blog/7-0-beta/). Things are evolving dynamically, so it would be better to _avoid using in production_. If you want to use the stable, [6.5 version](https://storybook.js.org/releases/6.5), please go to the [Storybook plugin overview guide](/packages/storybook) to get started.
|
||||
{% /callout %}
|
||||
|
||||
{% callout type="info" title="Setting up Storybook 7 in a new workspace" %}
|
||||
For settin up Storybook version 7 in a new Nx workspace, or a workspace that does NOT already have Storybook configured already, please refer to our [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).
|
||||
{% /callout %}
|
||||
|
||||
Storybook 7 is a major release that brings a lot of new features and improvements. You can read more about it in the [Storybook 7 beta announcement blog post](https://storybook.js.org/blog/7-0-beta/). Apart from the new features and improvements it introduces, it also brings some breaking changes. You can read more about them in the [Storybook 7 migration docs](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-65x-to-700) and the [Storybook 7 migration guide](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937). Do note that _version 7 is still in beta_, and things are evolving dynamically, so it would be better to _avoid using in production_.
|
||||
|
||||
You can now migrate your existing Nx workspace with Storybook configuration to use Storybook version 7. This guide will show you how to do that.
|
||||
|
||||
## Use the Storybook CLI to upgrade
|
||||
|
||||
You can take advantage of the Storybook CLI to automatically migrate some settings of your Storybook setup. For a full guide to migration using the Storybook CLI, please refer to the [Storybook 7 migration guide](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937).
|
||||
|
||||
The Storybook migration scripts do not work perfectly with Nx, however we can use them to get the latest beta versions of our packages, remove some unused packages, and get a hint of some settings that we will need to change manually, eventually.
|
||||
|
||||
{% callout type="warning" title="Don't use in production" %}
|
||||
Please take extra care when migrating your existing Storybook setup to version 7. Do not use in production, since it's still in beta.
|
||||
{% /callout %}
|
||||
|
||||
Let's see the steps we can make to migrate our Storybook setup to version 7.
|
||||
|
||||
### 1. Run the `upgrade` command of the Storybook CLI
|
||||
|
||||
```bash
|
||||
npx storybook@next upgrade --prerelease
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
- Upgrade your dependencies to the latest prerelease version
|
||||
- Run a number of migration scripts (code generators and modifiers) - upon approval
|
||||
|
||||
For more info, see [here](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937).
|
||||
|
||||
### 2. Click yes to the automigration prompts
|
||||
|
||||
The Storybook CLI will prompt you to run some code generators and modifiers.
|
||||
|
||||
Click `yes` to the following:
|
||||
|
||||
- `mainjsFramework`: It will add the `framework` field in your root `.storybook/main.js|ts` file. We are going to delete it since it's not needed in the root file, but it's handy to have it ready to copy. Also, it shows you an indication of what it looks like.
|
||||
- `eslintPlugin`: installs the `eslint-plugin-storybook`
|
||||
- `storybook-binary`: installs Storybook's `storybook` binary
|
||||
- `newFrameworks`: removed unused dependencies (eg. `@storybook/builder-webpack5`, `@storybook/manager-webpack5`, `@storybook/builder-vite`)
|
||||
|
||||
Click `no` to the following:
|
||||
|
||||
- `autodocsTrue`: we don't need it and it can potentially cause issues with missing dependencies
|
||||
|
||||
### 3. Restore the root `.storybook/main.js|ts` file
|
||||
|
||||
You will have noticed that the Storybook automigrator added the `framework` option to your root `.storybook/main.js|ts` file. Let's remove that, along with the `autodocs` option.
|
||||
|
||||
So, remove:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
from your root `.storybook/main.js|ts` file.
|
||||
|
||||
### 3. Edit all the project-level `.storybook/main.js|ts` files
|
||||
|
||||
Find all your project-level `.storybook/main.js|ts` files and edit them to add the `framework` option. While you are at it, remove the `builder` from `core` options.
|
||||
|
||||
#### Remove builder
|
||||
|
||||
In your project-level `.storybook/main.js|ts` files, remove the `builder` from `core` options.
|
||||
|
||||
Your core options most probably look like this:
|
||||
|
||||
```ts
|
||||
core: { ...rootMain.core, builder: '@storybook/builder-vite' },
|
||||
```
|
||||
|
||||
You must remove the `builder`, or you can also delete the `core` object entirely.
|
||||
|
||||
#### Add framework
|
||||
|
||||
Choose the `framework` carefully. The list of available frameworks is:
|
||||
|
||||
- `@storybook/angular`
|
||||
- `@storybook/html-webpack5`
|
||||
- `@storybook/nextjs`
|
||||
- `@storybook/preact-webpack5`
|
||||
- `@storybook/react-webpack5`
|
||||
- `@storybook/react-vite`
|
||||
- `@storybook/server-webpack5`
|
||||
- `@storybook/svelte-webpack5`
|
||||
- `@storybook/svelte-vite`
|
||||
- `@storybook/sveltekit`
|
||||
- `@storybook/vue-webpack5`
|
||||
- `@storybook/vue-vite`
|
||||
- `@storybook/vue3-webpack5`
|
||||
- `@storybook/vue3-vite`
|
||||
- `@storybook/web-components-webpack5`
|
||||
- `@storybook/web-components-vite`
|
||||
|
||||
#### For Angular projects
|
||||
|
||||
Choose the `@storybook/angular` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For React projects using `'@storybook/builder-vite'`
|
||||
|
||||
Choose the `@storybook/react-vite` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For React projects using `'@storybook/builder-webpack5'`
|
||||
|
||||
Choose the `@storybook/react-webpack5` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/react-webpack5',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For Next.js projects
|
||||
|
||||
Choose the `@storybook/nextjs` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/nextjs',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For Web Components projects using `'@storybook/builder-vite'`
|
||||
|
||||
Choose the `@storybook/web-components-vite` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/web-components-vite',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For Web Components projects using `'@storybook/builder-webpack5'`
|
||||
|
||||
Choose the `@storybook/web-components-webpack5` framework. So add this in your project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
framework: {
|
||||
name: '@storybook/web-components-webpack5',
|
||||
options: {}
|
||||
}
|
||||
```
|
||||
|
||||
#### For the rest of the projects
|
||||
|
||||
You can easily find the correct framework by looking at the `builder` option in your project-level `.storybook/main.js|ts` file.
|
||||
|
||||
#### Resulting project-level `.storybook/main.js|ts` file
|
||||
|
||||
Here is an example of a project-level `.storybook/main.js|ts` file:
|
||||
|
||||
```ts
|
||||
const rootMain = require('../../../.storybook/main');
|
||||
|
||||
module.exports = {
|
||||
...rootMain,
|
||||
stories: [
|
||||
...rootMain.stories,
|
||||
'../src/app/**/*.stories.mdx',
|
||||
'../src/app/**/*.stories.@(js|jsx|ts|tsx)',
|
||||
],
|
||||
addons: [...rootMain.addons],
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 4. For Vite.js projects
|
||||
|
||||
Make sure to add the `viteFinal` option to your project-level `.storybook/main.js|ts` files.
|
||||
|
||||
```ts
|
||||
async viteFinal(config, { configType }) {
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
viteTsConfigPaths({
|
||||
root: '<PATH_TO_PROJECT_ROOT>',
|
||||
}),
|
||||
],
|
||||
});
|
||||
},
|
||||
```
|
||||
|
||||
This will take care of any path resolution issues.
|
||||
|
||||
An example of a project-level `.storybook/main.js|ts` file for a Vite.js project:
|
||||
|
||||
```ts
|
||||
const { mergeConfig } = require('vite');
|
||||
const viteTsConfigPaths = require('vite-tsconfig-paths').default;
|
||||
const rootMain = require('../../../.storybook/main');
|
||||
|
||||
module.exports = {
|
||||
...rootMain,
|
||||
stories: [
|
||||
...rootMain.stories,
|
||||
'../src/app/**/*.stories.mdx',
|
||||
'../src/app/**/*.stories.@(js|jsx|ts|tsx)',
|
||||
],
|
||||
addons: [...rootMain.addons],
|
||||
async viteFinal(config, { configType }) {
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
viteTsConfigPaths({
|
||||
root: '../../../',
|
||||
}),
|
||||
],
|
||||
});
|
||||
},
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Use Storybook 7 beta
|
||||
|
||||
You can now use Storybook 7 beta! 🎉
|
||||
|
||||
```bash
|
||||
npx nx build-storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```bash
|
||||
npx nx storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
## Report any issues and bugs
|
||||
|
||||
Since this is a beta version, there are bound to be some issues and bugs. Please report any issues and bugs you find [on the Nx GitHub page](https://github.com/nrwl/nx/issues/new/choose) or on the [Storybook GitHub page](https://github.com/storybookjs/storybook/issues/new/choose).
|
||||
@ -2,14 +2,31 @@
|
||||
|
||||
This guide will briefly walk you through using Storybook within an Nx workspace.
|
||||
|
||||
{% callout type="info" title="Try out Storybook 7 beta" %}
|
||||
[Storybook version 7 is still in beta](https://storybook.js.org/blog/7-0-beta/). However, you can try it out with Nx by following the instructions in the [Storybook 7 setup](/packages/storybook/documents/storybook-7-setup) guide.
|
||||
{% /callout %}
|
||||
|
||||
## Setting Up Storybook
|
||||
|
||||
### Add the Storybook plugin
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="yarn" %}
|
||||
|
||||
```shell
|
||||
yarn add --dev @nrwl/storybook
|
||||
yarn add -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% tab label="npm" %}
|
||||
|
||||
```shell
|
||||
npm install -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
## Using Storybook
|
||||
|
||||
### Generating Storybook Configuration
|
||||
|
||||
116
docs/shared/packages/storybook/storybook-7-setup.md
Normal file
116
docs/shared/packages/storybook/storybook-7-setup.md
Normal file
@ -0,0 +1,116 @@
|
||||
# Storybook 7 is here - and Nx is ready
|
||||
|
||||
{% callout type="warning" title="Storybook 7 is in beta" %}
|
||||
[Storybook version 7 is still in beta](https://storybook.js.org/blog/7-0-beta/). Things are evolving dynamically, so it would be better to _avoid using in production_. If you want to use the stable, [6.5 version](https://storybook.js.org/releases/6.5), please go to the [Storybook plugin overview guide](/packages/storybook) to get started.
|
||||
{% /callout %}
|
||||
|
||||
Storybook 7 is a major release that brings a lot of new features and improvements. You can read more about it in the [Storybook 7 beta announcement blog post](https://storybook.js.org/blog/7-0-beta/). Apart from the new features and improvements it introduces, it also brings some breaking changes. You can read more about them in the [Storybook 7 migration docs](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-65x-to-700) and the [Storybook 7 migration guide](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937). Do note that _version 7 is still in beta_, and things are evolving dynamically, so it would be better to _avoid using in production_.
|
||||
|
||||
Nx provides new generators that allow you to generate Storybook 7 configuration for your projects, by installing the correct dependencies, and creating the corresponding version 7 configuration files.
|
||||
|
||||
So, let's see how to get started with Storybook 7 and Nx.
|
||||
|
||||
## Setting Up Storybook 7 in a _new_ Nx Workspace
|
||||
|
||||
In this guide we will see how to set up Storybook version 7 in a new Nx workspace, or a workspace that does NOT already have Storybook configured.
|
||||
|
||||
{% callout type="warning" title="Migrating existing Storybook configuration" %}
|
||||
For migrating your existing Nx workspace with existing Storybook configuration to use Storybook version 7, please refer to our [Storybook 7 migration guide](/packages/storybook/documents/migrate-storybook-7).
|
||||
{% /callout %}
|
||||
|
||||
### Add the Storybook plugin
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="yarn" %}
|
||||
|
||||
```shell
|
||||
yarn add -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% tab label="npm" %}
|
||||
|
||||
```shell
|
||||
npm install -D @nrwl/storybook
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
## Using Storybook
|
||||
|
||||
### Generating Storybook Configuration
|
||||
|
||||
You can generate Storybook configuration for an individual project with this command:
|
||||
|
||||
```shell
|
||||
nx g @nrwl/storybook:configuration project-name --storybook7betaConfiguration --storybook7UiFramework=@storybook/react-webpack5
|
||||
```
|
||||
|
||||
In the field `storybook7UiFramework` you must choose one of the following Storybook frameworks:
|
||||
|
||||
- `@storybook/angular`
|
||||
- `@storybook/html-webpack5`
|
||||
- `@storybook/nextjs`
|
||||
- `@storybook/preact-webpack5`
|
||||
- `@storybook/react-webpack5`
|
||||
- `@storybook/react-vite`
|
||||
- `@storybook/server-webpack5`
|
||||
- `@storybook/svelte-webpack5`
|
||||
- `@storybook/svelte-vite`
|
||||
- `@storybook/sveltekit`
|
||||
- `@storybook/vue-webpack5`
|
||||
- `@storybook/vue-vite`
|
||||
- `@storybook/vue3-webpack5`
|
||||
- `@storybook/vue3-vite`
|
||||
- `@storybook/web-components-webpack5`
|
||||
- `@storybook/web-components-vite`
|
||||
|
||||
In Storybook 7, [the `framework` field in `.storybook/main.js|ts` is mandatory](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-field-mandatory). You must choose one of the above frameworks when setting up your application.
|
||||
|
||||
If you are using one of the framework-specific generators (e.g. [`@nrwl/angular:storybook-configuration`](/packages/angular/generators/storybook-configuration), or [`@nrwl/react:storybook-configuration`](/packages/react/generators/storybook-configuration) for React and Nextjs projects, or [`@nrwl/react-native:storybook-configuration`](<(/packages/react-native/generators/storybook-configuration)>)), the generator will automatically choose the correct framework for you.
|
||||
|
||||
Choosing one of these frameworks will have the following effects on your workspace:
|
||||
|
||||
1. Nx will install all the required Storybook packages that go with it.
|
||||
|
||||
2. Nx will generate a root `.storybook` folder and a project-level `.storybook` folder (located under `libs/your-project/.storybook` or `apps/your-project/.storybook`) containing the essential configuration files for Storybook.
|
||||
|
||||
3. If you are working on an Angular, a React or a React Native project (and you choose `@storybook/angular`, `@storybook/react` or `@storybook/react-native`) the Nx generator will also generate stories for all the components in your project.
|
||||
|
||||
4. Nx will create new `targets` in your project's `project.json`, called `storybook` and `build-storybook`, containing all the necessary configuration to serve and build Storybook.
|
||||
|
||||
5. Nx will generate a new Cypress e2e app for your project (if there isn't one already) to run against the Storybook instance.
|
||||
|
||||
### Changes from the v6.5 Storybook configuration
|
||||
|
||||
The Storybook configuration generated by Nx for Storybook 7 is very similar to the one generated for Storybook 6.5. Here are the new things that you should expect to see:
|
||||
|
||||
#### Changes in `.storybook/main.js|ts` file
|
||||
|
||||
- No longer set the `core` field which contains the `builder` option.
|
||||
- The `framework` field is now mandatory, and it "replaces" the `builder` configuration. You can read more [in the Storybook docs](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#mainjs-framework-field).
|
||||
- Nx no longer adds the `webpackFinal` field to the `.storybook/main.js|ts` files. This is just for the sake of simplicity. You can still edit your webpack configuration by using the `webpackFinal` field, just as you can edit your Vite configuration by using the `viteFinal` field. You can read more about how to customize your webpack configuration [in the Storybook webpack docs](https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config), and you can read more about how to customize your Vite configuration [in the Storybook Vite docs](https://storybook.js.org/docs/react/builders/vite#configuration).
|
||||
|
||||
#### Changes in the `storybook` and `build-storybook` targets
|
||||
|
||||
- The `uiFramework` field is not needed any more, thus it is not set. Nx was using the `uiFramework` field to load any framework specific options for the Storybook builder. This is no longer needed, since the `framework` set in `.storybook/main.js|ts` takes care of that.
|
||||
- More options from the Storybook CLI are now exposed in the executors. You can see these in the [`@nrwl/storybook:storybook`](/packages/storybook/executors/storybook) and [`@nrwl/storybook:build`](/packages/storybook/executors/build) executor schemas. You can read more about these options in the [Storybook 7 CLI docs](https://storybook.js.org/docs/7.0/react/api/cli-options). If there's an option you need to pass but it's not in the executor schema, you can always pass it, since the executors are just passing the options to the Storybook CLI.
|
||||
|
||||
## Use Storybook 7 beta
|
||||
|
||||
You can now use Storybook 7 beta! 🎉
|
||||
|
||||
```bash
|
||||
npx nx build-storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```bash
|
||||
npx nx storybook PROJECT_NAME
|
||||
```
|
||||
|
||||
## Report any issues and bugs
|
||||
|
||||
Since this is a beta version, there are bound to be some issues and bugs. Please report any issues and bugs you find [on the Nx GitHub page](https://github.com/nrwl/nx/issues/new/choose) or on the [Storybook GitHub page](https://github.com/storybookjs/storybook/issues/new/choose).
|
||||
@ -37,3 +37,11 @@ nx g @nrwl/angular:storybook-configuration ui --generateStories=true --ignorePat
|
||||
This will generate a Storybook configuration for the `ui` project and generate stories for all components in the `libs/ui/src/lib` directory, except for the ones in the `libs/ui/src/not-stories` directory, and the ones in the `apps/my-app` directory that end with `.something.ts`, and also for components that their file name is of the pattern `*.other.*`.
|
||||
|
||||
This is useful if you have a project that contains components that are not meant to be used in isolation, but rather as part of a larger component.
|
||||
|
||||
### Generate Storybook configuration for Storybook version 7
|
||||
|
||||
```bash
|
||||
nx g @nrwl/angular:storybook-configuration ui --storybook7betaConfiguration=true
|
||||
```
|
||||
|
||||
This will generate a Storybook configuration for the `ui` project using Storybook version 7. It will install the Storybook version 7 dependencies and configure the Storybook configuration files (the files inside the `.storybook` directory) to use Storybook version 7. You can read more about Storybook 7 Nx support in the [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).
|
||||
|
||||
@ -16,5 +16,6 @@ export async function generateStorybookConfiguration(
|
||||
cypressDirectory: options.cypressDirectory,
|
||||
tsConfiguration: options.tsConfiguration,
|
||||
configureTestRunner: options.configureTestRunner,
|
||||
storybook7betaConfiguration: options.storybook7betaConfiguration,
|
||||
});
|
||||
}
|
||||
|
||||
@ -11,4 +11,5 @@ export interface StorybookConfigurationOptions {
|
||||
skipFormat?: boolean;
|
||||
ignorePaths?: string[];
|
||||
configureTestRunner?: boolean;
|
||||
storybook7betaConfiguration?: boolean;
|
||||
}
|
||||
|
||||
@ -78,6 +78,11 @@
|
||||
"configureTestRunner": {
|
||||
"type": "boolean",
|
||||
"description": "Add a Storybook Test-Runner target."
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
This generator will set up Storybook for your React project.
|
||||
This generator will set up Storybook for your **React** project. You can also use this generator to generate Storybook configuration for your **Next.js** project.
|
||||
|
||||
```bash
|
||||
nx g @nrwl/react:storybook-configuration project-name
|
||||
@ -45,3 +45,11 @@ nx g @nrwl/react:storybook-configuration ui --generateStories=true --js=true
|
||||
```
|
||||
|
||||
This will generate stories for all the components in the `ui` project using JavaScript instead of TypeScript. So, you will have `.stories.js` files next to your components.
|
||||
|
||||
### Generate Storybook configuration for Storybook version 7
|
||||
|
||||
```bash
|
||||
nx g @nrwl/react:storybook-configuration ui --storybook7betaConfiguration=true
|
||||
```
|
||||
|
||||
This will generate a Storybook configuration for the `ui` project using Storybook version 7. It will install the Storybook version 7 dependencies and configure the Storybook configuration files (the files inside the `.storybook` directory) to use Storybook version 7. You can read more about Storybook 7 Nx support in the [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).
|
||||
|
||||
@ -101,6 +101,11 @@ export async function storybookConfigurationGenerator(
|
||||
tsConfiguration: schema.tsConfiguration,
|
||||
configureTestRunner: schema.configureTestRunner,
|
||||
bundler,
|
||||
storybook7betaConfiguration: schema.storybook7betaConfiguration,
|
||||
storybook7UiFramework:
|
||||
bundler === 'vite'
|
||||
? '@storybook/react-vite'
|
||||
: '@storybook/react-webpack5',
|
||||
});
|
||||
|
||||
if (schema.generateStories) {
|
||||
|
||||
@ -13,4 +13,5 @@ export interface StorybookConfigureSchema {
|
||||
ignorePaths?: string[];
|
||||
bundler?: 'webpack' | 'vite';
|
||||
configureTestRunner?: boolean;
|
||||
storybook7betaConfiguration?: boolean;
|
||||
}
|
||||
|
||||
@ -86,6 +86,12 @@
|
||||
"description": "The Storybook builder to use.",
|
||||
"enum": ["vite", "webpack"],
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "important"
|
||||
}
|
||||
},
|
||||
"required": ["name"],
|
||||
|
||||
@ -32,3 +32,17 @@ nx g @nrwl/storybook:configuration ui --uiFramework=@storybook/web-components --
|
||||
```
|
||||
|
||||
This will generate a Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory).
|
||||
|
||||
### Generate Storybook configuration for Storybook version 7
|
||||
|
||||
```bash
|
||||
nx g @nrwl/storybook:configuration ui --uiFramework=@storybook/react --storybook7betaConfiguration=true
|
||||
```
|
||||
|
||||
OR
|
||||
|
||||
```bash
|
||||
nx g @nrwl/storybook:configuration ui --storybook7UiFramework=@storybook/react-vite --storybook7betaConfiguration=true
|
||||
```
|
||||
|
||||
This will generate a Storybook configuration for the `ui` project using Storybook version 7. It will install the Storybook version 7 dependencies and configure the Storybook configuration files (the files inside the `.storybook` directory) to use Storybook version 7. You can read more about Storybook 7 Nx support in the [Storybook 7 setup guide](/packages/storybook/documents/storybook-7-setup).
|
||||
|
||||
@ -9,6 +9,11 @@
|
||||
"executor": "@nrwl/js:tsc",
|
||||
"options": {
|
||||
"assets": [
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/files/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/project-files/.storybook/**",
|
||||
@ -16,7 +21,7 @@
|
||||
},
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/files/**",
|
||||
"glob": "**/project-files-7/.storybook/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
@ -29,25 +34,25 @@
|
||||
"glob": "**/project-files-ts/.storybook/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/project-files-7-ts/.storybook/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/root-files-ts/.storybook/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/root-files-nested/.storybook/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/root-files-nested-ts/.storybook/**",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/storybook",
|
||||
"glob": "**/*.json",
|
||||
"ignore": ["**/tsconfig*.json", "project.json", ".eslintrc.json"],
|
||||
"ignore": [
|
||||
"**/tsconfig*.json",
|
||||
"project.json",
|
||||
".eslintrc.json",
|
||||
"**/test-configs/**"
|
||||
],
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
|
||||
@ -14,9 +14,9 @@ jest.mock('@storybook/core-server', () => {
|
||||
});
|
||||
import * as build from '@storybook/core-server';
|
||||
import { CLIOptions } from '@storybook/types';
|
||||
import { CommonNxStorybookConfig } from '../models';
|
||||
import { CommonNxStorybookConfig } from '../../utils/models';
|
||||
|
||||
// TODO (katerina): Update when Storybook 7
|
||||
// TODO(katerina): Update when Storybook 7
|
||||
describe('Build storybook', () => {
|
||||
let context: ExecutorContext;
|
||||
let options: CLIOptions & CommonNxStorybookConfig;
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import { ExecutorContext, logger } from '@nrwl/devkit';
|
||||
import * as build from '@storybook/core-server';
|
||||
import { CLIOptions } from '@storybook/types'; // TODO (katerina): Remove when Storybook 7
|
||||
import { CLIOptions } from '@storybook/types'; // TODO(katerina): Remove when Storybook 7
|
||||
import 'dotenv/config';
|
||||
import { storybookConfigExistsCheck } from '../../utils/utilities';
|
||||
import { CommonNxStorybookConfig } from '../models';
|
||||
import {
|
||||
getStorybookFrameworkPath,
|
||||
isStorybookV7,
|
||||
runStorybookSetupCheck,
|
||||
} from '../utils';
|
||||
storybookConfigExistsCheck,
|
||||
} from '../../utils/utilities';
|
||||
import { CommonNxStorybookConfig } from '../../utils/models';
|
||||
import { getStorybookFrameworkPath, runStorybookSetupCheck } from '../utils';
|
||||
|
||||
export default async function buildStorybookExecutor(
|
||||
options: CLIOptions & CommonNxStorybookConfig,
|
||||
@ -24,7 +23,7 @@ export default async function buildStorybookExecutor(
|
||||
logger.info(`NX Storybook files available in ${buildOptions.outputDir}`);
|
||||
return { success: true };
|
||||
} else {
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
// print warnings
|
||||
runStorybookSetupCheck(options);
|
||||
|
||||
@ -55,11 +54,11 @@ function runInstance(options: CLIOptions, storybook7: boolean): Promise<void> {
|
||||
return build['build']({
|
||||
...options,
|
||||
mode: 'static',
|
||||
} as any); // TODO (katerina): Change to actual types when Storybook 7
|
||||
} as any); // TODO(katerina): Change to actual types when Storybook 7
|
||||
} else {
|
||||
return build.buildStaticStandalone({
|
||||
...options,
|
||||
ci: true,
|
||||
} as any); // TODO (katerina): Remove when Storybook 7
|
||||
} as any); // TODO(katerina): Remove when Storybook 7
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ import storybookExecutor from './storybook.impl';
|
||||
import { join } from 'path';
|
||||
import { readFileSync } from 'fs-extra';
|
||||
import { CLIOptions } from '@storybook/types';
|
||||
import { CommonNxStorybookConfig } from '../models';
|
||||
import { CommonNxStorybookConfig } from '../../utils/models';
|
||||
|
||||
// TODO (katerina): Update when Storybook 7
|
||||
// TODO(katerina): Update when Storybook 7
|
||||
|
||||
describe('@nrwl/storybook:storybook', () => {
|
||||
let context: ExecutorContext;
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import { ExecutorContext } from '@nrwl/devkit';
|
||||
import * as build from '@storybook/core-server';
|
||||
import 'dotenv/config';
|
||||
import { storybookConfigExistsCheck } from '../../utils/utilities';
|
||||
import {
|
||||
getStorybookFrameworkPath,
|
||||
runStorybookSetupCheck,
|
||||
isStorybookV7,
|
||||
} from '../utils';
|
||||
import { CLIOptions } from '@storybook/types'; // TODO (katerina): Remove when Storybook 7
|
||||
import { CommonNxStorybookConfig } from '../models';
|
||||
storybookConfigExistsCheck,
|
||||
} from '../../utils/utilities';
|
||||
import { getStorybookFrameworkPath, runStorybookSetupCheck } from '../utils';
|
||||
import { CLIOptions } from '@storybook/types'; // TODO(katerina): Remove when Storybook 7
|
||||
import { CommonNxStorybookConfig } from '../../utils/models';
|
||||
|
||||
export default async function* storybookExecutor(
|
||||
options: CLIOptions & CommonNxStorybookConfig,
|
||||
@ -28,15 +27,15 @@ export default async function* storybookExecutor(
|
||||
yield {
|
||||
success: true,
|
||||
info: {
|
||||
port: result.port,
|
||||
port: result?.port,
|
||||
baseUrl: `${options.https ? 'https' : 'http'}://${
|
||||
options.host ?? 'localhost'
|
||||
}:${result.port}`,
|
||||
}:${result?.port}`,
|
||||
},
|
||||
};
|
||||
await new Promise<{ success: boolean }>(() => {});
|
||||
} else {
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
// print warnings
|
||||
runStorybookSetupCheck(options);
|
||||
|
||||
@ -62,9 +61,9 @@ function runInstance(options: CLIOptions, storybook7: boolean) {
|
||||
return build['build']({
|
||||
...options,
|
||||
mode: 'dev',
|
||||
} as any); // TODO (katerina): Change to actual types when Storybook 7
|
||||
} as any); // TODO(katerina): Change to actual types when Storybook 7
|
||||
} else {
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
return build.buildDev({
|
||||
...options,
|
||||
configType: env.toUpperCase(),
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import { ExecutorContext, joinPathFragments, logger } from '@nrwl/devkit';
|
||||
import { joinPathFragments, logger } from '@nrwl/devkit';
|
||||
import { findNodes } from 'nx/src/utils/typescript';
|
||||
import 'dotenv/config';
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { gte } from 'semver';
|
||||
import ts = require('typescript');
|
||||
import { CommonNxStorybookConfig, UiFramework } from './models';
|
||||
import { storybookConfigExistsCheck } from '../utils/utilities';
|
||||
import { CommonNxStorybookConfig, UiFramework } from '../utils/models';
|
||||
import { CLIOptions } from '@storybook/types';
|
||||
|
||||
export interface NodePackage {
|
||||
@ -14,7 +13,7 @@ export interface NodePackage {
|
||||
version: string;
|
||||
}
|
||||
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
export function getStorybookFrameworkPath(uiFramework: UiFramework) {
|
||||
const serverOptionsPaths = {
|
||||
'@storybook/react': '@storybook/react/dist/cjs/server/options',
|
||||
@ -33,7 +32,7 @@ export function getStorybookFrameworkPath(uiFramework: UiFramework) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
function isStorybookV62onwards(uiFramework: string) {
|
||||
const storybookPackageVersion = require(join(
|
||||
uiFramework,
|
||||
@ -43,15 +42,7 @@ function isStorybookV62onwards(uiFramework: string) {
|
||||
return gte(storybookPackageVersion, '6.2.0-rc.4');
|
||||
}
|
||||
|
||||
export function isStorybookV7() {
|
||||
const storybookPackageVersion = require(join(
|
||||
'@storybook/core-server',
|
||||
'package.json'
|
||||
)).version;
|
||||
return gte(storybookPackageVersion, '7.0.0-alpha.0');
|
||||
}
|
||||
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
export function runStorybookSetupCheck(
|
||||
options: CLIOptions & CommonNxStorybookConfig
|
||||
) {
|
||||
@ -59,7 +50,7 @@ export function runStorybookSetupCheck(
|
||||
reactWebpack5Check(options);
|
||||
}
|
||||
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
function reactWebpack5Check(options: CLIOptions & CommonNxStorybookConfig) {
|
||||
if (options.uiFramework === '@storybook/react') {
|
||||
const source = mainJsTsFileContent(options.configDir);
|
||||
@ -81,7 +72,7 @@ function reactWebpack5Check(options: CLIOptions & CommonNxStorybookConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
function mainJsTsFileContent(configFolder: string): ts.SourceFile {
|
||||
let storybookConfigFilePath = joinPathFragments(configFolder, 'main.js');
|
||||
|
||||
@ -106,7 +97,7 @@ function mainJsTsFileContent(configFolder: string): ts.SourceFile {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
function webpackFinalPropertyCheck(
|
||||
options: CLIOptions & CommonNxStorybookConfig
|
||||
) {
|
||||
@ -147,7 +138,7 @@ function webpackFinalPropertyCheck(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (katerina): Remove when Storybook 7
|
||||
// TODO(katerina): Remove when Storybook 7
|
||||
export function builderIsWebpackButNotWebpack5(
|
||||
storybookConfig: ts.SourceFile
|
||||
): boolean {
|
||||
|
||||
@ -67,13 +67,7 @@ exports[`@nrwl/storybook:configuration for workspaces with Root project basic fu
|
||||
|
||||
export const rootMain: StorybookConfig = {
|
||||
stories: [],
|
||||
addons: ['@storybook/addon-essentials'],
|
||||
// webpackFinal: async (config, { configType }) => {
|
||||
// // Make whatever fine-grained changes you need that should apply to all storybook configs
|
||||
|
||||
// // Return the altered config
|
||||
// return config;
|
||||
// },
|
||||
addons: ['@storybook/addon-essentials']
|
||||
};
|
||||
"
|
||||
`;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,381 @@
|
||||
import {
|
||||
addProjectConfiguration,
|
||||
getProjects,
|
||||
NxJsonConfiguration,
|
||||
ProjectConfiguration,
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
Tree,
|
||||
updateJson,
|
||||
writeJson,
|
||||
} from '@nrwl/devkit';
|
||||
import {
|
||||
createTreeWithEmptyV1Workspace,
|
||||
createTreeWithEmptyWorkspace,
|
||||
} from '@nrwl/devkit/testing';
|
||||
|
||||
import { Linter } from '@nrwl/linter';
|
||||
import { libraryGenerator } from '@nrwl/workspace/generators';
|
||||
import { TsConfig } from '../../utils/utilities';
|
||||
import { storybook7Version } from '../../utils/versions';
|
||||
import configurationGenerator from './configuration';
|
||||
import * as variousProjects from './test-configs/various-projects.json';
|
||||
|
||||
describe('@nrwl/storybook:configuration for Storybook v7', () => {
|
||||
describe('basic functionalities', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(async () => {
|
||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||
updateJson<NxJsonConfiguration>(tree, 'nx.json', (json) => {
|
||||
json.namedInputs = {
|
||||
production: ['default'],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
await libraryGenerator(tree, {
|
||||
name: 'test-ui-lib',
|
||||
standaloneConfig: false,
|
||||
});
|
||||
writeJson(tree, 'package.json', {
|
||||
devDependencies: {
|
||||
'@storybook/addon-essentials': storybook7Version,
|
||||
'@storybook/react': storybook7Version,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate TypeScript Configuration files', async () => {
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib',
|
||||
uiFramework: '@storybook/angular',
|
||||
standaloneConfig: false,
|
||||
tsConfiguration: true,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/angular',
|
||||
});
|
||||
const project = readProjectConfiguration(tree, 'test-ui-lib');
|
||||
expect(project).toMatchSnapshot();
|
||||
|
||||
expect(tree.read('.storybook/main.ts', 'utf-8')).toMatchSnapshot();
|
||||
expect(
|
||||
tree.read('libs/test-ui-lib/.storybook/tsconfig.json', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
expect(
|
||||
tree.read('libs/test-ui-lib/.storybook/main.ts', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
expect(
|
||||
tree.exists('libs/test-ui-lib/.storybook/preview.ts')
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not update root files after generating them once', async () => {
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib',
|
||||
uiFramework: '@storybook/angular',
|
||||
standaloneConfig: false,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/angular',
|
||||
});
|
||||
|
||||
const newContents = `module.exports = {
|
||||
stories: [],
|
||||
addons: ['@storybook/addon-essentials', 'new-addon'],
|
||||
};
|
||||
`;
|
||||
await libraryGenerator(tree, {
|
||||
name: 'test-ui-lib-2',
|
||||
standaloneConfig: false,
|
||||
});
|
||||
|
||||
tree.write('.storybook/main.js', newContents);
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib-2',
|
||||
uiFramework: '@storybook/angular',
|
||||
standaloneConfig: false,
|
||||
storybook7betaConfiguration: true,
|
||||
});
|
||||
|
||||
expect(tree.read('.storybook/main.js', 'utf-8')).toEqual(newContents);
|
||||
});
|
||||
|
||||
it('should update `tsconfig.lib.json` file', async () => {
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib',
|
||||
uiFramework: '@storybook/react',
|
||||
standaloneConfig: false,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
const tsconfigJson = readJson<TsConfig>(
|
||||
tree,
|
||||
'libs/test-ui-lib/tsconfig.lib.json'
|
||||
) as Required<TsConfig>;
|
||||
|
||||
expect(tsconfigJson.exclude).toContain('**/*.stories.ts');
|
||||
expect(tsconfigJson.exclude).toContain('**/*.stories.js');
|
||||
expect(tsconfigJson.exclude).toContain('**/*.stories.jsx');
|
||||
expect(tsconfigJson.exclude).toContain('**/*.stories.tsx');
|
||||
});
|
||||
|
||||
it('should update `tsconfig.json` file', async () => {
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib',
|
||||
uiFramework: '@storybook/react',
|
||||
standaloneConfig: false,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
const tsconfigJson = readJson<TsConfig>(
|
||||
tree,
|
||||
'libs/test-ui-lib/tsconfig.json'
|
||||
);
|
||||
|
||||
expect(tsconfigJson.references).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"path": "./tsconfig.lib.json",
|
||||
},
|
||||
Object {
|
||||
"path": "./tsconfig.spec.json",
|
||||
},
|
||||
Object {
|
||||
"path": "./.storybook/tsconfig.json",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it("should update the project's .eslintrc.json if config exists", async () => {
|
||||
await libraryGenerator(tree, {
|
||||
name: 'test-ui-lib2',
|
||||
linter: Linter.EsLint,
|
||||
standaloneConfig: false,
|
||||
});
|
||||
|
||||
updateJson(tree, 'libs/test-ui-lib2/.eslintrc.json', (json) => {
|
||||
json.parserOptions = {
|
||||
project: [],
|
||||
};
|
||||
return json;
|
||||
});
|
||||
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib2',
|
||||
uiFramework: '@storybook/react',
|
||||
standaloneConfig: false,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'libs/test-ui-lib2/.eslintrc.json').parserOptions)
|
||||
.toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"project": Array [
|
||||
"libs/test-ui-lib2/.storybook/tsconfig.json",
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should have the proper typings', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
name: 'test-ui-lib2',
|
||||
linter: Linter.EsLint,
|
||||
standaloneConfig: false,
|
||||
});
|
||||
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib2',
|
||||
uiFramework: '@storybook/react',
|
||||
standaloneConfig: false,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
|
||||
expect(
|
||||
tree.read('libs/test-ui-lib2/.storybook/tsconfig.json', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should generate TS config for project if root config is TS', async () => {
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib',
|
||||
uiFramework: '@storybook/angular',
|
||||
standaloneConfig: false,
|
||||
tsConfiguration: true,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/angular',
|
||||
});
|
||||
|
||||
const newContents = `module.exports = {
|
||||
stories: [],
|
||||
addons: ['@storybook/addon-essentials', 'new-addon'],
|
||||
};
|
||||
`;
|
||||
// Setup a new lib
|
||||
await libraryGenerator(tree, {
|
||||
name: 'test-ui-lib-2',
|
||||
standaloneConfig: false,
|
||||
});
|
||||
|
||||
tree.write('.storybook/main.ts', newContents);
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib-2',
|
||||
uiFramework: '@storybook/angular',
|
||||
standaloneConfig: false,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/angular',
|
||||
});
|
||||
|
||||
expect(tree.read('.storybook/main.ts', 'utf-8')).toEqual(newContents);
|
||||
expect(
|
||||
tree.read('libs/test-ui-lib-2/.storybook/main.ts', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
expect(
|
||||
tree.exists('libs/test-ui-lib-2/.storybook/preview.ts')
|
||||
).toBeTruthy();
|
||||
expect(tree.exists('libs/test-ui-lib-2/.storybook/main.js')).toBeFalsy();
|
||||
expect(
|
||||
tree.exists('libs/test-ui-lib-2/.storybook/preview.js')
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should add test-storybook target', async () => {
|
||||
await configurationGenerator(tree, {
|
||||
name: 'test-ui-lib',
|
||||
uiFramework: '@storybook/react',
|
||||
configureTestRunner: true,
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'package.json').devDependencies['@storybook/test-runner']
|
||||
).toBeTruthy();
|
||||
|
||||
const project = readProjectConfiguration(tree, 'test-ui-lib');
|
||||
expect(project.targets['test-storybook']).toEqual({
|
||||
executor: 'nx:run-commands',
|
||||
options: {
|
||||
command:
|
||||
'test-storybook -c libs/test-ui-lib/.storybook --url=http://localhost:4400',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('generate Storybook configuration for all types of projects', () => {
|
||||
let tree: Tree;
|
||||
let testCases: string[][] = [];
|
||||
|
||||
for (const [name, project] of Object.entries(variousProjects)) {
|
||||
testCases.push([
|
||||
`${
|
||||
project.projectType === 'application' ? 'apps' : 'libs'
|
||||
}/${name}/.storybook/`,
|
||||
]);
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
tree = createTreeWithEmptyV1Workspace();
|
||||
for (const [name, project] of Object.entries(variousProjects)) {
|
||||
addProjectConfiguration(tree, name, project as ProjectConfiguration);
|
||||
writeJson(
|
||||
tree,
|
||||
`${
|
||||
project.projectType === 'application' ? 'apps' : 'libs'
|
||||
}/${name}/tsconfig.json`,
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
await configurationGenerator(tree, {
|
||||
name: 'main-vite',
|
||||
tsConfiguration: false,
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-vite',
|
||||
});
|
||||
await configurationGenerator(tree, {
|
||||
name: 'main-vite-ts',
|
||||
tsConfiguration: true,
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-vite',
|
||||
});
|
||||
await configurationGenerator(tree, {
|
||||
name: 'main-webpack',
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
await configurationGenerator(tree, {
|
||||
name: 'react-rollup',
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
await configurationGenerator(tree, {
|
||||
name: 'react-vite',
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-vite',
|
||||
});
|
||||
|
||||
await configurationGenerator(tree, {
|
||||
name: 'nextapp',
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/nextjs',
|
||||
});
|
||||
|
||||
await configurationGenerator(tree, {
|
||||
name: 'react-swc',
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/react-webpack5',
|
||||
});
|
||||
|
||||
await configurationGenerator(tree, {
|
||||
name: 'wv1',
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/web-components-vite',
|
||||
});
|
||||
|
||||
await configurationGenerator(tree, {
|
||||
name: 'ww1',
|
||||
uiFramework: '@storybook/react',
|
||||
storybook7betaConfiguration: true,
|
||||
storybook7UiFramework: '@storybook/web-components-webpack5',
|
||||
});
|
||||
});
|
||||
|
||||
it('should have updated all their target configurations correctly', async () => {
|
||||
const projects = getProjects(tree);
|
||||
expect(projects).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test.each(testCases)(
|
||||
'should contain the correct configuration in %p',
|
||||
(storybookConfigPath) => {
|
||||
if (tree.exists(storybookConfigPath)) {
|
||||
if (tree.exists(`${storybookConfigPath}main.ts`)) {
|
||||
expect(
|
||||
tree.read(`${storybookConfigPath}main.ts`, 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
}
|
||||
if (tree.exists(`${storybookConfigPath}main.js`)) {
|
||||
expect(
|
||||
tree.read(`${storybookConfigPath}main.js`, 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
}
|
||||
expect(
|
||||
tree.read(`${storybookConfigPath}tsconfig.json`, 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -27,7 +27,10 @@ import {
|
||||
updateLintConfig,
|
||||
} from './util-functions';
|
||||
import { Linter } from '@nrwl/linter';
|
||||
import { findStorybookAndBuildTargetsAndCompiler } from '../../utils/utilities';
|
||||
import {
|
||||
findStorybookAndBuildTargetsAndCompiler,
|
||||
isStorybookV7,
|
||||
} from '../../utils/utilities';
|
||||
import {
|
||||
storybookNextAddonVersion,
|
||||
storybookSwcAddonVersion,
|
||||
@ -50,17 +53,82 @@ export async function configurationGenerator(
|
||||
const { nextBuildTarget, compiler, viteBuildTarget } =
|
||||
findStorybookAndBuildTargetsAndCompiler(targets);
|
||||
|
||||
if (viteBuildTarget && schema.bundler !== 'vite') {
|
||||
logger.info(
|
||||
`Your project ${schema.name} uses Vite as a bundler.
|
||||
Nx will configure Storybook for this project to use Vite as well.`
|
||||
);
|
||||
schema.bundler = 'vite';
|
||||
/**
|
||||
* Make sure someone is not trying to configure Storybook
|
||||
* with the wrong version.
|
||||
*/
|
||||
let storybook7;
|
||||
try {
|
||||
storybook7 = isStorybookV7();
|
||||
} catch (e) {
|
||||
storybook7 = schema.storybook7betaConfiguration;
|
||||
}
|
||||
|
||||
const initTask = await initGenerator(tree, {
|
||||
uiFramework: schema.uiFramework,
|
||||
if (storybook7 && !schema.storybook7betaConfiguration) {
|
||||
schema.storybook7betaConfiguration = true;
|
||||
logger.info(
|
||||
`You are using Storybook version 7.
|
||||
So Nx will configure Storybook for version 7.`
|
||||
);
|
||||
}
|
||||
|
||||
if (viteBuildTarget) {
|
||||
if (schema.bundler !== 'vite') {
|
||||
logger.info(
|
||||
`Your project ${schema.name} uses Vite as a bundler.
|
||||
Nx will configure Storybook for this project to use Vite as well.`
|
||||
);
|
||||
schema.bundler = 'vite';
|
||||
}
|
||||
}
|
||||
|
||||
if (schema.storybook7betaConfiguration) {
|
||||
if (viteBuildTarget) {
|
||||
if (schema.storybook7UiFramework === '@storybook/react-webpack5') {
|
||||
logger.info(
|
||||
`Your project ${schema.name} uses Vite as a bundler.
|
||||
Nx will configure Storybook for this project to use Vite as well.`
|
||||
);
|
||||
schema.storybook7UiFramework = '@storybook/react-vite';
|
||||
}
|
||||
if (
|
||||
schema.storybook7UiFramework === '@storybook/web-components-webpack5'
|
||||
) {
|
||||
logger.info(
|
||||
`Your project ${schema.name} uses Vite as a bundler.
|
||||
Nx will configure Storybook for this project to use Vite as well.`
|
||||
);
|
||||
schema.storybook7UiFramework = '@storybook/web-components-vite';
|
||||
}
|
||||
}
|
||||
|
||||
if (nextBuildTarget) {
|
||||
schema.storybook7UiFramework = '@storybook/nextjs';
|
||||
}
|
||||
|
||||
if (!schema.storybook7UiFramework) {
|
||||
if (schema.uiFramework === '@storybook/react') {
|
||||
schema.storybook7UiFramework = viteBuildTarget
|
||||
? '@storybook/react-vite'
|
||||
: '@storybook/react-webpack5';
|
||||
} else if (schema.uiFramework === '@storybook/web-components') {
|
||||
schema.storybook7UiFramework = viteBuildTarget
|
||||
? '@storybook/web-components-vite'
|
||||
: '@storybook/web-components-webpack5';
|
||||
} else if (schema.uiFramework === '@storybook/angular') {
|
||||
schema.storybook7UiFramework = '@storybook/angular';
|
||||
} else if (schema.uiFramework !== '@storybook/react-native') {
|
||||
schema.storybook7UiFramework = `${schema.uiFramework}-webpack5`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const initTask = initGenerator(tree, {
|
||||
uiFramework: schema.storybook7betaConfiguration
|
||||
? schema.storybook7UiFramework
|
||||
: schema.uiFramework,
|
||||
bundler: schema.bundler,
|
||||
storybook7betaConfiguration: schema.storybook7betaConfiguration,
|
||||
});
|
||||
tasks.push(initTask);
|
||||
|
||||
@ -68,26 +136,32 @@ export async function configurationGenerator(
|
||||
createRootStorybookDirForRootProject(
|
||||
tree,
|
||||
schema.name,
|
||||
schema.uiFramework,
|
||||
schema.storybook7betaConfiguration
|
||||
? schema.storybook7UiFramework
|
||||
: schema.uiFramework,
|
||||
schema.js,
|
||||
schema.tsConfiguration,
|
||||
root,
|
||||
projectType,
|
||||
!!nextBuildTarget,
|
||||
compiler === 'swc',
|
||||
schema.bundler === 'vite'
|
||||
schema.bundler === 'vite',
|
||||
schema.storybook7betaConfiguration
|
||||
);
|
||||
} else {
|
||||
createRootStorybookDir(tree, schema.js, schema.tsConfiguration);
|
||||
createProjectStorybookDir(
|
||||
tree,
|
||||
schema.name,
|
||||
schema.uiFramework,
|
||||
schema.storybook7betaConfiguration
|
||||
? schema.storybook7UiFramework
|
||||
: schema.uiFramework,
|
||||
schema.js,
|
||||
schema.tsConfiguration,
|
||||
!!nextBuildTarget,
|
||||
compiler === 'swc',
|
||||
schema.bundler === 'vite'
|
||||
schema.bundler === 'vite',
|
||||
schema.storybook7betaConfiguration
|
||||
);
|
||||
}
|
||||
|
||||
@ -104,7 +178,8 @@ export async function configurationGenerator(
|
||||
tree,
|
||||
schema.name,
|
||||
schema.uiFramework,
|
||||
schema.configureTestRunner
|
||||
schema.configureTestRunner,
|
||||
schema.storybook7betaConfiguration
|
||||
);
|
||||
}
|
||||
|
||||
@ -136,7 +211,11 @@ export async function configurationGenerator(
|
||||
);
|
||||
}
|
||||
|
||||
if (nextBuildTarget && projectType === 'application') {
|
||||
if (
|
||||
nextBuildTarget &&
|
||||
projectType === 'application' &&
|
||||
!schema.storybook7betaConfiguration
|
||||
) {
|
||||
tasks.push(
|
||||
addDependenciesToPackageJson(
|
||||
tree,
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
<% if (!isRootProject){ %>import { rootMain } from '<%= offsetFromRoot %>../.storybook/<%= rootMainName %>';<% } %>
|
||||
<% if (isRootProject){ %>import { rootMain } from './main.root';<% } %>
|
||||
import type { StorybookConfig, Options } from '@storybook/core-common';
|
||||
<% if (usesVite){ %>import { mergeConfig } from 'vite';<% } %>
|
||||
<% if (usesVite){ %>import viteTsConfigPaths from 'vite-tsconfig-paths';<% } %>
|
||||
|
||||
const config: StorybookConfig = {
|
||||
...rootMain,
|
||||
stories: [
|
||||
...rootMain.stories,<% if(uiFramework === '@storybook/angular' && projectType === 'library') { %>
|
||||
'../**/*.stories.@(js|jsx|ts|tsx|mdx)' <% } else { %>
|
||||
'../<%= projectDirectory %>/**/*.stories.@(js|jsx|ts|tsx|mdx)'
|
||||
<% } %>],
|
||||
addons: [...(rootMain.addons || []) <% if(uiFramework === '@storybook/react-webpack5') { %>, '@nrwl/react/plugins/storybook' <% } %><% if(uiFramework === '@storybook/react-native') { %>, '@storybook/addon-ondevice-actions', '@storybook/addon-ondevice-backgrounds', '@storybook/addon-ondevice-controls', '@storybook/addon-ondevice-notes' <% } %>
|
||||
<% if(usesSwc) { %>, 'storybook-addon-swc' <% } %>
|
||||
]<% if(usesVite) { %>,
|
||||
async viteFinal(config: any) {
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
viteTsConfigPaths({
|
||||
root: '<%= offsetFromRoot %>../',
|
||||
}),
|
||||
],
|
||||
});
|
||||
},<% } %>
|
||||
framework: {
|
||||
name: '<%= uiFramework %>',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
||||
<% if(!usesVite) { %>
|
||||
// To customize your webpack configuration you can use the webpackFinal field.
|
||||
// Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
|
||||
<% } %>
|
||||
|
||||
<% if(usesVite) { %>
|
||||
// To customize your Vite configuration you can use the viteFinal field.
|
||||
// Check https://storybook.js.org/docs/react/builders/vite#configuration
|
||||
<% } %>
|
||||
@ -0,0 +1,28 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true
|
||||
<% if(uiFramework === '@storybook/react-webpack5' || uiFramework === '@storybook/react-vite') { %>, "outDir": "" <% } %>
|
||||
},
|
||||
<% if(uiFramework === '@storybook/react-webpack5' || uiFramework === '@storybook/react-vite') { %>"files": [
|
||||
"<% if(!isRootProject) { %><%= offsetFromRoot %><% } %>../node_modules/@nrwl/react/typings/styled-jsx.d.ts",
|
||||
"<% if(!isRootProject) { %><%= offsetFromRoot %><% } %>../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
"<% if(!isRootProject) { %><%= offsetFromRoot %><% } %>../node_modules/@nrwl/react/typings/image.d.ts"
|
||||
],<% } %>
|
||||
"exclude": ["../**/*.spec.ts" <% if(uiFramework === '@storybook/react-webpack5' || uiFramework === '@storybook/react-vite') { %>, "../**/*.spec.js", "../**/*.spec.tsx", "../**/*.spec.jsx"<% } %>],
|
||||
"include": [<% if(uiFramework === '@storybook/angular' && projectType === 'library') { %>
|
||||
"../src/**/*.stories.ts",
|
||||
"../src/**/*.stories.js",
|
||||
"../src/**/*.stories.jsx",
|
||||
"../src/**/*.stories.tsx",
|
||||
"../src/**/*.stories.mdx",
|
||||
"*.ts",
|
||||
"*.js"<% } else { %>
|
||||
"../<%= mainDir %>/**/*.stories.ts",
|
||||
"../<%= mainDir %>/**/*.stories.js",
|
||||
"../<%= mainDir %>/**/*.stories.jsx",
|
||||
"../<%= mainDir %>/**/*.stories.tsx",
|
||||
"../<%= mainDir %>/**/*.stories.mdx",
|
||||
"*.ts",
|
||||
"*.js"<% if(uiFramework === '@storybook/react-native') { %>, *.tsx"<% } %><% } %>]
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
<% if (!isRootProject){ %>const rootMain = require('<%= offsetFromRoot %>../.storybook/<%= rootMainName %>');<% } %>
|
||||
<% if (isRootProject){ %>const rootMain = require('./main.root');<% } %>
|
||||
<% if (usesVite){ %>const { mergeConfig } = require('vite');<% } %>
|
||||
<% if (usesVite){ %>const viteTsConfigPaths = require('vite-tsconfig-paths').default;<% } %>
|
||||
<% if (existsRootWebpackConfig && !usesVite){ %>const rootWebpackConfig = require('<%= offsetFromRoot %>../.storybook/webpack.config'); <% } %>
|
||||
|
||||
module.exports = {
|
||||
...rootMain,
|
||||
stories: [
|
||||
...rootMain.stories,<% if(uiFramework === '@storybook/angular' && projectType === 'library') { %>
|
||||
'../**/*.stories.@(js|jsx|ts|tsx|mdx)' <% } else { %>
|
||||
'../<%= projectDirectory %>/**/*.stories.@(js|jsx|ts|tsx|mdx)'
|
||||
<% } %>],
|
||||
addons: [...rootMain.addons <% if(uiFramework === '@storybook/react-webpack5') { %>, '@nrwl/react/plugins/storybook' <% } %><% if(uiFramework === '@storybook/react-native') { %>, '@storybook/addon-ondevice-actions', '@storybook/addon-ondevice-backgrounds', '@storybook/addon-ondevice-controls', '@storybook/addon-ondevice-notes' <% } %>
|
||||
<% if(usesSwc) { %>, 'storybook-addon-swc' <% } %>
|
||||
]<% if(usesVite) { %>,
|
||||
async viteFinal(config, { configType }) {
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
viteTsConfigPaths({
|
||||
root: '<%= offsetFromRoot %>../',
|
||||
}),
|
||||
],
|
||||
});
|
||||
},<% } %>
|
||||
framework: {
|
||||
name: '<%= uiFramework %>',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
<% if(!usesVite) { %>
|
||||
// To customize your webpack configuration you can use the webpackFinal field.
|
||||
// Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
|
||||
<% } %>
|
||||
|
||||
<% if(usesVite) { %>
|
||||
// To customize your Vite configuration you can use the viteFinal field.
|
||||
// Check https://storybook.js.org/docs/react/builders/vite#configuration
|
||||
<% } %>
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true
|
||||
<% if(uiFramework === '@storybook/react-webpack5' || uiFramework === '@storybook/react-vite') { %>, "outDir": "" <% } %>
|
||||
},
|
||||
<% if(uiFramework === '@storybook/react-webpack5' || uiFramework === '@storybook/react-vite') { %>"files": [
|
||||
"<% if(!isRootProject) { %><%= offsetFromRoot %><% } %>../node_modules/@nrwl/react/typings/styled-jsx.d.ts",
|
||||
"<% if(!isRootProject) { %><%= offsetFromRoot %><% } %>../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
"<% if(!isRootProject) { %><%= offsetFromRoot %><% } %>../node_modules/@nrwl/react/typings/image.d.ts"
|
||||
],<% } %>
|
||||
"exclude": ["../**/*.spec.ts" <% if(uiFramework === '@storybook/react-webpack5' || uiFramework === '@storybook/react-vite') { %>, "../**/*.spec.js", "../**/*.spec.tsx", "../**/*.spec.jsx"<% } %>],
|
||||
"include": [<% if(uiFramework === '@storybook/angular' && projectType === 'library') { %>
|
||||
"../src/**/*.stories.ts",
|
||||
"../src/**/*.stories.js",
|
||||
"../src/**/*.stories.jsx",
|
||||
"../src/**/*.stories.tsx",
|
||||
"../src/**/*.stories.mdx",
|
||||
"*.js"<% } else { %>
|
||||
"../<%= mainDir %>/**/*.stories.ts",
|
||||
"../<%= mainDir %>/**/*.stories.js",
|
||||
"../<%= mainDir %>/**/*.stories.jsx",
|
||||
"../<%= mainDir %>/**/*.stories.tsx",
|
||||
"../<%= mainDir %>/**/*.stories.mdx",
|
||||
"*.js"<% if(uiFramework === '@storybook/react-native') { %>, "*.ts", "*.tsx"<% } %><% } %>]
|
||||
}
|
||||
@ -2,11 +2,5 @@ import type { StorybookConfig } from '@storybook/core-common';
|
||||
|
||||
export const rootMain: StorybookConfig = {
|
||||
stories: [],
|
||||
addons: ['@storybook/addon-essentials'],
|
||||
// webpackFinal: async (config, { configType }) => {
|
||||
// // Make whatever fine-grained changes you need that should apply to all storybook configs
|
||||
|
||||
// // Return the altered config
|
||||
// return config;
|
||||
// },
|
||||
addons: ['@storybook/addon-essentials']
|
||||
};
|
||||
|
||||
@ -1,11 +1,4 @@
|
||||
module.exports = {
|
||||
stories: [],
|
||||
addons: ['@storybook/addon-essentials'],
|
||||
// uncomment the property below if you want to apply some webpack config globally
|
||||
// webpackFinal: async (config, { configType }) => {
|
||||
// // Make whatever fine-grained changes you need that should apply to all storybook configs
|
||||
|
||||
// // Return the altered config
|
||||
// return config;
|
||||
// },
|
||||
addons: ['@storybook/addon-essentials']
|
||||
};
|
||||
|
||||
@ -1,22 +1,17 @@
|
||||
import { Linter } from '@nrwl/linter';
|
||||
import { UiFramework7, UiFramework } from '../../utils/models';
|
||||
|
||||
export interface StorybookConfigureSchema {
|
||||
name: string;
|
||||
uiFramework:
|
||||
| '@storybook/angular'
|
||||
| '@storybook/react'
|
||||
| '@storybook/react-native'
|
||||
| '@storybook/html'
|
||||
| '@storybook/web-components'
|
||||
| '@storybook/vue'
|
||||
| '@storybook/vue3'
|
||||
| '@storybook/svelte';
|
||||
uiFramework: UiFramework; // TODO(katerina): Remove when Storybook 7
|
||||
configureCypress?: boolean;
|
||||
bundler?: 'webpack' | 'vite';
|
||||
bundler?: 'webpack' | 'vite'; // TODO(katerina): Remove when Storybook 7
|
||||
linter?: Linter;
|
||||
js?: boolean;
|
||||
tsConfiguration?: boolean;
|
||||
cypressDirectory?: string;
|
||||
standaloneConfig?: boolean;
|
||||
configureTestRunner?: boolean;
|
||||
storybook7betaConfiguration?: boolean; // TODO(katerina): Change when Storybook 7
|
||||
storybook7UiFramework?: UiFramework7; // TODO(katerina): Change when Storybook 7
|
||||
}
|
||||
|
||||
@ -76,6 +76,34 @@
|
||||
"x-prompt": "Which Storybook builder do you want to use?",
|
||||
"default": "webpack",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7UiFramework": {
|
||||
"type": "string",
|
||||
"description": "Storybook UI Framework to use.",
|
||||
"enum": [
|
||||
"@storybook/angular",
|
||||
"@storybook/html-webpack5",
|
||||
"@storybook/nextjs",
|
||||
"@storybook/preact-webpack5",
|
||||
"@storybook/react-webpack5",
|
||||
"@storybook/react-vite",
|
||||
"@storybook/server-webpack5",
|
||||
"@storybook/svelte-webpack5",
|
||||
"@storybook/svelte-vite",
|
||||
"@storybook/sveltekit",
|
||||
"@storybook/vue-webpack5",
|
||||
"@storybook/vue-vite",
|
||||
"@storybook/vue3-webpack5",
|
||||
"@storybook/vue3-vite",
|
||||
"@storybook/web-components-webpack5",
|
||||
"@storybook/web-components-vite"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["name"],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -21,12 +21,12 @@ import { join, relative } from 'path';
|
||||
import {
|
||||
dedupe,
|
||||
findStorybookAndBuildTargetsAndCompiler,
|
||||
isFramework,
|
||||
TsConfig,
|
||||
} from '../../utils/utilities';
|
||||
import { StorybookConfigureSchema } from './schema';
|
||||
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
|
||||
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
|
||||
import { UiFramework, UiFramework7 } from '../../utils/models';
|
||||
|
||||
const DEFAULT_PORT = 4400;
|
||||
|
||||
@ -34,7 +34,8 @@ export function addStorybookTask(
|
||||
tree: Tree,
|
||||
projectName: string,
|
||||
uiFramework: string,
|
||||
configureTestRunner: boolean
|
||||
configureTestRunner: boolean,
|
||||
usesV7?: boolean
|
||||
) {
|
||||
if (uiFramework === '@storybook/react-native') {
|
||||
return;
|
||||
@ -69,6 +70,11 @@ export function addStorybookTask(
|
||||
},
|
||||
};
|
||||
|
||||
if (usesV7) {
|
||||
delete projectConfig.targets['storybook'].options.uiFramework;
|
||||
delete projectConfig.targets['build-storybook'].options.uiFramework;
|
||||
}
|
||||
|
||||
if (configureTestRunner === true) {
|
||||
projectConfig.targets['test-storybook'] = {
|
||||
executor: 'nx:run-commands',
|
||||
@ -168,7 +174,8 @@ export function configureTsProjectConfig(
|
||||
...(tsConfigContent.exclude || []),
|
||||
'**/*.stories.ts',
|
||||
'**/*.stories.js',
|
||||
...(isFramework('react', schema) || isFramework('react-native', schema)
|
||||
...(schema.uiFramework === '@storybook/react' ||
|
||||
schema.uiFramework === '@storybook/react-native'
|
||||
? ['**/*.stories.jsx', '**/*.stories.tsx']
|
||||
: []),
|
||||
];
|
||||
@ -327,14 +334,15 @@ export function createRootStorybookDir(
|
||||
export function createRootStorybookDirForRootProject(
|
||||
tree: Tree,
|
||||
projectName: string,
|
||||
uiFramework: StorybookConfigureSchema['uiFramework'],
|
||||
uiFramework: UiFramework | UiFramework7,
|
||||
js: boolean,
|
||||
tsConfiguration: boolean,
|
||||
root: string,
|
||||
projectType: string,
|
||||
isNextJs?: boolean,
|
||||
usesSwc?: boolean,
|
||||
usesVite?: boolean
|
||||
usesVite?: boolean,
|
||||
usesV7?: boolean
|
||||
) {
|
||||
const rootConfigExists =
|
||||
tree.exists('.storybook/main.root.js') ||
|
||||
@ -370,7 +378,7 @@ export function createRootStorybookDirForRootProject(
|
||||
|
||||
const templatePath = join(
|
||||
__dirname,
|
||||
`./project-files${
|
||||
`./project-files${usesV7 ? '-7' : ''}${
|
||||
rootFileIsTs(tree, 'main.root', tsConfiguration) ? '-ts' : ''
|
||||
}`
|
||||
);
|
||||
@ -399,12 +407,13 @@ export function createRootStorybookDirForRootProject(
|
||||
export function createProjectStorybookDir(
|
||||
tree: Tree,
|
||||
projectName: string,
|
||||
uiFramework: StorybookConfigureSchema['uiFramework'],
|
||||
uiFramework: UiFramework | UiFramework7,
|
||||
js: boolean,
|
||||
tsConfiguration: boolean,
|
||||
isNextJs?: boolean,
|
||||
usesSwc?: boolean,
|
||||
usesVite?: boolean
|
||||
usesVite?: boolean,
|
||||
usesV7?: boolean
|
||||
) {
|
||||
const { root, projectType } = readProjectConfiguration(tree, projectName);
|
||||
|
||||
@ -434,7 +443,7 @@ export function createProjectStorybookDir(
|
||||
|
||||
const templatePath = join(
|
||||
__dirname,
|
||||
`./project-files${
|
||||
`./project-files${usesV7 ? '-7' : ''}${
|
||||
rootFileIsTs(tree, rootMainName, tsConfiguration) ? '-ts' : ''
|
||||
}`
|
||||
);
|
||||
|
||||
@ -7,7 +7,6 @@ import {
|
||||
updateJson,
|
||||
updateNxJson,
|
||||
} from '@nrwl/devkit';
|
||||
import { isFramework } from '../../utils/utilities';
|
||||
|
||||
import {
|
||||
babelCoreVersion,
|
||||
@ -17,6 +16,7 @@ import {
|
||||
litHtmlVersion,
|
||||
nxVersion,
|
||||
reactNativeStorybookLoader,
|
||||
storybook7Version,
|
||||
storybookReactNativeVersion,
|
||||
storybookVersion,
|
||||
svgrVersion,
|
||||
@ -36,74 +36,100 @@ function checkDependenciesInstalled(host: Tree, schema: Schema) {
|
||||
|
||||
// base deps
|
||||
devDependencies['@nrwl/storybook'] = nxVersion;
|
||||
devDependencies['@storybook/core-server'] = storybookVersion;
|
||||
devDependencies['@storybook/addon-essentials'] = storybookVersion;
|
||||
|
||||
if (schema.bundler === 'vite') {
|
||||
devDependencies['@storybook/builder-vite'] = viteBuilderVersion;
|
||||
} else {
|
||||
devDependencies['@storybook/builder-webpack5'] = storybookVersion;
|
||||
devDependencies['@storybook/manager-webpack5'] = storybookVersion;
|
||||
}
|
||||
if (schema.storybook7betaConfiguration) {
|
||||
if (schema.uiFramework === '@storybook/react-native') {
|
||||
devDependencies['@storybook/react-native'] = storybookReactNativeVersion;
|
||||
} else {
|
||||
devDependencies[schema.uiFramework] = storybook7Version;
|
||||
}
|
||||
devDependencies['@storybook/core-server'] = storybook7Version;
|
||||
devDependencies['@storybook/addon-essentials'] = storybook7Version;
|
||||
|
||||
// TODO(katerina): Remove this when Storybook 7.0 is added in Nx
|
||||
devDependencies['html-webpack-plugin'] = htmlWebpackPluginVersion;
|
||||
|
||||
if (isFramework('angular', schema)) {
|
||||
devDependencies['@storybook/angular'] = storybookVersion;
|
||||
devDependencies['webpack'] = webpack5Version;
|
||||
if (schema.uiFramework === '@storybook/angular') {
|
||||
if (
|
||||
!packageJson.dependencies['@angular/forms'] &&
|
||||
!packageJson.devDependencies['@angular/forms']
|
||||
) {
|
||||
devDependencies['@angular/forms'] = '*';
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!packageJson.dependencies['@angular/forms'] &&
|
||||
!packageJson.devDependencies['@angular/forms']
|
||||
schema.uiFramework === '@storybook/web-components-vite' ||
|
||||
schema.uiFramework === '@storybook/web-components-webpack5'
|
||||
) {
|
||||
devDependencies['@angular/forms'] = '*';
|
||||
devDependencies['lit-html'] = litHtmlVersion;
|
||||
}
|
||||
}
|
||||
|
||||
if (isFramework('react', schema)) {
|
||||
devDependencies['@storybook/react'] = storybookVersion;
|
||||
devDependencies['@svgr/webpack'] = svgrVersion;
|
||||
devDependencies['url-loader'] = urlLoaderVersion;
|
||||
devDependencies['babel-loader'] = babelLoaderVersion;
|
||||
devDependencies['@babel/core'] = babelCoreVersion;
|
||||
devDependencies['@babel/preset-typescript'] = babelPresetTypescriptVersion;
|
||||
devDependencies['@storybook/react'] = storybookVersion;
|
||||
}
|
||||
if (schema.uiFramework === '@storybook/react-native') {
|
||||
devDependencies['@storybook/addon-ondevice-actions'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-backgrounds'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-controls'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-notes'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['react-native-storybook-loader'] =
|
||||
reactNativeStorybookLoader;
|
||||
}
|
||||
} else {
|
||||
// TODO(katerina): Remove when Storybook v7
|
||||
if (schema.uiFramework === '@storybook/react-native') {
|
||||
devDependencies['@storybook/react-native'] = storybookReactNativeVersion;
|
||||
} else {
|
||||
devDependencies[schema.uiFramework] = storybookVersion;
|
||||
}
|
||||
|
||||
if (isFramework('html', schema)) {
|
||||
devDependencies['@storybook/html'] = storybookVersion;
|
||||
}
|
||||
devDependencies['@storybook/core-server'] = storybookVersion;
|
||||
devDependencies['@storybook/addon-essentials'] = storybookVersion;
|
||||
|
||||
if (isFramework('vue', schema)) {
|
||||
devDependencies['@storybook/vue'] = storybookVersion;
|
||||
}
|
||||
if (schema.bundler === 'vite') {
|
||||
devDependencies['@storybook/builder-vite'] = viteBuilderVersion;
|
||||
} else {
|
||||
devDependencies['@storybook/builder-webpack5'] = storybookVersion;
|
||||
devDependencies['@storybook/manager-webpack5'] = storybookVersion;
|
||||
}
|
||||
|
||||
if (isFramework('vue3', schema)) {
|
||||
devDependencies['@storybook/vue3'] = storybookVersion;
|
||||
}
|
||||
devDependencies['html-webpack-plugin'] = htmlWebpackPluginVersion;
|
||||
|
||||
if (isFramework('web-components', schema)) {
|
||||
devDependencies['@storybook/web-components'] = storybookVersion;
|
||||
devDependencies['lit-html'] = litHtmlVersion;
|
||||
}
|
||||
if (schema.uiFramework === '@storybook/angular') {
|
||||
devDependencies['webpack'] = webpack5Version;
|
||||
|
||||
if (isFramework('svelte', schema)) {
|
||||
devDependencies['@storybook/svelte'] = storybookVersion;
|
||||
}
|
||||
if (
|
||||
!packageJson.dependencies['@angular/forms'] &&
|
||||
!packageJson.devDependencies['@angular/forms']
|
||||
) {
|
||||
devDependencies['@angular/forms'] = '*';
|
||||
}
|
||||
}
|
||||
|
||||
if (isFramework('react-native', schema)) {
|
||||
devDependencies['@storybook/react-native'] = storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-actions'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-backgrounds'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-controls'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-notes'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['react-native-storybook-loader'] =
|
||||
reactNativeStorybookLoader;
|
||||
if (schema.uiFramework === '@storybook/react') {
|
||||
devDependencies['@svgr/webpack'] = svgrVersion;
|
||||
devDependencies['url-loader'] = urlLoaderVersion;
|
||||
devDependencies['babel-loader'] = babelLoaderVersion;
|
||||
devDependencies['@babel/core'] = babelCoreVersion;
|
||||
devDependencies['@babel/preset-typescript'] =
|
||||
babelPresetTypescriptVersion;
|
||||
}
|
||||
|
||||
if (schema.uiFramework === '@storybook/web-components') {
|
||||
devDependencies['lit-html'] = litHtmlVersion;
|
||||
}
|
||||
|
||||
if (schema.uiFramework === '@storybook/react-native') {
|
||||
devDependencies['@storybook/addon-ondevice-actions'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-backgrounds'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-controls'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['@storybook/addon-ondevice-notes'] =
|
||||
storybookReactNativeVersion;
|
||||
devDependencies['react-native-storybook-loader'] =
|
||||
reactNativeStorybookLoader;
|
||||
}
|
||||
}
|
||||
|
||||
return addDependenciesToPackageJson(host, dependencies, devDependencies);
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
import { UiFramework, UiFramework7 } from '../../utils/models';
|
||||
|
||||
export interface Schema {
|
||||
uiFramework:
|
||||
| '@storybook/angular'
|
||||
| '@storybook/react'
|
||||
| '@storybook/html'
|
||||
| '@storybook/web-components'
|
||||
| '@storybook/vue'
|
||||
| '@storybook/vue3'
|
||||
| '@storybook/svelte'
|
||||
| '@storybook/react-native';
|
||||
bundler?: 'webpack' | 'vite';
|
||||
uiFramework: UiFramework | UiFramework7;
|
||||
bundler?: 'webpack' | 'vite'; // TODO(katerina): Remove when Storybook 7
|
||||
storybook7betaConfiguration?: boolean;
|
||||
}
|
||||
|
||||
@ -10,6 +10,21 @@
|
||||
"description": "Storybook UI Framework to use.",
|
||||
"enum": [
|
||||
"@storybook/angular",
|
||||
"@storybook/html-webpack5",
|
||||
"@storybook/nextjs",
|
||||
"@storybook/preact-webpack5",
|
||||
"@storybook/react-webpack5",
|
||||
"@storybook/react-vite",
|
||||
"@storybook/server-webpack5",
|
||||
"@storybook/svelte-webpack5",
|
||||
"@storybook/svelte-vite",
|
||||
"@storybook/sveltekit",
|
||||
"@storybook/vue-webpack5",
|
||||
"@storybook/vue-vite",
|
||||
"@storybook/vue3-webpack5",
|
||||
"@storybook/vue3-vite",
|
||||
"@storybook/web-components-webpack5",
|
||||
"@storybook/web-components-vite",
|
||||
"@storybook/react",
|
||||
"@storybook/html",
|
||||
"@storybook/web-components",
|
||||
@ -28,6 +43,12 @@
|
||||
"x-prompt": "Which bundler do you want to use?",
|
||||
"default": "webpack",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"storybook7betaConfiguration": {
|
||||
"description": "Configure your workspace to use Storybook 7, even though Storybook v7 is still in beta.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "important"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
writeJson,
|
||||
formatFiles,
|
||||
} from '@nrwl/devkit';
|
||||
import { isFramework, TsConfig } from '../../utils/utilities';
|
||||
import { TsConfig } from '../../utils/utilities';
|
||||
|
||||
export default async function updateStorybookTsconfig(tree: Tree) {
|
||||
let changesMade = false;
|
||||
@ -37,10 +37,8 @@ export default async function updateStorybookTsconfig(tree: Tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isReactProject = isFramework('react', {
|
||||
uiFramework: targets[storybookExecutor]?.options
|
||||
?.uiFramework as Parameters<typeof isFramework>[1]['uiFramework'],
|
||||
});
|
||||
const isReactProject =
|
||||
targets[storybookExecutor]?.options?.uiFramework === '@storybook/react';
|
||||
|
||||
if (isReactProject) {
|
||||
const tsConfig = {
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
writeJson,
|
||||
} from '@nrwl/devkit';
|
||||
import * as path from 'path';
|
||||
import { isFramework, TsConfig } from '../../utils/utilities';
|
||||
import { TsConfig } from '../../utils/utilities';
|
||||
|
||||
export default async function addReactTypings(tree: Tree) {
|
||||
let changesMade = false;
|
||||
@ -40,10 +40,8 @@ export default async function addReactTypings(tree: Tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isReactProject = isFramework('react', {
|
||||
uiFramework: targets[storybookExecutor].options
|
||||
?.uiFramework as Parameters<typeof isFramework>[1]['uiFramework'],
|
||||
});
|
||||
const isReactProject =
|
||||
targets[storybookExecutor].options?.uiFramework === '@storybook/react';
|
||||
|
||||
if (isReactProject) {
|
||||
const tsConfig = {
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
writeJson,
|
||||
} from '@nrwl/devkit';
|
||||
import * as path from 'path';
|
||||
import { isFramework, TsConfig } from '../../utils/utilities';
|
||||
import { TsConfig } from '../../utils/utilities';
|
||||
|
||||
export default async function addStyledJsxTypings(tree: Tree) {
|
||||
let changesMade = false;
|
||||
@ -42,10 +42,8 @@ export default async function addStyledJsxTypings(tree: Tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isReactProject = isFramework('react', {
|
||||
uiFramework: targets[storybookExecutor].options
|
||||
?.uiFramework as Parameters<typeof isFramework>[1]['uiFramework'],
|
||||
});
|
||||
const isReactProject =
|
||||
targets[storybookExecutor].options?.uiFramework === '@storybook/react';
|
||||
|
||||
if (isReactProject) {
|
||||
const tsConfig = {
|
||||
|
||||
@ -1,19 +1,11 @@
|
||||
export interface StorybookConfig {
|
||||
configFolder?: string;
|
||||
configPath?: string;
|
||||
pluginPath?: string;
|
||||
srcRoot?: string;
|
||||
}
|
||||
|
||||
export interface CommonNxStorybookConfig {
|
||||
uiFramework?: UiFramework;
|
||||
uiFramework7?: UiFramework7;
|
||||
uiFramework?: UiFramework; // TODO(katerina): Remove when Storybook 7
|
||||
}
|
||||
|
||||
export type UiFramework7 =
|
||||
| '@storybook/angular'
|
||||
| '@storybook/html-webpack5'
|
||||
| '@storybook/next'
|
||||
| '@storybook/nextjs'
|
||||
| '@storybook/preact-webpack5'
|
||||
| '@storybook/react-webpack5'
|
||||
| '@storybook/react-vite'
|
||||
@ -6,10 +6,11 @@ import {
|
||||
} from '@nrwl/devkit';
|
||||
import { CompilerOptions } from 'typescript';
|
||||
import { storybookVersion } from './versions';
|
||||
import { StorybookConfig } from '../executors/models';
|
||||
import { statSync } from 'fs';
|
||||
import { findNodes } from 'nx/src/utils/typescript';
|
||||
import ts = require('typescript');
|
||||
import { gte } from 'semver';
|
||||
import { join } from 'path';
|
||||
|
||||
export const Constants = {
|
||||
addonDependencies: ['@storybook/addons'],
|
||||
@ -29,6 +30,24 @@ export const Constants = {
|
||||
svelte: '@storybook/svelte',
|
||||
'react-native': '@storybook/react-native',
|
||||
} as const,
|
||||
uiFrameworks7: [
|
||||
'@storybook/angular',
|
||||
'@storybook/html-webpack5',
|
||||
'@storybook/nextjs',
|
||||
'@storybook/preact-webpack5',
|
||||
'@storybook/react-webpack5',
|
||||
'@storybook/react-vite',
|
||||
'@storybook/server-webpack5',
|
||||
'@storybook/svelte-webpack5',
|
||||
'@storybook/svelte-vite',
|
||||
'@storybook/sveltekit',
|
||||
'@storybook/vue-webpack5',
|
||||
'@storybook/vue-vite',
|
||||
'@storybook/vue3-webpack5',
|
||||
'@storybook/vue3-vite',
|
||||
'@storybook/web-components-webpack5',
|
||||
'@storybook/web-components-vite',
|
||||
],
|
||||
};
|
||||
type Constants = typeof Constants;
|
||||
|
||||
@ -36,47 +55,13 @@ type Framework = {
|
||||
type: keyof Constants['uiFrameworks'];
|
||||
uiFramework: Constants['uiFrameworks'][keyof Constants['uiFrameworks']];
|
||||
};
|
||||
export function isFramework(
|
||||
type: Framework['type'],
|
||||
schema: Pick<Framework, 'uiFramework'>
|
||||
) {
|
||||
if (type === 'angular' && schema.uiFramework === '@storybook/angular') {
|
||||
return true;
|
||||
}
|
||||
if (type === 'react' && schema.uiFramework === '@storybook/react') {
|
||||
return true;
|
||||
}
|
||||
if (type === 'html' && schema.uiFramework === '@storybook/html') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
type === 'web-components' &&
|
||||
schema.uiFramework === '@storybook/web-components'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === 'vue' && schema.uiFramework === '@storybook/vue') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === 'vue3' && schema.uiFramework === '@storybook/vue3') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type === 'svelte' && schema.uiFramework === '@storybook/svelte') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
type === 'react-native' &&
|
||||
schema.uiFramework === '@storybook/react-native'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
export function isStorybookV7() {
|
||||
const storybookPackageVersion = require(join(
|
||||
'@storybook/core-server',
|
||||
'package.json'
|
||||
)).version;
|
||||
return gte(storybookPackageVersion, '7.0.0-alpha.0');
|
||||
}
|
||||
|
||||
export function safeFileDelete(tree: Tree, path: string): boolean {
|
||||
|
||||
@ -14,3 +14,5 @@ export const storybookNextAddonVersion = '^1.6.6';
|
||||
export const storybookTestRunnerVersion = '^0.7.2';
|
||||
export const litHtmlVersion = '^2.3.1';
|
||||
export const htmlWebpackPluginVersion = '^5.5.0';
|
||||
|
||||
export const storybook7Version = '^7.0.0-beta.25';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user