feat(nuxt): storybook generators (#19529)

This commit is contained in:
Katerina Skroumpelou 2023-10-12 17:31:34 +03:00 committed by GitHub
parent 89ab1c934b
commit cbeed02ee5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 772 additions and 46 deletions

View File

@ -1711,6 +1711,14 @@
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{
"name": "Set up Storybook for Angular Projects",
"path": "/recipes/storybook/overview-angular",
"id": "overview-angular",
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{ {
"name": "Set up Storybook for Vue Projects", "name": "Set up Storybook for Vue Projects",
"path": "/recipes/storybook/overview-vue", "path": "/recipes/storybook/overview-vue",
@ -1720,9 +1728,9 @@
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"path": "/recipes/storybook/overview-angular", "path": "/recipes/storybook/overview-nuxt",
"id": "overview-angular", "id": "overview-nuxt",
"isExternal": false, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
@ -2908,6 +2916,14 @@
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{
"name": "Set up Storybook for Angular Projects",
"path": "/recipes/storybook/overview-angular",
"id": "overview-angular",
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{ {
"name": "Set up Storybook for Vue Projects", "name": "Set up Storybook for Vue Projects",
"path": "/recipes/storybook/overview-vue", "path": "/recipes/storybook/overview-vue",
@ -2917,9 +2933,9 @@
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"path": "/recipes/storybook/overview-angular", "path": "/recipes/storybook/overview-nuxt",
"id": "overview-angular", "id": "overview-nuxt",
"isExternal": false, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
@ -3007,6 +3023,14 @@
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false
}, },
{
"name": "Set up Storybook for Angular Projects",
"path": "/recipes/storybook/overview-angular",
"id": "overview-angular",
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{ {
"name": "Set up Storybook for Vue Projects", "name": "Set up Storybook for Vue Projects",
"path": "/recipes/storybook/overview-vue", "path": "/recipes/storybook/overview-vue",
@ -3016,9 +3040,9 @@
"disableCollapsible": false "disableCollapsible": false
}, },
{ {
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"path": "/recipes/storybook/overview-angular", "path": "/recipes/storybook/overview-nuxt",
"id": "overview-angular", "id": "overview-nuxt",
"isExternal": false, "isExternal": false,
"children": [], "children": [],
"disableCollapsible": false "disableCollapsible": false

View File

@ -2133,6 +2133,16 @@
"path": "/recipes/storybook/overview-react", "path": "/recipes/storybook/overview-react",
"tags": ["storybook"] "tags": ["storybook"]
}, },
{
"id": "overview-angular",
"name": "Set up Storybook for Angular Projects",
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular",
"itemList": [],
"isExternal": false,
"path": "/recipes/storybook/overview-angular",
"tags": ["storybook"]
},
{ {
"id": "overview-vue", "id": "overview-vue",
"name": "Set up Storybook for Vue Projects", "name": "Set up Storybook for Vue Projects",
@ -2144,13 +2154,13 @@
"tags": ["storybook"] "tags": ["storybook"]
}, },
{ {
"id": "overview-angular", "id": "overview-nuxt",
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.", "description": "This guide explains how to set up Storybook for Nuxt projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular", "file": "shared/recipes/storybook/plugin-nuxt",
"itemList": [], "itemList": [],
"isExternal": false, "isExternal": false,
"path": "/recipes/storybook/overview-angular", "path": "/recipes/storybook/overview-nuxt",
"tags": ["storybook"] "tags": ["storybook"]
}, },
{ {
@ -3626,6 +3636,16 @@
"path": "/recipes/storybook/overview-react", "path": "/recipes/storybook/overview-react",
"tags": ["storybook"] "tags": ["storybook"]
}, },
{
"id": "overview-angular",
"name": "Set up Storybook for Angular Projects",
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular",
"itemList": [],
"isExternal": false,
"path": "/recipes/storybook/overview-angular",
"tags": ["storybook"]
},
{ {
"id": "overview-vue", "id": "overview-vue",
"name": "Set up Storybook for Vue Projects", "name": "Set up Storybook for Vue Projects",
@ -3637,13 +3657,13 @@
"tags": ["storybook"] "tags": ["storybook"]
}, },
{ {
"id": "overview-angular", "id": "overview-nuxt",
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.", "description": "This guide explains how to set up Storybook for Nuxt projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular", "file": "shared/recipes/storybook/plugin-nuxt",
"itemList": [], "itemList": [],
"isExternal": false, "isExternal": false,
"path": "/recipes/storybook/overview-angular", "path": "/recipes/storybook/overview-nuxt",
"tags": ["storybook"] "tags": ["storybook"]
}, },
{ {
@ -3751,6 +3771,16 @@
"path": "/recipes/storybook/overview-react", "path": "/recipes/storybook/overview-react",
"tags": ["storybook"] "tags": ["storybook"]
}, },
"/recipes/storybook/overview-angular": {
"id": "overview-angular",
"name": "Set up Storybook for Angular Projects",
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular",
"itemList": [],
"isExternal": false,
"path": "/recipes/storybook/overview-angular",
"tags": ["storybook"]
},
"/recipes/storybook/overview-vue": { "/recipes/storybook/overview-vue": {
"id": "overview-vue", "id": "overview-vue",
"name": "Set up Storybook for Vue Projects", "name": "Set up Storybook for Vue Projects",
@ -3761,14 +3791,14 @@
"path": "/recipes/storybook/overview-vue", "path": "/recipes/storybook/overview-vue",
"tags": ["storybook"] "tags": ["storybook"]
}, },
"/recipes/storybook/overview-angular": { "/recipes/storybook/overview-nuxt": {
"id": "overview-angular", "id": "overview-nuxt",
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.", "description": "This guide explains how to set up Storybook for Nuxt projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular", "file": "shared/recipes/storybook/plugin-nuxt",
"itemList": [], "itemList": [],
"isExternal": false, "isExternal": false,
"path": "/recipes/storybook/overview-angular", "path": "/recipes/storybook/overview-nuxt",
"tags": ["storybook"] "tags": ["storybook"]
}, },
"/recipes/storybook/configuring-storybook": { "/recipes/storybook/configuring-storybook": {

View File

@ -892,6 +892,13 @@
"name": "Set up Storybook for React Projects", "name": "Set up Storybook for React Projects",
"path": "/recipes/storybook/overview-react" "path": "/recipes/storybook/overview-react"
}, },
{
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular",
"id": "overview-angular",
"name": "Set up Storybook for Angular Projects",
"path": "/recipes/storybook/overview-angular"
},
{ {
"description": "This guide explains how to set up Storybook for Vue projects in your Nx workspace.", "description": "This guide explains how to set up Storybook for Vue projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-vue", "file": "shared/recipes/storybook/plugin-vue",
@ -900,11 +907,11 @@
"path": "/recipes/storybook/overview-vue" "path": "/recipes/storybook/overview-vue"
}, },
{ {
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.", "description": "This guide explains how to set up Storybook for Nuxt projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular", "file": "shared/recipes/storybook/plugin-nuxt",
"id": "overview-angular", "id": "overview-nuxt",
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"path": "/recipes/storybook/overview-angular" "path": "/recipes/storybook/overview-nuxt"
}, },
{ {
"description": "This guide explains how Storybook is configured on your Nx workspace.", "description": "This guide explains how Storybook is configured on your Nx workspace.",

View File

@ -72,6 +72,13 @@ nx g @nx/react:storybook-configuration my-react-project
nx g @nx/vue:storybook-configuration my-vue-project nx g @nx/vue:storybook-configuration my-vue-project
``` ```
{% /tab %}
{% tab label="Nuxt" %}
```shell
nx g @nx/nuxt:storybook-configuration my-nuxt-app
```
{% /tab %} {% /tab %}
{% tab label="React Native" %} {% tab label="React Native" %}
@ -84,7 +91,7 @@ nx g @nx/react-native:storybook-configuration my-react-native-project
These framework-specific generators will also **generate stories** and interaction tests for you. These framework-specific generators will also **generate stories** and interaction tests for you.
If you are NOT using a framework-specific generator (for [Angular](/nx-api/angular/generators/storybook-configuration), [React](/nx-api/react/generators/storybook-configuration), [React Native](/nx-api/react-native/generators/storybook-configuration), [Vue](/nx-api/vue/generators/storybook-configuration)), in the field `uiFramework` you must choose one of the following Storybook frameworks: If you are NOT using a framework-specific generator (for [Angular](/nx-api/angular/generators/storybook-configuration), [React](/nx-api/react/generators/storybook-configuration), [React Native](/nx-api/react-native/generators/storybook-configuration), [Vue](/nx-api/vue/generators/storybook-configuration), [Nuxt](/nx-api/nuxt/generators/storybook-configuration)), in the field `uiFramework` you must choose one of the following Storybook frameworks:
- `@storybook/angular` - `@storybook/angular`
- `@storybook/html-webpack5` - `@storybook/html-webpack5`
@ -111,7 +118,7 @@ Choosing one of these frameworks will have the following effects on your workspa
3. Nx will create new `targets` in your project's `project.json`, called `storybook`, `test-storybook` and `build-storybook`, containing all the necessary configuration to serve, test and build Storybook. 3. Nx will create new `targets` in your project's `project.json`, called `storybook`, `test-storybook` and `build-storybook`, containing all the necessary configuration to serve, test and build Storybook.
Make sure to **use the framework-specific generators** if your project is using Angular, React, Next.js or React Native: [`@nx/angular:storybook-configuration`](/nx-api/angular/generators/storybook-configuration), [`@nx/react:storybook-configuration`](/nx-api/react/generators/storybook-configuration), [`@nx/react-native:storybook-configuration`](/nx-api/react-native/generators/storybook-configuration), as shown above. Make sure to **use the framework-specific generators** if your project is using Angular, React, Next.js, Vue, Nuxt, or React Native: [`@nx/angular:storybook-configuration`](/nx-api/angular/generators/storybook-configuration), [`@nx/react:storybook-configuration`](/nx-api/react/generators/storybook-configuration), [`@nx/vue:storybook-configuration`](/nx-api/vue/generators/storybook-configuration), [`@nx/nuxt:storybook-configuration`](/nx-api/nuxt/generators/storybook-configuration), [`@nx/react-native:storybook-configuration`](/nx-api/react-native/generators/storybook-configuration), as shown above.
### Running Storybook ### Running Storybook
@ -211,6 +218,7 @@ You can find dedicated information for React and Angular:
- [Set up Storybook for Angular Projects](/recipes/storybook/overview-angular) - [Set up Storybook for Angular Projects](/recipes/storybook/overview-angular)
- [Set up Storybook for React Projects](/recipes/storybook/overview-react) - [Set up Storybook for React Projects](/recipes/storybook/overview-react)
- [Set up Storybook for Vue Projects](/recipes/storybook/overview-vue) - [Set up Storybook for Vue Projects](/recipes/storybook/overview-vue)
- [Set up Storybook for Nuxt Projects](/recipes/storybook/overview-nuxt)
You can find all Storybook-related Nx documentation in the [Storybook recipes section](/recipes/storybook). You can find all Storybook-related Nx documentation in the [Storybook recipes section](/recipes/storybook).

View File

@ -656,6 +656,13 @@
"description": "This guide explains how to set up Storybook for React projects in your Nx workspace.", "description": "This guide explains how to set up Storybook for React projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-react" "file": "shared/recipes/storybook/plugin-react"
}, },
{
"name": "Set up Storybook for Angular Projects",
"id": "overview-angular",
"tags": ["storybook"],
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular"
},
{ {
"name": "Set up Storybook for Vue Projects", "name": "Set up Storybook for Vue Projects",
"id": "overview-vue", "id": "overview-vue",
@ -664,11 +671,11 @@
"file": "shared/recipes/storybook/plugin-vue" "file": "shared/recipes/storybook/plugin-vue"
}, },
{ {
"name": "Set up Storybook for Angular Projects", "name": "Set up Storybook for Nuxt Projects",
"id": "overview-angular", "id": "overview-nuxt",
"tags": ["storybook"], "tags": ["storybook"],
"description": "This guide explains how to set up Storybook for Angular projects in your Nx workspace.", "description": "This guide explains how to set up Storybook for Nuxt projects in your Nx workspace.",
"file": "shared/recipes/storybook/plugin-angular" "file": "shared/recipes/storybook/plugin-nuxt"
}, },
{ {
"name": "Configuring Storybook on Nx", "name": "Configuring Storybook on Nx",

View File

@ -72,6 +72,13 @@ nx g @nx/react:storybook-configuration my-react-project
nx g @nx/vue:storybook-configuration my-vue-project nx g @nx/vue:storybook-configuration my-vue-project
``` ```
{% /tab %}
{% tab label="Nuxt" %}
```shell
nx g @nx/nuxt:storybook-configuration my-nuxt-app
```
{% /tab %} {% /tab %}
{% tab label="React Native" %} {% tab label="React Native" %}
@ -84,7 +91,7 @@ nx g @nx/react-native:storybook-configuration my-react-native-project
These framework-specific generators will also **generate stories** and interaction tests for you. These framework-specific generators will also **generate stories** and interaction tests for you.
If you are NOT using a framework-specific generator (for [Angular](/nx-api/angular/generators/storybook-configuration), [React](/nx-api/react/generators/storybook-configuration), [React Native](/nx-api/react-native/generators/storybook-configuration), [Vue](/nx-api/vue/generators/storybook-configuration)), in the field `uiFramework` you must choose one of the following Storybook frameworks: If you are NOT using a framework-specific generator (for [Angular](/nx-api/angular/generators/storybook-configuration), [React](/nx-api/react/generators/storybook-configuration), [React Native](/nx-api/react-native/generators/storybook-configuration), [Vue](/nx-api/vue/generators/storybook-configuration), [Nuxt](/nx-api/nuxt/generators/storybook-configuration)), in the field `uiFramework` you must choose one of the following Storybook frameworks:
- `@storybook/angular` - `@storybook/angular`
- `@storybook/html-webpack5` - `@storybook/html-webpack5`
@ -111,7 +118,7 @@ Choosing one of these frameworks will have the following effects on your workspa
3. Nx will create new `targets` in your project's `project.json`, called `storybook`, `test-storybook` and `build-storybook`, containing all the necessary configuration to serve, test and build Storybook. 3. Nx will create new `targets` in your project's `project.json`, called `storybook`, `test-storybook` and `build-storybook`, containing all the necessary configuration to serve, test and build Storybook.
Make sure to **use the framework-specific generators** if your project is using Angular, React, Next.js or React Native: [`@nx/angular:storybook-configuration`](/nx-api/angular/generators/storybook-configuration), [`@nx/react:storybook-configuration`](/nx-api/react/generators/storybook-configuration), [`@nx/react-native:storybook-configuration`](/nx-api/react-native/generators/storybook-configuration), as shown above. Make sure to **use the framework-specific generators** if your project is using Angular, React, Next.js, Vue, Nuxt, or React Native: [`@nx/angular:storybook-configuration`](/nx-api/angular/generators/storybook-configuration), [`@nx/react:storybook-configuration`](/nx-api/react/generators/storybook-configuration), [`@nx/vue:storybook-configuration`](/nx-api/vue/generators/storybook-configuration), [`@nx/nuxt:storybook-configuration`](/nx-api/nuxt/generators/storybook-configuration), [`@nx/react-native:storybook-configuration`](/nx-api/react-native/generators/storybook-configuration), as shown above.
### Running Storybook ### Running Storybook
@ -211,6 +218,7 @@ You can find dedicated information for React and Angular:
- [Set up Storybook for Angular Projects](/recipes/storybook/overview-angular) - [Set up Storybook for Angular Projects](/recipes/storybook/overview-angular)
- [Set up Storybook for React Projects](/recipes/storybook/overview-react) - [Set up Storybook for React Projects](/recipes/storybook/overview-react)
- [Set up Storybook for Vue Projects](/recipes/storybook/overview-vue) - [Set up Storybook for Vue Projects](/recipes/storybook/overview-vue)
- [Set up Storybook for Nuxt Projects](/recipes/storybook/overview-nuxt)
You can find all Storybook-related Nx documentation in the [Storybook recipes section](/recipes/storybook). You can find all Storybook-related Nx documentation in the [Storybook recipes section](/recipes/storybook).

View File

@ -0,0 +1,76 @@
---
title: Set up Storybook for Nuxt Projects
description: This guide explains how to set up Storybook for Nuxt projects in your Nx workspace.
---
# Set up Storybook for Nuxt Projects
This guide will walk you through setting up [Storybook](https://storybook.js.org) for Nuxt projects in your Nx workspace.
The generators for your Nuxt projects use the `@nx/vue:storybook-configuration` and `@nx/vue:stories` generators under the hood, with some additional configuration. There is no official support or settings for Nuxt3 in Storybook yet, so until then we are just configuring your Nuxt apps as if they were Vue apps, since the components are still Vue components.
{% callout type="warning" title="Set up Storybook in your workspace" %}
You first need to set up Storybook for your Nx workspace, if you haven't already. You can read the [Storybook plugin overview guide](/nx-api/storybook) to get started.
{% /callout %}
## Generate Storybook Configuration for a Nuxt project
You can generate Storybook configuration for an individual Nuxt project by using the [`@nx/nuxt:storybook-configuration` generator](/nx-api/nuxt/generators/storybook-configuration), like this:
```shell
nx g @nx/nuxt:storybook-configuration project-name
```
## Auto-generate Stories
The [`@nx/nuxt:storybook-configuration` generator](/nx-api/nuxt/generators/storybook-configuration) has the option to automatically generate `*.stories.ts` files for each component declared in your project, under the `components` directory. This makes sure that no stories are generated for your `pages` components. The stories will be generated using [Component Story Format 3 (CSF3)](https://storybook.js.org/blog/storybook-csf3-is-here/).
```text
<some-folder>/
├── MyComponent.vue
└── MyComponent.stories.ts
```
If you add more components to your project, and want to generate stories for all your (new) components at any point, you can use the [`@nx/nuxt:stories` generator](/nx-api/nuxt/generators/stories):
```shell
nx g @nx/nuxt:stories --project=<project-name>
```
{% callout type="note" title="Example" %}
Let's take for a example a Nuxt application in your workspace, under `my-nuxt-app`, called `my-nuxt-app`. This application contains a component, called `my-button`.
The command to generate stories for that application would be:
```shell
nx g @nx/nuxt:stories --project=my-nuxt-app
```
and the result would be the following:
```text
<workspace name>/
my-nuxt-app
├── nuxt.config.ts
├── project.json
├── src
│   ├── app.vue
│   ├── assets
│   ├── components
│   │   └── my-button
│   │   ├── my-button.stories.ts
│   │   └── my-button.vue
│   ├── pages
│   ├── public
│   └── server
├── tsconfig.json
└── tsconfig.storybook.json
```
{% /callout %}
## More Documentation
You can find all Storybook-related Nx topics [here](/nx-api#storybook).
For more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/vue/get-started/introduction).

View File

@ -112,8 +112,9 @@
- [Wait for Tasks to Finish](/recipes/node/wait-for-tasks) - [Wait for Tasks to Finish](/recipes/node/wait-for-tasks)
- [Storybook](/recipes/storybook) - [Storybook](/recipes/storybook)
- [Set up Storybook for React Projects](/recipes/storybook/overview-react) - [Set up Storybook for React Projects](/recipes/storybook/overview-react)
- [Set up Storybook for Vue Projects](/recipes/storybook/overview-vue)
- [Set up Storybook for Angular Projects](/recipes/storybook/overview-angular) - [Set up Storybook for Angular Projects](/recipes/storybook/overview-angular)
- [Set up Storybook for Vue Projects](/recipes/storybook/overview-vue)
- [Set up Storybook for Nuxt Projects](/recipes/storybook/overview-nuxt)
- [Configuring Storybook on Nx](/recipes/storybook/configuring-storybook) - [Configuring Storybook on Nx](/recipes/storybook/configuring-storybook)
- [One main Storybook instance for all projects](/recipes/storybook/one-storybook-for-all) - [One main Storybook instance for all projects](/recipes/storybook/one-storybook-for-all)
- [One Storybook instance per scope](/recipes/storybook/one-storybook-per-scope) - [One Storybook instance per scope](/recipes/storybook/one-storybook-per-scope)

View File

@ -1,4 +1,5 @@
import { import {
checkFilesExist,
cleanupProject, cleanupProject,
killPorts, killPorts,
newProject, newProject,
@ -8,11 +9,13 @@ import {
describe('Nuxt Plugin', () => { describe('Nuxt Plugin', () => {
let proj: string; let proj: string;
const app = uniq('app');
beforeAll(() => { beforeAll(() => {
proj = newProject({ proj = newProject({
unsetProjectNameAndRootFormat: false, unsetProjectNameAndRootFormat: false,
}); });
runCLI(`generate @nx/nuxt:app ${app} --unitTestRunner=none`);
}); });
afterAll(() => { afterAll(() => {
@ -21,13 +24,17 @@ describe('Nuxt Plugin', () => {
}); });
it('should build application', async () => { it('should build application', async () => {
const app = uniq('app');
runCLI(`generate @nx/nuxt:app ${app} --unitTestRunner=none`);
const result = runCLI(`build ${app}`); const result = runCLI(`build ${app}`);
expect(result).toContain( expect(result).toContain(
`Successfully ran target build for project ${app}` `Successfully ran target build for project ${app}`
); );
}); });
it('should build storybook for app', () => {
runCLI(
`generate @nx/vue:storybook-configuration ${app} --generateStories --no-interactive`
);
runCLI(`run ${app}:build-storybook --verbose`);
checkFilesExist(`dist/storybook/${app}/index.html`);
}, 300_000);
}); });

View File

@ -0,0 +1,38 @@
This generator will generate stories for all your components in your project. The stories will be generated using [Component Story Format 3 (CSF3)](https://storybook.js.org/blog/storybook-csf3-is-here/).
```bash
nx g @nx/nuxt:stories project-name
```
You can read more about how this generator works, in the [Storybook for Nuxt overview page](/recipes/storybook/overview-nuxt#auto-generate-stories).
When running this generator, you will be prompted to provide the following:
- The `name` of the project you want to generate the configuration for.
- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..
You must provide a `name` for the generator to work.
By default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/angular/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.
There are a number of other options available. Let's take a look at some examples.
## Examples
### Ignore certain paths when generating stories
```bash
nx g @nx/nuxt:stories --name=ui --ignorePaths=libs/ui/src/not-stories/**,**/**/src/**/*.other.*
```
This will generate stories for all the components in the `ui` project, except for the ones in the `libs/ui/src/not-stories` directory, 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 stories using JavaScript instead of TypeScript
```bash
nx g @nx/nuxt:stories --name=ui --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.

View File

@ -0,0 +1,55 @@
This generator will set up Storybook for your **Nuxt** project. You can also use this generator to generate Storybook configuration for your **Next.js** project. By default, starting Nx 16, Storybook v7 is used.
```bash
nx g @nx/nuxt:storybook-configuration project-name
```
You can read more about how this generator works, in the [Storybook for Nuxt overview page](/recipes/storybook/overview-nuxt#generate-storybook-configuration-for-a-nuxt-project).
When running this generator, you will be prompted to provide the following:
- The `name` of the project you want to generate the configuration for.
- Whether you want to set up [Storybook interaction tests](https://storybook.js.org/docs/nuxt/writing-tests/interaction-testing) (`interactionTests`). If you choose `yes`, a `play` function will be added to your stories, and all the necessary dependencies will be installed. Also, 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/nuxt/writing-tests/test-runner). You can read more about this in the [Nx Storybook interaction tests documentation page](/packages/storybook/documents/interaction-tests)..
- 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.
You must provide a `name` for the generator to work.
By default, this generator will also set up [Storybook interaction tests](https://storybook.js.org/docs/nuxt/writing-tests/interaction-testing). If you don't want to set up Storybook interaction tests, you can pass the `--interactionTests=false` option, but it's not recommended.
There are a number of other options available. Let's take a look at some examples.
## Examples
### Generate Storybook configuration
```bash
nx g @nx/nuxt:storybook-configuration ui
```
This will generate Storybook configuration for the `ui` project using TypeScript for the Storybook configuration files (the files inside the `.storybook` directory, eg. `.storybook/main.ts`).
### Ignore certain paths when generating stories
```bash
nx g @nx/nuxt:storybook-configuration ui --generateStories=true --ignorePaths="libs/ui/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts"
```
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 stories using JavaScript instead of TypeScript
```bash
nx g @nx/nuxt: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 using JavaScript
```bash
nx g @nx/nuxt:storybook-configuration ui --tsConfiguration=false
```
By default, our generator generates TypeScript Storybook configuration files. You can choose to use JavaScript for the Storybook configuration files of your project (the files inside the `.storybook` directory, eg. `.storybook/main.js`).

View File

@ -27,6 +27,18 @@
"schema": "./src/generators/page/schema.json", "schema": "./src/generators/page/schema.json",
"x-type": "page", "x-type": "page",
"description": "Create a new page for your Nuxt application." "description": "Create a new page for your Nuxt application."
},
"storybook-configuration": {
"factory": "./src/generators/storybook-configuration/configuration",
"schema": "./src/generators/storybook-configuration/schema.json",
"description": "Set up storybook for a Nuxt app.",
"hidden": false
},
"stories": {
"factory": "./src/generators/stories/stories",
"schema": "./src/generators/stories/schema.json",
"description": "Create stories for all components declared in an app or library.",
"hidden": false
} }
} }
} }

View File

@ -0,0 +1,64 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxNuxtStorybookStories",
"title": "Generate Nuxt Storybook stories",
"description": "Generate stories/specs for all components declared in a project.",
"type": "object",
"properties": {
"project": {
"type": "string",
"aliases": ["name", "projectName"],
"description": "Project for which to generate stories.",
"$default": {
"$source": "projectName",
"index": 0
},
"x-prompt": "For which project do you want to generate stories?",
"x-priority": "important"
},
"generateCypressSpecs": {
"type": "boolean",
"description": "Automatically generate `*.spec.ts` files in the cypress e2e app generated by the cypress-configure generator."
},
"cypressProject": {
"type": "string",
"description": "The Cypress project to generate the stories under. This is inferred from `project` by default."
},
"interactionTests": {
"type": "boolean",
"description": "Set up Storybook interaction tests.",
"x-prompt": "Do you want to set up Storybook interaction tests?",
"x-priority": "important",
"default": true
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files.",
"default": false
},
"ignorePaths": {
"type": "array",
"description": "Paths to ignore when looking for components.",
"items": {
"type": "string",
"description": "Path to ignore."
},
"examples": [
"apps/my-app/src/not-stories/**",
"**/**/src/**/not-stories/**",
"libs/my-lib/**/*.something.ts",
"**/**/src/**/*.other.*",
"libs/my-lib/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts"
]
},
"skipFormat": {
"description": "Skip formatting files.",
"type": "boolean",
"default": false,
"x-priority": "internal"
}
},
"required": ["project"],
"examplesFile": "../../../docs/stories-examples.md"
}

View File

@ -0,0 +1,21 @@
import { runTasksInSerial, Tree } from '@nx/devkit';
import {
storiesGenerator as vueStoriesGenerator,
StorybookStoriesSchema,
} from '@nx/vue';
/*
* This generator is basically the Vue one
*/
export async function storiesGenerator(
host: Tree,
options: StorybookStoriesSchema
) {
const storiesGenerator = await vueStoriesGenerator(host, {
...options,
});
return runTasksInSerial(storiesGenerator);
}
export default storiesGenerator;

View File

@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`nuxt:storybook-configuration should configure with vue3 framework and styles import 1`] = `
"import type { StorybookConfig } from '@storybook/vue3-vite';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import { mergeConfig } from 'vite';
const config: StorybookConfig = {
stories: ['../src/components/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'],
framework: {
name: '@storybook/vue3-vite',
options: {},
},
viteFinal: async (config) =>
mergeConfig(config, {
plugins: [nxViteTsPaths()],
}),
};
export default config;
// To customize your Vite configuration you can use the viteFinal field.
// Check https://storybook.js.org/docs/react/builders/vite#configuration
// and https://nx.dev/recipes/storybook/custom-builder-configs
"
`;
exports[`nuxt:storybook-configuration should configure with vue3 framework and styles import 2`] = `""`;

View File

@ -0,0 +1,98 @@
import { logger, Tree } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Linter } from '@nx/linter';
import applicationGenerator from '../application/application';
import componentGenerator from '../component/component';
import storybookConfigurationGenerator from './configuration';
const componentContent = `<script setup lang="ts">
defineProps<{
name: string;
displayAge: boolean;
age: number;
}>();
</script>
<template>
<p>Welcome to Vlv!</p>
</template>
<style scoped>
</style>
`;
describe('nuxt:storybook-configuration', () => {
let appTree;
beforeEach(async () => {
jest.spyOn(logger, 'warn').mockImplementation(() => {});
jest.spyOn(logger, 'debug').mockImplementation(() => {});
jest.resetModules();
});
afterEach(() => {
jest.restoreAllMocks();
});
it('should configure with vue3 framework and styles import', async () => {
appTree = await createTestApp('test-ui-app');
await storybookConfigurationGenerator(appTree, {
name: 'test-ui-app',
});
expect(
appTree.read('test-ui-app/.storybook/main.ts', 'utf-8')
).toMatchSnapshot();
expect(
appTree.read('test-ui-app/.storybook/preview.ts', 'utf-8')
).toMatchSnapshot();
expect(appTree.exists('test-ui-app/tsconfig.storybook.json')).toBeTruthy();
});
it('should generate stories for components and not pages', async () => {
appTree = await createTestApp('test-ui-app');
appTree.write(
'test-ui-app/src/components/my-component/my-component.vue',
componentContent
);
appTree.write('test-ui-app/src/pages/about.vue', componentContent);
await storybookConfigurationGenerator(appTree, {
name: 'test-ui-app',
generateStories: true,
});
expect(
appTree.exists(
'test-ui-app/src/components/my-component/my-component.stories.ts'
)
).toBeTruthy();
expect(
appTree.exists('test-ui-app/src/pages/about.stories.ts')
).toBeFalsy();
});
});
export async function createTestApp(
appName: string,
plainJS = false
): Promise<Tree> {
let appTree = createTreeWithEmptyWorkspace();
await applicationGenerator(appTree, {
e2eTestRunner: 'none',
linter: Linter.EsLint,
skipFormat: false,
style: 'css',
unitTestRunner: 'none',
name: appName,
js: plainJS,
projectNameAndRootFormat: 'as-provided',
});
await componentGenerator(appTree, {
name: 'my-component',
project: appName,
});
return appTree;
}

View File

@ -0,0 +1,37 @@
import {
formatFiles,
readProjectConfiguration,
runTasksInSerial,
Tree,
} from '@nx/devkit';
import { storybookConfigurationGenerator as vueStorybookConfigurationGenerator } from '@nx/vue';
import { Schema } from './schema';
/*
* This generator is basically the Vue one, but for Nuxt we
* are just adding the styles in `.storybook/preview.ts`
*/
export async function storybookConfigurationGenerator(
host: Tree,
options: Schema
) {
const storybookConfigurationGenerator =
await vueStorybookConfigurationGenerator(host, {
...options,
});
const projectConfiguration = readProjectConfiguration(host, options.name);
const storybookConfigFolder =
projectConfiguration.targets?.storybook?.options?.configDir;
host.write(
`${storybookConfigFolder}/preview.${options.tsConfiguration ? 'ts' : 'js'}`,
`import '../src/assets/css/styles.css';`
);
await formatFiles(host);
return runTasksInSerial(storybookConfigurationGenerator);
}
export default storybookConfigurationGenerator;

View File

@ -0,0 +1,12 @@
import { Linter } from '@nx/linter';
export interface Schema {
name: string;
interactionTests?: boolean;
generateStories?: boolean;
js?: boolean;
tsConfiguration?: boolean;
linter?: Linter;
ignorePaths?: string[];
configureStaticServe?: boolean;
}

View File

@ -0,0 +1,77 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxNuxtStorybookConfigure",
"title": "Nuxt Storybook Configure",
"description": "Set up Storybook for a Nuxt project.",
"type": "object",
"properties": {
"name": {
"type": "string",
"aliases": ["project", "projectName"],
"description": "Project for which to generate Storybook configuration.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "For which project do you want to generate Storybook configuration?",
"x-dropdown": "projects",
"x-priority": "important"
},
"interactionTests": {
"type": "boolean",
"description": "Set up Storybook interaction tests.",
"x-prompt": "Do you want to set up Storybook interaction tests?",
"x-priority": "important",
"alias": ["configureTestRunner"],
"default": true
},
"generateStories": {
"type": "boolean",
"description": "Automatically generate `*.stories.ts` files for components declared in this project?",
"x-prompt": "Automatically generate *.stories.ts files for components declared in this project?",
"default": true,
"x-priority": "important"
},
"configureStaticServe": {
"type": "boolean",
"description": "Specifies whether to configure a static file server target for serving storybook. Helpful for speeding up CI build/test times.",
"x-prompt": "Configure a static file server for the storybook instance?",
"default": true,
"x-priority": "important"
},
"js": {
"type": "boolean",
"description": "Generate JavaScript story files rather than TypeScript story files.",
"default": false
},
"tsConfiguration": {
"type": "boolean",
"description": "Configure your project with TypeScript. Generate main.ts and preview.ts files, instead of main.js and preview.js.",
"default": true
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": ["eslint"],
"default": "eslint"
},
"ignorePaths": {
"type": "array",
"description": "Paths to ignore when looking for components.",
"items": {
"type": "string",
"description": "Path to ignore."
},
"examples": [
"apps/my-app/src/not-stories/**",
"**/**/src/**/not-stories/**",
"libs/my-lib/**/*.something.ts",
"**/**/src/**/*.other.*",
"libs/my-lib/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts"
]
}
},
"required": ["name"],
"examplesFile": "../../../docs/storybook-configuration-examples.md"
}

View File

@ -2,6 +2,11 @@ export * from './src/utils/versions';
export { applicationGenerator } from './src/generators/application/application'; export { applicationGenerator } from './src/generators/application/application';
export { libraryGenerator } from './src/generators/library/library'; export { libraryGenerator } from './src/generators/library/library';
export { componentGenerator } from './src/generators/component/component'; export { componentGenerator } from './src/generators/component/component';
export { storybookConfigurationGenerator } from './src/generators/storybook-configuration/configuration';
export {
storiesGenerator,
StorybookStoriesSchema,
} from './src/generators/stories/stories';
export { type InitSchema } from './src/generators/init/schema'; export { type InitSchema } from './src/generators/init/schema';
export { vueInitGenerator } from './src/generators/init/init'; export { vueInitGenerator } from './src/generators/init/init';
export { addJest } from './src/generators/application/lib/add-jest'; export { addJest } from './src/generators/application/lib/add-jest';

View File

@ -28,6 +28,95 @@ export default config;
" "
`; `;
exports[`vue:storybook-configuration should generate stories for components 1`] = `null`; exports[`vue:storybook-configuration should generate stories for components 1`] = `
"import type { Meta, StoryObj } from '@storybook/vue3';
import myComponent from './my-component.vue';
exports[`vue:storybook-configuration should generate stories for components without interaction tests 1`] = `null`; import { within } from '@storybook/testing-library';
import { expect } from '@storybook/jest';
const meta: Meta<typeof myComponent> = {
component: myComponent,
title: 'myComponent',
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary = {
args: {
name: 'name',
displayAge: false,
age: 0,
},
};
export const Heading: Story = {
args: {
name: 'name',
displayAge: false,
age: 0,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.getByText(/Welcome to myComponent!/gi)).toBeTruthy();
},
};
"
`;
exports[`vue:storybook-configuration should generate stories for components for app 1`] = `
"import type { Meta, StoryObj } from '@storybook/vue3';
import myComponent from './my-component.vue';
import { within } from '@storybook/testing-library';
import { expect } from '@storybook/jest';
const meta: Meta<typeof myComponent> = {
component: myComponent,
title: 'myComponent',
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary = {
args: {
name: 'name',
displayAge: false,
age: 0,
},
};
export const Heading: Story = {
args: {
name: 'name',
displayAge: false,
age: 0,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.getByText(/Welcome to myComponent!/gi)).toBeTruthy();
},
};
"
`;
exports[`vue:storybook-configuration should generate stories for components without interaction tests 1`] = `
"import type { Meta, StoryObj } from '@storybook/vue3';
import myComponent from './my-component.vue';
const meta: Meta<typeof myComponent> = {
component: myComponent,
title: 'myComponent',
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary = {
args: {
name: 'name',
displayAge: false,
age: 0,
},
};
"
`;

View File

@ -66,6 +66,11 @@ describe('vue:storybook-configuration', () => {
it('should generate stories for components', async () => { it('should generate stories for components', async () => {
appTree = await createTestUILib('test-ui-lib'); appTree = await createTestUILib('test-ui-lib');
appTree.write(
'test-ui-lib/src/components/my-component/my-component.vue',
componentContent
);
await storybookConfigurationGenerator(appTree, { await storybookConfigurationGenerator(appTree, {
name: 'test-ui-lib', name: 'test-ui-lib',
generateStories: true, generateStories: true,
@ -74,6 +79,12 @@ describe('vue:storybook-configuration', () => {
expect( expect(
appTree.exists('test-ui-lib/src/components/test-ui-lib.stories.ts') appTree.exists('test-ui-lib/src/components/test-ui-lib.stories.ts')
).toBeTruthy(); ).toBeTruthy();
expect(
appTree.read(
'test-ui-lib/src/components/my-component/my-component.stories.ts',
'utf-8'
)
).toMatchSnapshot();
}); });
it('should configure everything at once', async () => { it('should configure everything at once', async () => {
@ -86,8 +97,12 @@ describe('vue:storybook-configuration', () => {
expect(appTree.exists('test-ui-app/tsconfig.storybook.json')).toBeTruthy(); expect(appTree.exists('test-ui-app/tsconfig.storybook.json')).toBeTruthy();
}); });
it('should generate stories for components', async () => { it('should generate stories for components for app', async () => {
appTree = await createTestAppLib('test-ui-app'); appTree = await createTestAppLib('test-ui-app');
appTree.write(
'test-ui-app/src/components/my-component/my-component.vue',
componentContent
);
await storybookConfigurationGenerator(appTree, { await storybookConfigurationGenerator(appTree, {
name: 'test-ui-app', name: 'test-ui-app',
generateStories: true, generateStories: true,
@ -103,6 +118,10 @@ describe('vue:storybook-configuration', () => {
it('should generate stories for components without interaction tests', async () => { it('should generate stories for components without interaction tests', async () => {
appTree = await createTestAppLib('test-ui-app'); appTree = await createTestAppLib('test-ui-app');
appTree.write(
'test-ui-app/src/components/my-component/my-component.vue',
componentContent
);
await storybookConfigurationGenerator(appTree, { await storybookConfigurationGenerator(appTree, {
name: 'test-ui-app', name: 'test-ui-app',
generateStories: true, generateStories: true,