nx/docs/generated/packages/storybook.json
Katerina Skroumpelou 742686a051
docs(storybook): best practices guide and recipe (#12071)
* docs(storybook): best practices guide and recipe

* docs(storybook): rearrange structure
2022-09-21 13:53:50 -04:00

516 lines
101 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"githubRoot": "https://github.com/nrwl/nx/blob/master",
"name": "storybook",
"packageName": "@nrwl/storybook",
"description": "The Nx Plugin for Storybook contains executors and generators for allowing your workspace to use the powerful Storybook integration testing & documenting capabilities.",
"root": "/packages/storybook",
"source": "/packages/storybook/src",
"documentation": [
{
"id": "overview",
"name": "Overview Generic",
"path": "/packages/storybook",
"file": "shared/guides/storybook/plugin-overview",
"content": "![Storybook logo](/shared/storybook-logo.png)\n\n[Storybook](https://storybook.js.org) is a development environment for UI components. It allows you to browse a component library, view the different states of each component, and interactively develop and test components.\n\nThis guide will briefly walk you through using Storybook within an Nx workspace.\n\n## Setting Up Storybook\n\n### Add the Storybook plugin\n\n```bash\nyarn add --dev @nrwl/storybook\n```\n\n## Using Storybook\n\n### Generating Storybook Configuration\n\nYou can generate Storybook configuration for an individual project with this command:\n\n```bash\nnx g @nrwl/storybook:configuration project-name\n```\n\nYou can choose to use Storybook for one of the supported frameworks:\n\n- `@storybook/angular`\n- `@storybook/react`\n- `@storybook/react-native`\n- `@storybook/html`\n- `@storybook/web-components`\n- `@storybook/vue`\n- `@storybook/vue3`\n- `@storybook/svelte`\n\nChoosing one of these frameworks will have the following effects on your workspace:\n\n1. Nx will install all the required Storybook packages that go with it.\n\n2. 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.\n\n3. 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.\n\n4. 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.\n\n5. Nx will generate a new Cypress e2e app for your project (if there isn't one already) to run against the Storybook instance.\n\n### Configure your project using TypeScript\n\nYou can choose to configure your project using TypeScript instead of JavaScript. To do that, just add the `--tsConfiguration=true` flag to the above command, like this:\n\n```bash\nnx g @nrwl/storybook:configuration project-name --tsConfiguration=true\n```\n\n[Here is the Storybook documentation](https://storybook.js.org/docs/react/configure/overview#configure-your-project-with-typescript) if you want to learn more.\n\n### Running Storybook\n\nServe Storybook using this command:\n\n```bash\nnx run project-name:storybook\n```\n\nor\n\n```bash\nnx storybook project-name\n```\n\n### Building Storybook\n\nBuild Storybook using this command:\n\n```bash\nnx run project-name:build-storybook\n```\n\nor\n\n```bash\nnx build-storybook project-name\n```\n\n### Anatomy of the Storybook setup\n\nWhen running the Nx Storybook generator, it'll configure the Nx workspace to be able to run Storybook seamlessly. It'll create\n\n- a global Storybook configuration\n- a project specific Storybook configuration\n\nThe **global** Storybook configuration allows to set addon-ons or custom webpack configuration at a global level that applies to all Storybook's within the Nx workspace. You can find that folder at `.storybook/` at the root of the workspace.\n\n```treeview\n<workspace name>/\n├── .storybook/\n│ ├── main.js\n│ ├── tsconfig.json\n├── apps/\n├── libs/\n├── nx.json\n├── package.json\n├── README.md\n└── etc...\n```\n\nThe project-specific Storybook configuration is pretty much similar what you would have for a non-Nx setup of Storybook. There's a `.storybook` folder within the project root folder.\n\n```treeview\n<project root>/\n├── .storybook/\n│ ├── main.js\n│ ├── preview.js\n│ ├── tsconfig.json\n├── src/\n├── README.md\n├── tsconfig.json\n└── etc...\n```\n\n### Using Addons\n\nTo register a [Storybook addon](https://storybook.js.org/addons/) for all storybook instances in your workspace:\n\n1. In `/.storybook/main.js`, in the `addons` array of the `module.exports` object, add the new addon:\n ```typescript\n module.exports = {\n stories: [...],\n ...,\n addons: [..., '@storybook/addon-essentials'],\n };\n ```\n2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js`, you can export an array called `decorators`.\n\n ```typescript\n import someDecorator from 'some-storybook-addon';\n export const decorators = [someDecorator];\n ```\n\n**-- OR --**\n\nTo register an [addon](https://storybook.js.org/addons/) for a single storybook instance, go to that project's `.storybook` folder:\n\n1. In `main.js`, in the `addons` array of the `module.exports` object, add the new addon:\n ```typescript\n module.exports = {\n stories: [...],\n ...,\n addons: [..., '@storybook/addon-essentials'],\n };\n ```\n2. If a decorator is required, in `preview.js` you can export an array called `decorators`.\n\n ```typescript\n import someDecorator from 'some-storybook-addon';\n export const decorators = [someDecorator];\n ```\n\n## More Documentation\n\nYou can find dedicated information for React and Angular:\n\n- [Set up Storybook for Angular Projects](/storybook/overview-angular)\n- [Set up Storybook for React Projects](/storybook/overview-react)\n\nYou can find all Storybook-related Nx documentation [here](/packages#storybook).\n\nFor more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/basics/introduction/).\n\n### Migration Scenarios\n\nHere's more information on common migration scenarios for Storybook with Nx. For Storybook specific migrations that are not automatically handled by Nx please refer to the [official Storybook page](https://storybook.js.org/)\n\n- [Upgrading to Storybook 6](/storybook/upgrade-storybook-v6-react)\n- [Migrate to the Nrwl React Storybook Preset](/storybook/migrate-webpack-final-react)\n"
},
{
"id": "overview-react",
"name": "Set up Storybook for React Projects",
"file": "shared/guides/storybook/plugin-react",
"content": "# Set up Storybook for React Projects\n\n![Storybook logo](/shared/storybook-logo.png)\n\nThis guide will walk you through setting up [Storybook](https://storybook.js.org) for React projects in your Nx workspace.\n\n{% callout type=\"warning\" title=\"Set up Storybook in your workspace\" %}\nYou first need to set up Storybook for your Nx workspace, if you haven't already. You can read the [Storybook plugin overview guide](/packages/storybook) to get started.\n{% /callout %}\n\n## Generate Storybook Configuration for a React project\n\nYou can generate Storybook configuration for an individual React project with this command:\n\n```bash\nnx g @nrwl/react:storybook-configuration project-name\n```\n\n## Nx React Storybook Preset\n\n`@nrwl/react` ships with a Storybook preset to make sure it uses the very same configuration as your Nx React application. When you generate a Storybook configuration for a project, it'll automatically add the preset to your configuration.\n\n```typescript\nconst rootMain = require('../../../.storybook/main');\n\nmodule.exports = {\n ...rootMain,\n addons: [...rootMain.addons, '@nrwl/react/plugins/storybook'],\n ...\n};\n```\n\n## Auto-generate Stories\n\nThe `@nrwl/react:storybook-configuration` generator has the option to automatically generate `*.stories.ts` files for each component declared in the library.\n\n```treeview\n<some-folder>/\n├── my.component.ts\n└── my.component.stories.ts\n```\n\nYou can re-run it at a later point using the following command:\n\n```bash\nnx g @nrwl/react:stories <project-name>\n```\n\n{% callout type=\"note\" title=\"Example\" %}\n\nLet's take for a example a library in your workspace, under `libs/feature/ui`, called `feature-ui`. This library contains a component, called `my-button`.\n\nThe command to generate stories for that library would be:\n\n```bash\nnx g @nrwl/react:stories feature-ui\n```\n\nand the result would be the following:\n\n```treeview\n<workspace name>/\n├── .storybook/\n├── apps/\n├── libs/\n│ ├── feature/\n│ │ ├── ui/\n| | | ├── .storybook/\n| | | ├── src/\n| | | | ├──lib\n| | | | | ├──my-button\n| | | | | | ├── my-button.component.ts\n| | | | | | ├── my-button.component.stories.ts\n| | | | | | └── etc...\n| | | | | └── etc...\n| | | ├── README.md\n| | | ├── tsconfig.json\n| | | └── etc...\n| | └── etc...\n| └── etc...\n├── nx.json\n├── package.json\n├── README.md\n└── etc...\n```\n\n{% /callout %}\n\n## Cypress tests for Stories\n\nThe `storybook-configuration` generator gives the option to set up an e2e Cypress app that is configured to run against the project's Storybook instance.\n\nTo launch Storybook and run the Cypress tests against the iframe inside of Storybook:\n\n```bash\nnx run project-name-e2e:e2e\n```\n\nThe url that Cypress points to should look like this:\n\n`'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'`\n\n- `buttoncomponent` is a lowercase version of the `Title` in the `*.stories.ts` file.\n- `primary` is the name of an individual story.\n- `style=default` sets the `style` arg to a value of `default`.\n\nChanging args in the url query parameters allows your Cypress tests to test different configurations of your component. You can [read the documentation](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) for more information.\n\n## Example Files\n\n**\\*.stories.tsx file**\n\n```typescript\nimport { Story, Meta } from '@storybook/react';\nimport { Button, ButtonProps } from './button';\n\nexport default {\n component: Button,\n title: 'Button',\n} as Meta;\n\nconst Template: Story<ButtonProps> = (args) => <Button {...args} />;\n\nexport const Primary = Template.bind({});\nPrimary.args = {\n text: 'Click me!',\n padding: 0,\n style: 'default',\n};\n```\n\n**Cypress test file**\n\n> Depending on your Cypress version, the file will end with .spec.ts or .cy.ts\n\n```typescript\ndescribe('shared-ui', () => {\n beforeEach(() =>\n cy.visit(\n '/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'\n )\n );\n\n it('should render the component', () => {\n cy.get('storybook-trial-button').should('exist');\n });\n});\n```\n\n## More Documentation\n\nYou can find all Storybook-related Nx topics [here](/packages#storybook).\n\nFor more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/react/get-started/introduction).\n\n### Migration Scenarios\n\nHere's more information on common migration scenarios for Storybook with Nx. For Storybook specific migrations that are not automatically handled by Nx please refer to the [official Storybook page](https://storybook.js.org/)\n\n- [Upgrading to Storybook 6](/storybook/upgrade-storybook-v6-react)\n- [Migrate to the Nrwl React Storybook Preset](/storybook/migrate-webpack-final-react)\n"
},
{
"id": "overview-angular",
"name": "Set up Storybook for Angular Projects",
"file": "shared/guides/storybook/plugin-angular",
"content": "# Set up Storybook for Angular Projects\n\n![Storybook logo](/shared/storybook-logo.png)\n\nThis guide will walk you through setting up [Storybook](https://storybook.js.org) for Angular projects in your Nx workspace.\n\n{% callout type=\"warning\" title=\"Set up Storybook in your workspace\" %}\nYou first need to set up Storybook for your Nx workspace, if you haven't already. You can read the [Storybook plugin overview guide](/packages/storybook) to get started.\n{% /callout %}\n\n## Generate Storybook Configuration for an Angular project\n\nYou can generate Storybook configuration for an individual Angular project with this command:\n\n```bash\nnx g @nrwl/angular:storybook-configuration project-name\n```\n\n## Auto-generate Stories\n\nThe `@nrwl/angular:storybook-configuration` generator has the option to automatically generate `*.stories.ts` files for each component declared in the library.\n\n```treeview\n<some-folder>/\n├── my.component.ts\n└── my.component.stories.ts\n```\n\nYou can re-run it at a later point using the following command:\n\n```bash\nnx g @nrwl/angular:stories <project-name>\n```\n\n{% callout type=\"note\" title=\"Example\" %}\n\nLet's take for a example a library in your workspace, under `libs/feature/ui`, called `feature-ui`. This library contains a component, called `my-button`.\n\nThe command to generate stories for that library would be:\n\n```bash\nnx g @nrwl/angular:stories feature-ui\n```\n\nand the result would be the following:\n\n```treeview\n<workspace name>/\n├── .storybook/\n├── apps/\n├── libs/\n│ ├── feature/\n│ │ ├── ui/\n| | | ├── .storybook/\n| | | ├── src/\n| | | | ├──lib\n| | | | | ├──my-button\n| | | | | | ├── my-button.component.ts\n| | | | | | ├── my-button.component.stories.ts\n| | | | | | └── etc...\n| | | | | └── etc...\n| | | ├── README.md\n| | | ├── tsconfig.json\n| | | └── etc...\n| | └── etc...\n| └── etc...\n├── nx.json\n├── package.json\n├── README.md\n└── etc...\n```\n\n{% /callout %}\n\n## Cypress tests for Stories\n\nThe `storybook-configuration` generator gives the option to set up an e2e Cypress app that is configured to run against the project's Storybook instance.\n\nTo launch Storybook and run the Cypress tests against the iframe inside of Storybook:\n\n```bash\nnx run project-name-e2e:e2e\n```\n\nThe url that Cypress points to should look like this:\n\n`'/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'`\n\n- `buttoncomponent` is a lowercase version of the `Title` in the `*.stories.ts` file.\n- `primary` is the name of an individual story.\n- `style=default` sets the `style` arg to a value of `default`.\n\nChanging args in the url query parameters allows your Cypress tests to test different configurations of your component. You can [read the documentation](https://storybook.js.org/docs/angular/writing-stories/args#setting-args-through-the-url) for more information.\n\n## Example Files\n\n**\\*.component.stories.ts file**\n\n```typescript\nimport { moduleMetadata, Story, Meta } from '@storybook/angular';\nimport { ButtonComponent } from './button.component';\n\nexport default {\n title: 'ButtonComponent',\n component: ButtonComponent,\n decorators: [\n moduleMetadata({\n imports: [],\n }),\n ],\n} as Meta<ButtonComponent>;\n\nconst Template: Story<ButtonComponent> = (args: ButtonComponent) => ({\n props: args,\n});\n\nexport const Primary = Template.bind({});\nPrimary.args = {\n text: 'Click me!',\n padding: 0,\n style: 'default',\n};\n```\n\n**Cypress test file**\n\n> Depending on your Cypress version, the file will end with .spec.ts or .cy.ts\n\n```typescript\ndescribe('shared-ui', () => {\n beforeEach(() =>\n cy.visit(\n '/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'\n )\n );\n\n it('should render the component', () => {\n cy.get('storybook-trial-button').should('exist');\n });\n});\n```\n\n## More Documentation\n\n- [Information about the `storybook` targets](/storybook/angular-storybook-targets)\n- [Configuring styles and preprocessor options](/storybook/angular-configuring-styles)\n- [The `browserTarget`](/storybook/angular-browser-target)\n\nYou can find all Storybook-related Nx topics [here](/packages#storybook).\n\nFor more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/react/get-started/introduction).\n\n### Migration Scenarios\n\nHere's more information on common migration scenarios for Storybook with Nx. For Storybook specific migrations that are not automatically handled by Nx please refer to the [official Storybook page](https://storybook.js.org/)\n\n- [Upgrading to Storybook 6](/storybook/upgrade-storybook-v6-angular)\n- [Migrate to the new Storybook `webpackFinal` config](/storybook/migrate-webpack-final-angular)\n"
},
{
"id": "best-practices",
"name": "Storybook best practices for making the most out of Nx",
"file": "shared/guides/storybook/best-practices",
"content": "# Storybook best practices for making the most out of Nx\n\n## Purpose of this guide\n\nThe purpose of this guide is to help you [set up Storybook in your Nx workspace](/packages/storybook) so that you can get the most out of Nx and its powerful capabilities.\n\n## When to use Storybook\n\nUsually, Storybook is mainly used for two reasons. Testing and documentation. You can read more on when and why to use Storybook in the [Why Storybook in 2022?](https://storybook.js.org/blog/why-storybook-in-2022/) article and also in the [Introduction to Storybook](https://storybook.js.org/docs/react/get-started/introduction) documentation page.\n\n### Testing\n\nStorybook helps you test your UIs. You can read more about testing with Storybook in the [How to test your UIs with Storybook](https://storybook.js.org/docs/react/writing-tests/introduction) documentation page. Essentially, Storybook uses the stories as a starting point for testing.\n\n### Documentation\n\nStorybook helps you document your UI elements, or your design system, effectively and in an interactive way. You can read more in the [How to document components](https://storybook.js.org/docs/react/writing-docs/introduction) documentation page. Essentially, you can use Storybook to publish a catalog of your components. A catalog that you can share with the design team, the developer team, the product team, anyone else in the product development process, or even the client. The components are isolated, interactive, and can be represented in all possible forms that they can take (eg. for a button: enabled, disabled, active, etc). You can read more about publishing your Storybook in the [Publish Storybook](https://storybook.js.org/docs/react/sharing/publish-storybook) documentation page.\n\n## Nx and Storybook\n\nNow lets see how Nx can be used to accommodate both of these pillars of Storybook. Nx takes lots of the burden off your arms when setting up Storybook initially. It essentially provides you with all that you need to start using Storybooks capabilities (testing and documentation) right away, without having to write a single line of code.\n\n### Development tools\n\nFirst, lets see what Nx offers, when you are in the process of developing a project with Storybook.\n\n#### Configuration generation\n\nYou can generate the Storybook configuration files and settings using the Nx [`@nrwl/storybook:configuration` generator](/packages/storybook/generators/configuration). You can read more about configuring Storybook with Nx in our [`@nrwl/storybook` package overview page](/packages/storybook#generating-storybook-configuration). With Nx, you configure Storybook for each individual project.\n\n#### Stories generation\n\nIf you are on a project using Angular, React or React Native, you can also generate stories for your components. You can do so either by using each package's `storybook-configuration` generators or by using the `stories` generator, if you already have Storybook configured for your project.\n\nIf your project is not configured yet, check out one of these guides:\n\n- [Set up Storybook for React Projects](/storybook/overview-react)\n\n- [Set up Storybook for Angular Projects](/storybook/overview-angular)\n\nIf your project is [already configured](/packages/storybook), you can use the `stories` generator:\n\n- [React stories generator](/packages/react/generators/stories)\n\n- [React Native stories generator](/packages/react-native/generators/stories)\n\n- [Angular stories generator](/packages/angular/generators/stories)\n\nThe stories generator will read your inputs (if youre using Angular), or your props (if you're using React), and will generate stories with the corresponding arguments/controls already prefilled.\n\n#### Cypress tests generation\n\nNx also generates Cypress tests for your components, that point to the corresponding components story. You can read more about how the Cypress tests are generated and how they look like in the [storybook-configuration generator documentation](/storybook/overview-react#cypress-tests-for-stories).\n\nTake a look at the generated code of the Cypress test file, specifically at the URL which Cypress visits:\n\n```javascript\ncy.visit(\n '/iframe.html?id=buttoncomponent--primary&args=text:Click+me!;padding;style:default'\n);\n```\n\nCypress visits the URL that hosts the story of the component we are testing, adding values to its controls (eg. `args=text:Click+me!`). Then, the test attempts to validate that the values are correctly applied.\n\n### CI/CD tools\n\nNow lets see how Nx helps in the CI/CD journey, as well.\n\n#### Cypress testing\n\nWhen you are running the Cypress tests for a project, Cypress will start the Storybook server of that project. The Storybook server will fire up a Storybook instance, hosting all the components's stories for that project. The e2e tests will then run, which actually visit the stories and perform the tests there. Cypress will be configured to start and stop the Storybook server. The results will be cached, and they will go through the Nx graph, meaning that Nx will know if the tests need to be run again or not, depending on the affected status of your project.\n\n#### Serve\n\nWhen you are configuring Storybook, Nx [adds a serve and a build target for Storybook](/packages/storybook#generating-storybook-configuration) in your `project.json`, as we explained above. You can use these targets to [serve](/packages/storybook/executors/storybook) and [build](/packages/storybook/executors/build) storybook locally, and also in production. Cypress will also use these targets when firing up the e2e tests. While developing, you can serve your Storybooks locally to see if your components work and look as expected. This can help you and speed up the development and debugging process (no need to fire up a complex dev stack).\n\n#### Build and deploy\n\nThe build and deploy step usually comes in handy when you are ready to use Storybook for documentation, and you want to publish it. The [building](/packages/storybook/executors/build) step of Storybook is integrated in the Nx ecosystem, as explained above, and you can trigger your Storybook builds as you would trigger any other build inside your workspace.\n\nWhen you publish your organizations Storybook, as a result, ideally, you would want to have one shareable Storybook page/application living under one URL, that you can share. With Nx, you can build your Storybook and it will be ready for deployment. **However**, at this point, you have one Storybook per project in your workspace, and you could end up with far too many Storybooks that are built and ready for deployment. This is not ideal, and does not accomplish the ultimate goal of “one shareable documentation page”.\n\nIn the following section, we are going to see how to set up Storybook in these cases, to get the most out of Nx.\n\n## How to set up Storybook to get the most out of Nx\n\n### Philosophy\n\nSetting up Storybook on Nx reflects - and takes advantage of - the [mental model](/concepts/mental-model) of Nx, and especially the architecture of [Applications and Libraries](/more-concepts/applications-and-libraries). What that means, in essence, is that you still maintain the individual Storybook instances (per project) which you use for testing and local development, but you also keep one extra “container” for publishing, that serves as a single entry point. Lets see this in more detail.\n\n#### Local development and testing\n\n##### Development and debugging\n\nIn the process of setting up Storybook in your Nx workspace that we described above, you end up with one Storybook instance per project. That way, you can use your projects Storybook targets to serve and build Storybook:\n\n```bash\nnx storybook my-project\n```\n\nand\n\n```bash\nnx build-storybook my-project\n```\n\nThis feature is extremely useful when developing locally. The containerized stories in your Storybook are the only ones that are built/served when you want to debug just one component, or just one library. You dont have to wait for a huge Storybook containing all your stories in your repository to fire up. You just need to wait for the Storybook of a single project to start. This speeds up the process.\n\n##### E2e tests with Cypress\n\nIf youre using Cypress, and youre taking advantage of the generated Cypress tests that our Storybook generators generate, then your e2e tests are also going to be much faster. When you run your e2e tests for a particular project, Cypress is only going to start the specific Storybook instance, and its going to take much less time than having to start an all-including universal Storybook.\n\n##### Caching, affected, dependency management\n\nSince each Storybook, in this case, is attached to a project, so is the serving of Storybook and the building of Storybook and the e2e tests for that project. That means that Nx is aware of these tasks, so it caches them, it knows when to fetch them from the cache or re-run them according to the affected status of that project. It also knows that projects dependencies and knows which things to rebuild before each task.\n\n#### Publishing\n\nWhen you are publishing your Storybook, you can follow the same principles described in the [Applications and Libraries Mental Model](/more-concepts/applications-and-libraries#mental-model) documentation page. The general idea is to have one central Storybook container, into which you are going to gather your stories from multiple libraries.\n\nYou can think of the central Storybook container as a grouping of similar-concept or same-scope UI parts of your workspace. In the same way you are scoping libraries, you can group your stories as well.\n\nThen, according to your use-case, you can have one central Storybook for your whole workspace, importing all the stories from all the projects. Alternatively, you can have one Storybook per \"scope\", which imports all the stories from projects the same scope. Or even one Storybook per application, importing all the stories of all the libraries that it is depending on. As you can see, there are many options, and you can choose the one that best suits your needs.\n\n{% callout type=\"note\" title=\"Storybook Composition\" %}\nIn order to achieve some of the things mentioned above, you may use [Storybook Composition](/storybook/storybook-composition-setup). However, in this case, you would still need to build each projects Storybook individually, and also deploy it individually. So in the cases where you have multiple projects, Storybook Composition would not be very efficient.\n{% /callout %}\n\nBefore moving on to the examples section, it could be useful to read the [Library Types](/more-concepts/library-types) documentation page and the [Grouping libraries](/more-concepts/grouping-libraries) documentation page. These could help you decide which way fits your use case better.\n\n## Examples / Use cases\n\nYou can check out the following examples (recipes) to see publishing strategies for Storybook in Nx:\n\n- [One main Storybook instance for all projects](/recipe/one-storybook-for-all)\n- [One Storybook instance per scope](/recipe/one-storybook-per-scope)\n- [One main Storybook instance using Storybook Composition](/recipe/one-storybook-with-composition)\n\n## Conclusion\n\nIn this guide, we have given a direction towards the most efficient way to use Storybook in a Nx workspace, in a way that takes advantage of the all that Nx has to offer.\nWe have covered the different ways to set up Storybook, and publish it, too. We have also covered the different use cases that apply to each of the solutions.\n\nIf you have any questions or suggestions, please feel free to reach out to us on [GitHub](https://github.com/nrwl/nx), and don't hesitate to ask your questions or share your stories in our [Nx community Slack](https://join.slack.com/t/nrwlcommunity/shared_invite/zt-1fmyh7hib-MsIDqDDxoutA1gqeFHCnyA).\n\n### Nx & Storybook documentation\n\nYou can find all Storybook-related Nx documentation in the [packages page](/packages#storybook).\n"
},
{
"id": "storybook-composition-setup",
"name": "Setting up Storybook Composition with Nx",
"file": "shared/guides/storybook/storybook-composition-setup",
"content": "# Setting up Storybook Composition with Nx\n\n## What is Storybook Composition\n\nAs explained in the [Storybook official docs](https://storybook.js.org/docs/angular/workflows/storybook-composition), Storybook Composition allows you to embed components from any Storybook inside your local Storybook. If you want to learn more about Storybook Composition, please take a look at the following articles, which explain it in detail:\n\n- [Storybook Composition - Chromatic blog](https://www.chromatic.com/blog/storybook-composition/)\n- [Storybook Composition - Storybook docs](https://storybook.js.org/docs/angular/workflows/storybook-composition)\n\n## How it works\n\nIn essence, you have a Storybook running, which will be the host of the embeded Storybooks as well. Then, you provide this \"host\" Storybook with a URL of a live/running Storybook. The composed Storybook is then displayed in a new Canvas iframe as part of the host Storybook, and is listed on the left-hand-side stories inventory, too. You can read more about this in the docs listed above.\n\n## How to use it\n\nAll you need is a URL of a live Storybook, and a \"host\" Storybook. In the `.storybook/main.js` file of the \"host\" Storybook, inside `module.exports` you add a new `refs` attribute, which will contain the link(s) for the composed Storybook(s).\n\nIn the example below, we have a host Storybook running on local port 4400 (http://localhost:4400) - not displayed here. In it, we want to compose three other Storybooks. The \"one-composed\" and \"two-composed\", running on local ports `4401` and `4402` accordingly, as well as the [Storybook website's Storybook](https://next--storybookjs.netlify.app/official-storybook) which is live on the address that you see.\n\n```javascript\n// .storybook/main.js of our Host Storybook - assuming it's running on port 4400\nmodule.exports = {\n ...,\n refs: {\n 'one-composed': {\n title: 'One composed',\n url: 'http://localhost:4401',\n },\n 'two-composed': {\n title: 'Two composed',\n url: 'http://localhost:4402',\n },\n 'storybook-website-storybook': {\n title: 'The Storybook of the Storybook website',\n url: 'https://next--storybookjs.netlify.app/official-storybook/',\n },\n },\n};\n```\n\nYou can always read more in the [official Storybook docs](https://storybook.js.org/docs/angular/workflows/storybook-composition#compose-published-storybooks).\n\n## How to use it in Nx\n\nIt's quite easy to use this feature, in Nx and in general, since you do not need to make any code changes, you just need to have the \"composed\" Storybook instances (the ones you need to \"compose\") running, choose a \"host\" Storybook, and just add the composed Storybooks in it's `.storybook/main.js` file.\n\nNx provides the [`run-many`](/nx/run-many) command, which will allow you to easily run multiple Storybooks at the same time. You need to run the `run-many` command with the parallel flag (eg. `--parallel=3`), because you want to run all your Storybooks in parallel. You can change the value of the `parallel` flag to be of as many Storybooks you want to run in parallel as you need. However, be **very carefull** with putting large numbers in this\nflag, since it can cause big delays or get stuck. You can play around and adjust that number to one your machine runs comfortably with. Keep in mind that you can add in this feature however many live/public Storybooks as you need (Storybooks that you do not run locally).\n\nIn order to get get it working for you, you need to two two things:\n\n1. Make sure your \"composed\" Storybook instances are running. For that you can do:\n\n```bash\nnx run-many --target=storybook --projects=one-composed,two-composed,three-composed --parallel=3\n```\n\n2. Start your host Storybook in another tab of your terminal:\n\n```bash\nnx storybook main-host\n```\n\nBefore doing the above steps to actually compose our Storybook instances under the **`main-host`** project, we would need to do the following adjustments to our workspace:\n\n### Adjust the Storybook ports in `project.json`\n\nTake a look in your `project.json` file of each one of your projects (eg. for the `main-host` project, you can find it in the path `apps/main-host/project.json`).\nIn your project's targets, in the `storybook` target, you will notice that the default port that Nx assigns to your projects' Storybook is always `4400`:\n\n```json\n{\n ...\n \"targets\": {\n ...\n \"storybook\": {\n ...\n \"options\": {\n ...\n \"port\": 4400,\n ...\n },\n ...\n },\n ...\n` },\n}\n```\n\nWe can keep this port for the project which will serve as the host of our configuration, but we must change the port numbers of the other projects, the projects which will be composed/composed. The reason for that is the following:\n\n- When the `nx run-many --target=storybook --parallel=3` command executes, it will go and look into your `project.json` file to see the port you have assigned for that project's Storybook.\n- When it finds a port that it is already used, it will change the port number randomly (usually adding `1` until it finds an empty port).\n\nSince we are using the `--parallel` flag, and the commands are executed in parallel, we cannot know for sure the order that the `storybook` command will be executed. So, we cannot be sure which port will correspond to which of the projects.\n\nIf we don't change the port numbers, and there are projects that want to use the same port for their Storybooks, the `run-many` command will change that port, and the result will be that we will not know for sure which\nof our projects runs on which port. The problem that this creates is that we will not be able to create the proper configuration for Storybook Composition, since we will not be able to tell which URLs our composed Storybooks run on.\n\n### Add the refs in our host project's `.storybook/main.js` file\n\nNow, we need to add to our host project's `main.js` file (the path of which would be `apps/main-host/.storybook/main.js`) a `refs` object, to configure our composition. An example of such a configuration looks like this:\n\n```javascript\nmodule.exports = {\n ...,\n refs: {\n one-composed: {\n title: 'One composed',\n url: 'http://localhost:4401',\n },\n two-composed: {\n title: 'Two composed',\n url: 'http://localhost:4402',\n },\n three-composed: {\n title: 'Three composed',\n url: 'http://localhost:4403',\n },\n },\n};\n```\n\n### Optional: use `run-commands` and create a `storybook-composition` target\n\nIf you want to take advantage of the [`run-commands`](https://nx.dev/packages/workspace/executors/run-commands) functionality of Nx, you can create a custom target that will invoke the `run-parallel` command for your \"composed\" Storybook instances.\n\nThe objective is to end up with a new target in your `main-host`'s `project.json` file (`apps/main-host/project.json`) that looks like this:\n\n```json\n \"storybook-composition\": {\n \"executor\": \"nx:run-commands\",\n \"options\": {\n \"commands\": [\n \"nx storybook one-composed\",\n \"nx storybook two-composed\",\n \"nx storybook three-composed\"\n ],\n \"parallel\": true\n }\n }\n```\n\nwhich you can then invoke like this:\n\n```bash\nnx run main-host:storybook-composition\n```\n\nwhich will take care of starting all your \"composed\" Storybook instances, before you run `nx storybook main-host`.\n\n#### Generating a new `target` in our `main-host`\n\nLet's first generate a new `target` called `storybook-composition` for our `main-host`.\n\nRun the following command:\n\n```bash\nnx generate nx:run-commands storybook-composition --command='nx storybook one-composed' --project=main-host\n```\n\nThis will create a new `target` in your `apps/main-host/project.json`:\n\n```json\n \"storybook-composition\": {\n \"executor\": \"nx:run-commands\",\n \"outputs\": [],\n \"options\": {\n \"command\": \"nx storybook one-composed\"\n }\n }\n```\n\nNow, change the `command` option to be `commands`, add the `\"parallel\": true` option, and add all the other \"composed\" Storybook commands:\n\n```json\n \"storybook-composition\": {\n \"executor\": \"nx:run-commands\",\n \"options\": {\n \"commands\": [\n \"nx storybook one-composed\",\n \"nx storybook two-composed\",\n \"nx storybook three-composed\"\n ],\n \"parallel\": true\n }\n }\n```\n\nNow, you can start all your \"composed\" Storybook instances by running:\n\n```bash\nnx run main-host:storybook-composition\n```\n\n**After** all of your \"composed\" Storybook instances have started, you can run in a new terminal:\n\n```bash\nnx storybook main-host\n```\n\nThis approach takes the \"burden\" of writing the `run-many` command manually, and makes it easier to add/remove \"composed\" Storybook instances.\n"
},
{
"id": "angular-storybook-targets",
"name": "Angular: Information about the Storybook targets",
"file": "shared/guides/storybook/angular-storybook-targets",
"content": "{% callout type=\"note\" title=\"Note\" %}\nThis documentation page contains information about the [Storybook plugin](/packages/storybook), specifically regarding [Angular projects that are using Storybook](/storybook/overview-angular).\n{% /callout %}\n\n## Information about `storybook` and `build-storybook` targets for Angular projects with a Storybook configuration\n\nIf you are on Nx version `>=14.1.8`, the [Nx Storybook plugin for _Angular_ projects](/storybook/overview-angular) uses the original Storybook executors for Angular (`\"@storybook/angular:start-storybook\"` and `\"@storybook/angular:build-storybook\"`) to serve and build Storybook.\n\nThat means that you can use the official [Storybook for Angular documentation (expand the \"Troubleshooting\" section)](https://storybook.js.org/docs/angular/get-started/install#troubleshooting) to configure the options for serving and building Storybook.\n\n## Moving your project targets to the new (native Storybook) schema\n\nIf you are on Nx version `<14.1.8` and you want to move to the latest version (or any version `>=14.1.8`) you can use the `nx migrate` command, which will take care of migrating your Storybook targets across all your Angular projects using Storybook to use the new schema, the original Storybook executors for Angular. The configuration changes that you need to make will be handled automatically by Nx, so you will not have to do any manual work.\n\nIf you have already moved on a version of Nx `>=14.1.8` without using `nx migrate` and now you are having trouble with with your Angular projects using Storybook (eg. `Property 'uiFramework' does not match the schema. '@storybook/angular' should be one of ...`), that means that your targets are still using the old schema and they should change. For that, you can use the [`change-storybook-targets` generator](/packages/storybook/generators/change-storybook-targets) which will take care of changing your `storybook` and `build-storybook` targets across your workspace for your Angular projects using Storybook.\n"
},
{
"id": "angular-configuring-styles",
"name": "Angular: Configuring styles and preprocessor options",
"file": "shared/guides/storybook/angular-configuring-styles",
"content": "{% callout type=\"note\" title=\"Note\" %}\nThis documentation page contains information about the [Storybook plugin](/packages/storybook), specifically regarding [Angular projects that are using Storybook](/storybook/overview-angular).\n{% /callout %}\n\n## Configuring styles and preprocessor options for Angular projects with a Storybook configuration\n\nAngular supports including extra entry-point files for styles. Also, in case you use Sass, you can add extra base paths that will be checked for imports. In your project's `project.json` file you can use the `styles` and `stylePreprocessorOptions` properties in your `storybook` and `build-storybook` target `options`, as you would in your Storybook or your Angular configurations. If your project is an application, you can add these extra options in your `build` target. Your `storybook` and `build-storybook` `browserTarget` are going to be pointing to the `build` target, so they will pick up these styles from there. Check out the [Angular Workspace Configuration](https://angular.io/guide/workspace-config#styles-and-scripts-configuration) documentation for more information. You can also check the [official Storybook for Angular documentation](https://storybook.js.org/docs/angular/configure/styling-and-css) on working with styles and CSS.\n\nYour Storybook targets in your `project.json` will look like this:\n\n```json\n \"storybook\": {\n \"executor\": \"@storybook/angular:start-storybook\",\n \"options\": {\n ...\n \"styles\": [\"some-styles.css\"],\n \"stylePreprocessorOptions\": {\n \"includePaths\": [\"some-style-paths\"]\n }\n },\n ...\n },\n \"build-storybook\": {\n \"executor\": \"@storybook/angular:build-storybook\",\n ...\n \"options\": {\n ...\n \"styles\": [\"some-styles.css\"],\n \"stylePreprocessorOptions\": {\n \"includePaths\": [\"some-style-paths\"]\n }\n },\n ...\n }\n```\n\n### Using build-storybook for styles\n\nChances are, you will most probably need the same `styles` and `stylePreprocessorOptions` for your `storybook` and your `build-storybook` targets. Since you're using `browserTarget`, that means that Storybook will use the `options` of `build` or `build-storybook` when executing the `storybook` task (when compiling your Storybook). In that case, as explained, you _only_ need to add the `styles` or `stylePreprocessorOptions` to the corresponding target (`build` or `build-storybook`) that the `browserTarget` is pointing to. In that case, for example, the configuration shown above would look like this:\n\n```json\n \"storybook\": {\n \"executor\": \"@storybook/angular:start-storybook\",\n \"options\": {\n ...\n \"browserTarget\": \"my-project:build-storybook\"\n },\n ...\n },\n \"build-storybook\": {\n \"executor\": \"@storybook/angular:build-storybook\",\n ...\n \"options\": {\n ...\n \"browserTarget\": \"my-project:build-storybook\",\n \"styles\": [\"some-styles.css\"],\n \"stylePreprocessorOptions\": {\n \"includePaths\": [\"some-style-paths\"]\n }\n },\n ...\n }\n```\n"
},
{
"id": "angular-browser-target",
"name": "Angular: The browserTarget",
"file": "shared/guides/storybook/angular-browser-target",
"content": "{% callout type=\"note\" title=\"Note\" %}\nThis documentation page contains information about the [Storybook plugin](/packages/storybook), specifically regarding [Angular projects that are using Storybook](/storybook/overview-angular).\n{% /callout %}\n\n## The `browserTarget` for Angular projects with a Storybook configuration\n\n### Setting up `browserTarget`\n\nIf you're using [Storybook](/packages/storybook) in your Angular project, you will notice that `browserTarget` is specified for the `storybook` and `build-storybook` targets, much like it is done for `serve` or other targets. Angular needs the `browserTarget` for Storybook in order to know which configuration to use for the build. If your project is buildable (it has a `build` target, and uses the main Angular builder - `@angular-devkit/build-angular:browser`) the `browserTarget` for Storybook will use the `build` target, if it's not buildable it will use the `build-storybook` target.\nYou do not have to do anything manually. Nx will create the configuration for you. Even if you are migrating from an older version of Nx, Nx will make sure to change your `package.json` Storybook targets to match the new schema.\n\nYou can read more about the `browserTarget` in the [official Angular documentation](https://angular.io/cli/serve).\n\nYour Storybook targets in your `project.json` will look like this:\n\n```json\n \"storybook\": {\n \"executor\": \"@storybook/angular:start-storybook\",\n \"options\": {\n ...\n \"browserTarget\": \"my-project:build\"\n },\n ...\n },\n \"build-storybook\": {\n \"executor\": \"@storybook/angular:build-storybook\",\n ...\n \"options\": {\n ...\n \"browserTarget\": \"my-project:build\"\n },\n ...\n }\n```\n\nThis setup instructs Nx to use the configuration under the `build` target of `my-project` when using the `storybook` and `build-storybook` executors.\n\n### Setting up `projectBuildConfig` for Nx versions `<14.1.8`\n\n**_Careful: This is for older versions of Nx - for the latest version please look at the section above, about `browserTarget`_**\n\nIf you are on Nx version `<14.1.8`, you're still using our custom executor, which means that you have to comply by the Nx Storybook schema. This means that the contents of `browserTarget` should be placed in the `projectBuildConfig` property. This is telling Storybook where to get the build configuration from. To know more about the purpose of `browserTarget` (and `projectBuildConfig`) read the section above.\n\nIf you're using Nx version `>=13.4.6` either in a new Nx workspace, or you migrated your older Nx workspace to Nx version `>=13.4.6`, Nx will automatically add the `projectBuildConfig` property in your projects `project.json` files, for projects that are using Storybook.\n\nYour Storybook targets in your `project.json` will look like this:\n\n```json\n \"storybook\": {\n \"executor\": \"@nrwl/storybook:storybook\",\n \"options\": {\n ...\n \"projectBuildConfig\": \"my-project:build-storybook\"\n },\n ...\n },\n \"build-storybook\": {\n \"executor\": \"@nrwl/storybook:build\",\n ...\n \"options\": {\n ...\n \"projectBuildConfig\": \"my-project:build-storybook\"\n },\n ...\n }\n```\n\nThis setup instructs Nx to use the configuration under the `build-storybook` target of `my-project` when using the `storybook` and `build-storybook` executors.\n\n## Notes about the `defaultProject`\n\nStorybook for Angular needs a default project specified in order to run. The reason is that it uses that default project to read the build configuration from (paths to files to include in the build, and other configurations/settings). In a pure Angular/Storybook setup (**not** an Nx workspace), the Angular application/project would have an `angular.json` file. That file would have a property called `defaultProject`. In an Nx workspace the `defaultProject` property would be specified in the `nx.json` file. Previously, Nx would try to resolve the `defaultProject` of the workspace, and use the build configuration of that project. In most cases, the `defaultProject`'s build configuration would not work for some other project set up with Storybook, since there would most probably be mismatches in paths or other project-specific options.\n"
},
{
"id": "migrate-webpack-final-angular",
"name": "Angular: Storybook Webpack Migration",
"file": "shared/guides/storybook/migrate-webpack-final-angular",
"content": "# Storybook Webpack Migration\n\nNx 12.7 as in combination with Storybook v6.3 doesn't need a custom `webpack.config.js` which was previously required and auto-generated by Nx.\n\nHere are the main differences to the previous setups:\n\n- there's no `webpack.config.js`\n- custom webpack configurations can be added in the `webpackFinal` property of the `main.js` file\n\nHere's an example of a newly generated `main.js` file:\n\n```javascript\n// project-level .storybook/main.js file\nconst rootMain = require('../../../.storybook/main');\n\nmodule.exports = {\n ...rootMain,\n\n core: { ...rootMain.core, builder: 'webpack5' },\n\n stories: [\n ...rootMain.stories,\n '../src/lib/**/*.stories.mdx',\n '../src/lib/**/*.stories.@(js|jsx|ts|tsx)',\n ],\n addons: [...rootMain.addons],\n webpackFinal: async (config, { configType }) => {\n // apply any global webpack configs that might have been specified in .storybook/main.js\n if (rootMain.webpackFinal) {\n config = await rootMain.webpackFinal(config, { configType });\n }\n\n // add your own webpack tweaks if needed\n\n return config;\n },\n};\n```\n\nAt the Nx workspace root level, the configuration file looks as follows:\n\n```javascript\n// root level .storybook/main.js file\nmodule.exports = {\n stories: [],\n addons: ['@storybook/addon-essentials'],\n // uncomment the property below if you want to apply some webpack config globally\n // webpackFinal: async (config, { configType }) => {\n // // Make whatever fine-grained changes you need that should apply to all storybook configs\n\n // // Return the altered config\n // return config;\n // },\n};\n```\n\n## Migrating\n\nIf you're upgrading from a lower version of Nx, your old Storybook configuration will still work. New configurations generated will use the new syntax as shown above. The newly generated code will also make sure to extend from a global `webpack.config.js` which might exist in the root-level `.storybook/` directory of your Nx workspace.\n\nThis gives you the flexibility to incrementally migrate your configurations.\n\nHere's the step-by-step migration process:\n\n### 1. adjust the `main.js` file\n\nRestructure your `main.js` file so that it looks like in the example illustrated above.\n\nIf you need to keep your root-level `.storybook/webpack.config.js` for now, then make sure you adjust the `main.js` in a way that it properly calls the root-level `webpack.config.js` to inherit all of the global configurations.\n\n```javascript\nconst rootMain = require('../../../.storybook/main');\nconst rootWebpackConfig = require('../../../.storybook/webpack.config');\n\nmodule.exports = {\n ...rootMain,\n ...\n webpackFinal: async (config) => {\n // for backwards compatibility call the `rootWebpackConfig`\n // this can be removed once that one is migrated fully to\n // use the `webpackFinal` property in the `main.js` file\n config = rootWebpackConfig({ config });\n\n // add your own webpack tweaks if needed\n\n return config;\n },\n};\n```\n\n{% callout type=\"note\" title=\"Tip!\" %}\nThe easiest way is probably to generate a new library and Storybook configuration and then copy & paste the `main.js`.\n{% /callout %}\n\n### 2. Move any custom webpack configuration to `webpackFinal`\n\nIn previous versions of Nx a custom `webpack.config.js` was generated with the following content:\n\n```javascript\nconst TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');\nconst rootWebpackConfig = require('../../../.storybook/webpack.config');\n/**\n * Export a function. Accept the base config as the only param.\n *\n * @param {Parameters<typeof rootWebpackConfig>[0]} options\n */\nmodule.exports = async ({ config, mode }) => {\n config = await rootWebpackConfig({ config, mode });\n\n const tsPaths = new TsconfigPathsPlugin({\n configFile: './tsconfig.base.json',\n });\n\n config.resolve.plugins\n ? config.resolve.plugins.push(tsPaths)\n : (config.resolve.plugins = [tsPaths]);\n\n return config;\n};\n```\n\nSuch webpack file is no more needed as Storybook v6.3+ has proper TypeScript support already built-in now.\n\nIn case you made custom modifications to the `webpack.config.js` file, you need to move them over to the `main.js` `webpackFinal` property and then delete the `webpack.config.js`.\n\n### 3. Remove the root-level `.storybook/webpack.config.js` file\n\nOnce you've migrated all your libraries, you can think about removing the root-level `.storybook/webpack.config.js` file and migrate any custom configuration there to `.storybook/main.js` `webpackFinal` property in the very same folder.\n\n### 4. Opting in to Webpack 5\n\nIf you choose to opt-in to Webpack 5, by specifying `builder: 'webpack5'` in your project's `.storybook/main.(js|ts)` (as shown above, in the example of a newly generated `main.js` file), don't forget to add the Storybook dependencies for Webpack 5 to work:\n\n```shell\nyarn add -D @storybook/builder-webpack5 @storybook/manager-webpack5\n```\n\nor if you're using `npm`:\n\n```shell\nnpm install --save-dev @storybook/builder-webpack5 @storybook/manager-webpack5\n```\n"
},
{
"id": "upgrade-storybook-v6-angular",
"name": "Angular: Upgrading to Storybook 6",
"file": "shared/guides/storybook/storybook-v6-angular",
"content": "# Upgrading to Storybook 6 (and Nx versions >10.1.x and <14.0.0)\n\n_Disclaimer: From Nx 14.0.0 and on, Nx does not support Storybook v.5. If your workspace is on a version of Nx older than Nx 14, then you will be able to use the generators described in this guide. If you're using Nx >14, then you will already have been automatically migrated to Storybook 6._\n\nNx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).\n\nNx version `10.2.x` will continue to support Storybook version `5.2.x`, however newer versions of Nx will only support Storybook version `6` (and on).\n\nWhen you are running the Nx workspace migration script, your Storybook instances and configurations across your apps and libraries will NOT be migrated automatically. We chose not to migrate your Storybook instances and configurations across your apps and libraries automatically, since there a number of breaking changes that Storybook introduced in versions `5.3` and `6.0`, and making decisions on what to migrate automatically would risk the integrity of your code.\n\nInstead, when you choose to migrate from Nx versions `<10.1.x` to Nx versions `>10.2.x` (using the Nx migration script - `nx migrate`) we will keep your Storybook packages and Storybook instances and configurations intact. We suggest that you do the migration on your own, using the guide below, with all the references to the official Storybook migration guides. Look at the use cases below, and follow the one that matches your case.\n\n## Use Cases\n\n### Use case 1: Create an Nx workspace from scratch using the latest version of Nx\n\nIf you are creating an Nx workspace using the latest version of Nx, the latest version of Storybook (version 6) will be used as well. You do not need to do anything.\n\n### Use case 2: I already have an Nx workspace that does NOT use Storybook and I want to migrate to the latest Nx\n\nIf you already have an Nx workspace with a previous version of Nx that does NOT use Storybook, and you migrate to the latest Nx using the migrate scripts provided by Nx, and then, after the migration to the latest Nx, you choose to add Storybook, the latest version of Storybook will be used. You do not need to do anything.\n\n### Use case 3: I already have an Nx workspace with Storybook and I want to migrate to the latest Nx\n\nIn that case, when you run the Nx migration scripts, the scripts will ignore the Storybook packages, the Storybook configuration files, the Storybook instances in your apps and libraries, and all the generated stories. If you continue to add Storybook configurations and Storybook instances to new libraries and applications, then the version of Storybook that you already have will be used (most probably, if you have not changed anything manually, that version will be `5.3.9` using, however, the configuration files of `5.2`). You will have to do the [upgrade to the latest Storybook on your own, manually](#upgrading-to-storybook-6-manually). After that, Nx will use that version, and configure all new Storybook instances using the new version.\n\n## Upgrading to Storybook 6 using the Nx migration generator\n\n### Some info about the generator\n\nThe `@nrwl/angular:storybook-migrate-defaults-5-to-6` generator will not exactly do a migration. It will perform the following actions:\n\n- It will generate new Storybook configuration files using the new (`>6.x`) Storybook way. The way it will do that is, it will look in all the `project.json` files and it will find all the projects that have a `Storybook` configuration. Using the `configFolder` path provided there, it will go and generate new Storybook instances in all these paths. Finally, it will generate a new Storybook instance at the root directory.\n\n- If you choose to `keepOld`, then it will add all your existing Storybook configuration files into another folder labeled `.old_storybook`.\n\n- It will update all the Storybook-related (`@storybook/*`) packages in your `package.json`.\n\n### How to use the generator\n\nThat way, you can have working Storybook instances for all your projects just by running\n\n```bash\nnx g @nrwl/angular:storybook-migrate-defaults-5-to-6\n```\n\n### What if I had made changes to the defaults?\n\nIn case you had made customizations to the default Storybook configurations, you can then manually change each of your Storybook instance configuration files using the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) to make sure you use the new syntax. Your old configuration files are available to you to use as a reference.\n\nPlease check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).\n\n### What if I am not ready to change everything at once?\n\nThe generator gives you the option to migrate one project at a time. You can provide the `--name=PROJECT_NAME` flag, and then the generator will **only** generate new files for the specified project.\n\nPlease note that this option will NOT update all the Storybook-related (`@storybook/*`) packages in your `package.json`, or the root Storybook folder. The reason is that if you want to do the migration gradually, one project at a time, you want your old, existing, projects, to still work. That way, you will still be able to run your old, non-migrated Storybook projects. However, you will not be able to run any migrated Storbook projects. Once you have migrated all your Storybook projects, you can run `nx g @nrwl/angular:storybook-migrate-defaults-5-to-6` once again, and the generator will take care of updating all the Storybook-related (`@storybook/*`) packages in your `package.json` and it will also generate the new Storybook files for the root Storybook directory.\n\n### General tip:\n\n**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.\n\n## Upgrading to Storybook 6 manually\n\nThere is really no great reason for doing the migration completely manually. The `@nrwl/angular:storybook-migrate-defaults-5-to-6` generator [will take care of Steps 1, 2 and 3](#upgrading-to-storybook-6-using-the-nx-migration-generator). What you will need to do after running the generator is that you have to manually migrate any custom changes you had done to the default Storybook configuration files that were automatically generated by Nx when you first used Nx Storybook. To do the manual migration you should use the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).\n\nHowever, if you still want to do everything manually, these are the steps you should follow:\n\n### Step 0:\n\n**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.\n\n### Step 1: Changing the configuration files from version 5.2 to 5.3\n\nThe most noticeable change in Storybook versions newer than `5.2` is that the configuration files have changed names and content.\nQuoting from the [official Storybook migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x):\n\n- `presets.js` has been renamed to `main.js`. `main.js` is the main point of configuration for storybook.\n- `config.js` has been renamed to `preview.js`. `preview.js` configures the \"preview\" iframe that renders your components.\n- `addons.js` has been renamed to `manager.js`. `manager.js` configures Storybook's \"manager\" UI that wraps the preview, and also configures addons panel.\n\nPlease follow the [official Storybook version 5.2.x to 5.3.x migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x) to change your files accordingly.\n\nIf you are using Storybook using only the generated files after running the `storybook-configuration` generator, things might be easier for you. Please check the [sample files for a manual upgrade](#sample-files-for-manual-upgrade).\n\n### Step 2: Going from version 5.3 to 6.0\n\nPlease check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).\n\n- One big change in Storybook version `6` is that it has **built-in Typescript support**. This means that you can remove Typescript configurations from your configuration files.\n- Please also **check that your stories match any differences in syntax** introduced in versions `5.3` and `6.0`.\n\n### Step 3: Upgrade all `@storybook/*` packages in your project\n\nCheck your `package.json` file for all `@storybook` packages. Install the latest versions of these, using `yarn`:\n\nFor example:\n\n```bash\nyarn add --dev @storybook/angular@latest\n```\n\n### Step 4: Check that everything works as expected\n\nCheck that everything works as expected. If you are still having trouble, you can submit you issue in the [GitHub Nx repo](https://github.com/nrwl/nx). We wish you luck!\n\n## Sample files for manual upgrade\n\nIf you have not changed the content of the files which the `storybook-configuration` generator produced, you can use the following samples to migrate to Storybook `6`:\n\n### Configuring the root `./storybook` directory\n\n- In the root `./storybook` directory, create a new file named `main.js` with the following content:\n\n```typescript\nmodule.exports = {\n stories: [],\n addons: ['@storybook/addon-essentials'],\n};\n```\n\n- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.\n\n- The other two files remain unchanged.\n\n### Configuring the Storybook instances across apps and libraries - the library-specific `./storybook` directories\n\n- In the library `./storybook` directory, create a new file named `main.js` with the following content:\n\n```typescript\nconst lib_main_module = require('../../.storybook/main');\n\nlib_main_module.stories.push('../src/lib/**/*.stories.mdx');\nlib_main_module.stories.push('../src/lib/**/*.stories.@(js|jsx|ts|tsx)');\nmodule.exports = lib_main_module;\n```\n\nPlease take extra care making sure that the path to the root `./storybook` directory provided in the first line is correct.\n\n- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:\n\n```typescript\nlib_main_module.addons.push('<YOUR_ADDON_HERE>');\n```\n\nAfter you add any addons in the `main.js` file, you can safely delete the `addons.js` file. If you are using the default generated files without any changes, your `addons.js` file should be empty (but an import line, referencing the root `addons.js` file).\n\n- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:\n\n```typescript\nimport { addDecorator } from '@storybook/angular';\nimport { YourDecorator } from '@storybook/<something>';\n\naddDecorator(YourDecorator);\n```\n\n- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:\n\n```typescript\nconfig.resolve.extensions.push('.ts', '.tsx');\nconfig.module.rules.push({\n test: /\\.(ts|tsx)$/,\n loader: require.resolve('babel-loader'),\n options: {\n presets: [\n '@babel/preset-env',\n '@babel/preset-react',\n '@babel/preset-typescript',\n ],\n },\n});\n```\n\n### Check final folder structure\n\nYour folder structure should now look like this:\n\n```treeview\n<workspace name>/\n├── .storybook/\n│ ├── main.js\n│ ├── tsconfig.json\n│ └── webpack.config.js\n├── apps/\n├── libs/\n│ └── <library name>/\n│ ├── .storybook/\n│ │ ├── main.js\n│ │ ├── tsconfig.json\n│ │ └── webpack.config.js\n│ ├── src/\n│ ├── README.md\n│ ├── tsconfig.json\n│ └── etc...\n├── nx.json\n├── package.json\n├── README.md\n└── etc...\n```\n"
},
{
"id": "migrate-webpack-final-react",
"name": "React: Migrate to the Nrwl React Storybook Preset",
"file": "shared/guides/storybook/migrate-webpack-final-react",
"content": "# Nrwl React Storybook Preset\n\nNx 12.7 comes with a dedicated Storybook preset for React which drammatically simplifies the Storybook setup and makes sure that Storybook uses the same webpack configuration as your React applications running within an Nx workspace.\n\n{% youtube\nsrc=\"https://www.youtube.com/embed/oUE74McS_NY\"\ntitle=\"New in Nx 12.7: React Storybook Preset\"\nwidth=\"100%\" /%}\n\nHere are the main differences to the previous versions of Nx:\n\n- there's no `webpack.config.js`; Custom webpack configurations can be added in the `webpackFinal` property of the `main.js` file\n- the `main.js` file now contains a predefined Storybook preset exported by `@nrwl/react/plugins/storybook`.\n\nHere's an example of a newly generated `main.js` file:\n\n```javascript\n// project-level .storybook/main.js file\nconst rootMain = require('../../../.storybook/main');\n\nmodule.exports = {\n ...rootMain,\n\n core: {\n ...rootMain.core,\n // opt-into Storybook Webpack 5\n builder: 'webpack5'\n }\n\n stories: [\n ...rootMain.stories,\n '../src/lib/**/*.stories.mdx',\n '../src/lib/**/*.stories.@(js|jsx|ts|tsx)',\n ],\n addons: [...rootMain.addons, '@nrwl/react/plugins/storybook'],\n webpackFinal: async (config, { configType }) => {\n // apply any global webpack configs that might have been specified in .storybook/main.js\n if (rootMain.webpackFinal) {\n config = await rootMain.webpackFinal(config, { configType });\n }\n\n // add your own webpack tweaks if needed\n\n return config;\n },\n};\n```\n\nAt the Nx workspace root level, the configuration file looks as follows:\n\n```javascript\n// root level .storybook/main.js file\nmodule.exports = {\n stories: [],\n addons: ['@storybook/addon-essentials'],\n // uncomment the property below if you want to apply some webpack config globally\n // webpackFinal: async (config, { configType }) => {\n // // Make whatever fine-grained changes you need that should apply to all storybook configs\n\n // // Return the altered config\n // return config;\n // },\n};\n```\n\n## Migrating\n\nIf you're upgrading from a lower version of Nx, your old Storybook configuration will still work. New configurations generated will use the new syntax as shown above. The newly generated code will also make sure to extend from a global `webpack.config.js` which might exist in the root-level `.storybook/` directory of your Nx workspace.\n\nThis gives you the flexibility to incrementally migrate your configurations.\n\nHere's the step-by-step migration process:\n\n### 1. adjust the `main.js` file\n\nRestructure your `main.js` file so that it looks like in the example illustrated above.\n\nIf you need to keep your root-level `.storybook/webpack.config.js` for now, then make sure you adjust the `main.js` in a way that it properly calls the root-level `webpack.config.js` to inherit all of the global configurations.\n\n```javascript\nconst rootMain = require('../../../.storybook/main');\nconst rootWebpackConfig = require('../../../.storybook/webpack.config');\n\nmodule.exports = {\n ...rootMain,\n ...\n webpackFinal: async (config) => {\n // for backwards compatibility call the `rootWebpackConfig`\n // this can be removed once that one is migrated fully to\n // use the `webpackFinal` property in the `main.js` file\n config = rootWebpackConfig({ config });\n\n // add your own webpack tweaks if needed\n\n return config;\n },\n};\n```\n\n{% callout type=\"note\" title=\"Tip!\" %}\nThe easiest way is probably to generate a new library and Storybook configuration and then copy & paste the `main.js`.\n{% /callout %}\n\n### 2. Move any custom webpack configuration to `webpackFinal`\n\nIn previous versions of Nx a custom `webpack.config.js` was generated with the following content:\n\n```javascript\nmodule.exports = async ({ config, mode }) => {\n config = await rootWebpackConfig({ config, mode });\n\n const tsPaths = new TsconfigPathsPlugin({\n configFile: './tsconfig.base.json',\n });\n\n config.resolve.plugins\n ? config.resolve.plugins.push(tsPaths)\n : (config.resolve.plugins = [tsPaths]);\n\n // Found this here: https://github.com/nrwl/nx/issues/2859\n // And copied the part of the solution that made it work\n\n const svgRuleIndex = config.module.rules.findIndex((rule) => {\n const { test } = rule;\n\n return test.toString().startsWith('/\\\\.(svg|ico');\n });\n config.module.rules[svgRuleIndex].test =\n /\\.(ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\\?.*)?$/;\n\n config.module.rules.push(\n {\n test: /\\.(png|jpe?g|gif|webp)$/,\n loader: require.resolve('url-loader'),\n options: {\n limit: 10000, // 10kB\n name: '[name].[hash:7].[ext]',\n },\n },\n {\n test: /\\.svg$/,\n oneOf: [\n // If coming from JS/TS file, then transform into React component using SVGR.\n {\n issuer: {\n test: /\\.[jt]sx?$/,\n },\n use: [\n {\n loader: require.resolve('@svgr/webpack'),\n options: {\n svgo: false,\n titleProp: true,\n ref: true,\n },\n },\n {\n loader: require.resolve('url-loader'),\n options: {\n limit: 10000, // 10kB\n name: '[name].[hash:7].[ext]',\n esModule: false,\n },\n },\n ],\n },\n // Fallback to plain URL loader.\n {\n use: [\n {\n loader: require.resolve('url-loader'),\n options: {\n limit: 10000, // 10kB\n name: '[name].[hash:7].[ext]',\n },\n },\n ],\n },\n ],\n }\n );\n\n return config;\n};\n```\n\nSuch webpack file is no more needed as the `@nrwl/react/plugins/storybook` now takes care of it.\n\nIn case you made custom modifications to the `webpack.config.js` file, you need to move them over to the `main.js` `webpackFinal` property and then delete the `webpack.config.js`.\n\n### 3. Remove the root-level `.storybook/webpack.config.js` file\n\nOnce you've migrated all your libraries, you can think about removing the root-level `.storybook/webpack.config.js` file and migrate any custom configuration there to `.storybook/main.js` `webpackFinal` property in the very same folder.\n\n### 4. Opting in to Webpack 5\n\nIf you choose to opt-in to Webpack 5, by specifying `builder: 'webpack5'` in your project's `.storybook/main.(js|ts)` (as shown above, in the example of a newly generated `main.js` file), don't forget to add the Storybook dependencies for Webpack 5 to work:\n\n```shell\nyarn add -D @storybook/builder-webpack5 @storybook/manager-webpack5\n```\n\nor if you're using `npm`:\n\n```shell\nnpm install --save-dev @storybook/builder-webpack5 @storybook/manager-webpack5\n```\n"
},
{
"id": "upgrade-storybook-v6-react",
"name": "React: Upgrading to Storybook 6",
"file": "shared/guides/storybook/storybook-v6-react",
"content": "# Upgrading to Storybook 6 (and Nx versions >10.1.x and <14.0.0)\n\n_Disclaimer: From Nx 14.0.0 and on, Nx does not support Storybook v.5. If your workspace is on a version of Nx older than Nx 14, then you will be able to use the generators described in this guide. If you're using Nx >14, then you will already have been automatically migrated to Storybook 6._\n\nNx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).\n\nNx version `10.2.x` will continue to support Storybook version `5.2.x`, however newer versions of Nx will only support Storybook version `6` (and on).\n\nWhen you are running the Nx workspace migration script, your Storybook instances and configurations across your apps and libraries will NOT be migrated automatically. We chose not to migrate your Storybook instances and configurations across your apps and libraries automatically, since there a number of breaking changes that Storybook introduced in versions `5.3` and `6.0`, and making decisions on what to migrate automatically would risk the integrity of your code.\n\nInstead, when you choose to migrate from Nx versions `<10.1.x` to Nx versions `>10.2.x` (using the Nx migration script - `nx migrate`) we will keep your Storybook packages and Storybook instances and configurations intact. We suggest that you do the migration on your own, using the guide below, with all the references to the official Storybook migration guides. Look at the use cases below, and follow the one that matches your case.\n\n## Use Cases\n\n### Use case 1: Create an Nx workspace from scratch using the latest version of Nx\n\nIf you are creating an Nx workspace using the latest version of Nx, the latest version of Storybook (version 6) will be used as well. You do not need to do anything.\n\n### Use case 2: I already have an Nx workspace that does NOT use Storybook and I want to migrate to the latest Nx\n\nIf you already have an Nx workspace with a previous version of Nx that does NOT use Storybook, and you migrate to the latest Nx using the migrate scripts provided by Nx, and then, after the migration to the latest Nx, you choose to add Storybook, the latest version of Storybook will be used. You do not need to do anything.\n\n### Use case 3: I already have an Nx workspace with Storybook and I want to migrate to the latest Nx\n\nIn that case, when you run the Nx migration scripts, the scripts will ignore the Storybook packages, the Storybook configuration files, the Storybook instances in your apps and libraries, and all the generated stories. If you continue to add Storybook configurations and Storybook instances to new libraries and applications, then the version of Storybook that you already have will be used (most probably, if you have not changed anything manually, that version will be `5.3.9` using, however, the configuration files of `5.2`). You will have to do the [upgrade to the latest Storybook on your own, manually](#upgrading-to-storybook-6-manually). After that, Nx will use that version, and configure all new Storybook instances using the new version.\n\n## Upgrading to Storybook 6 using the Nx migration generator\n\n### Some info about the generator\n\nThe `@nrwl/react:storybook-migrate-defaults-5-to-6` generator will not exactly do a migration. It will perform the following actions:\n\n- It will generate new Storybook configuration files using the new (`>6.x`) Storybook way. The way it will do that is, it will look in all the `project.json` files and it will find all the projects that have a `Storybook` configuration. Using the `configFolder` path provided there, it will go and generate new Storybook instances in all these paths. Finally, it will generate a new Storybook instance at the root directory.\n\n- If you choose to `keepOld`, then it will add all your existing Storybook configuration files into another folder labeled `.old_storybook`.\n\n- It will update all the Storybook-related (`@storybook/*`) packages in your `package.json`.\n\n### How to use the generator\n\nThat way, you can have working Storybook instances for all your projects just by running\n\n```bash\nnx g @nrwl/react:storybook-migrate-defaults-5-to-6\n```\n\n### What if I had made changes to the defaults?\n\nIn case you had made customizations to the default Storybook configurations, you can then manually change each of your Storybook instance configuration files using the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) to make sure you use the new syntax. Your old configuration files are available to you to use as a reference.\n\nPlease check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).\n\n### What if I am not ready to change everything at once?\n\nThe generator gives you the option to migrate one project at a time. You can provide the `--name=PROJECT_NAME` flag, and then the generator will **only** generate new files for the specified project.\n\nPlease note that this option will NOT update all the Storybook-related (`@storybook/*`) packages in your `package.json`, or the root Storybook folder. The reason is that if you want to do the migration gradually, one project at a time, you want your old, existing, projects, to still work. That way, you will still be able to run your old, non-migrated Storybook projects. However, you will not be able to run any migrated Storbook projects. Once you have migrated all your Storybook projects, you can run `nx g @nrwl/react:storybook-migrate-defaults-5-to-6` once again, and the generator will take care of updating all the Storybook-related (`@storybook/*`) packages in your `package.json` and it will also generate the new Storybook files for the root Storybook directory.\n\n### General tip:\n\n**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.\n\n## Upgrading to Storybook 6 manually\n\nThere is really no great reason for doing the migration completely manually. The `@nrwl/react:storybook-migrate-defaults-5-to-6` generator [will take care of Steps 1, 2 and 3](#upgrading-to-storybook-6-using-the-nx-migration-generator). What you will need to do after running the generator is that you have to manually migrate any custom changes you had done to the default Storybook configuration files that were automatically generated by Nx when you first used Nx Storybook. To do the manual migration you should use the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).\n\nHowever, if you still want to do everything manually, these are the steps you should follow:\n\n### Step 0:\n\n**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.\n\n### Step 1: Changing the configuration files from version 5.2 to 5.3\n\nThe most noticeable change in Storybook versions newer than `5.2` is that the configuration files have changed names and content.\nQuoting from the [official Storybook migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x):\n\n- `presets.js` has been renamed to `main.js`. `main.js` is the main point of configuration for storybook.\n- `config.js` has been renamed to `preview.js`. `preview.js` configures the \"preview\" iframe that renders your components.\n- `addons.js` has been renamed to `manager.js`. `manager.js` configures Storybook's \"manager\" UI that wraps the preview, and also configures addons panel.\n\nPlease follow the [official Storybook version 5.2.x to 5.3.x migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x) to change your files accordingly.\n\n### Step 2: Going from version 5.3 to 6.0\n\nPlease check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).\n\n- One big change in Storybook version `6` is that it has **built-in Typescript support**. This means that you can remove Typescript configurations from your configuration files.\n- Please also **check that your stories match any differences in syntax** introduced in versions `5.3` and `6.0`.\n\n### Step 3: Upgrade all `@storybook/*` packages in your project\n\nCheck your `package.json` file for all `@storybook` packages. Install the latest versions of these, using `yarn`:\n\nFor example:\n\n```bash\nyarn add --dev @storybook/react@latest\n```\n\n### Step 4: Check that everything works as expected\n\nCheck that everything works as expected. If you are still having trouble, you can submit you issue in the [GitHub Nx repo](https://github.com/nrwl/nx). We wish you luck!\n\n### Sample files for manual upgrade\n\nIf you have not changed the content of the files which the `storybook-configuration` generator produced, you can use the following samples to migrate to Storybook `6`:\n\n### Configuring the root `./storybook` directory\n\n- In the root `./storybook` directory, create a new file named `main.js` with the following content:\n\n```typescript\nmodule.exports = {\n stories: [],\n addons: ['@storybook/addon-essentials'],\n};\n```\n\n- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.\n\n- The other two files remain unchanged.\n\n### Configuring the Storybook instances across apps and libraries - the library-specific `./storybook` directories\n\n- In the library `./storybook` directory, create a new file named `main.js` with the following content:\n\n```typescript\nconst lib_main_module = require('../../.storybook/main');\n\nlib_main_module.stories.push('../src/lib/**/*.stories.mdx');\nlib_main_module.stories.push('../src/lib/**/*.stories.@(js|jsx|ts|tsx)');\nmodule.exports = lib_main_module;\n```\n\nPlease take extra care making sure that the path to the root `./storybook` directory provided in the first line is correct.\n\n- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:\n\n```typescript\nlib_main_module.addons.push('<YOUR_ADDON_HERE>');\n```\n\nAfter you add any addons in the `main.js` file, you can safely delete the `addons.js` file. If you are using the default generated files without any changes, your `addons.js` file should be empty (but an import line, referencing the root `addons.js` file).\n\n- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:\n\n```typescript\nimport { addDecorator } from '@storybook/react';\n\naddDecorator(<YourDecorator>);\n```\n\n- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:\n\n```typescript\nconfig.resolve.extensions.push('.ts', '.tsx');\nconfig.module.rules.push({\n test: /\\.(ts|tsx)$/,\n loader: require.resolve('babel-loader'),\n options: {\n presets: [\n '@babel/preset-env',\n '@babel/preset-react',\n '@babel/preset-typescript',\n ],\n },\n});\n```\n\n### Check final folder structure\n\nYour folder structure should now look like this:\n\n```treeview\n<workspace name>/\n├── .storybook/\n│ ├── main.js\n│ ├── tsconfig.json\n│ └── webpack.config.js\n├── apps/\n├── libs/\n│ └── <library name>/\n│ ├── .storybook/\n│ │ ├── main.js\n│ │ ├── tsconfig.json\n│ │ └── webpack.config.js\n│ ├── src/\n│ ├── README.md\n│ ├── tsconfig.json\n│ └── etc...\n├── nx.json\n├── package.json\n├── README.md\n└── etc...\n```\n"
}
],
"generators": [
{
"name": "init",
"factory": "./src/generators/init/init",
"schema": {
"cli": "nx",
"title": "Add Storybook Configuration to the workspace",
"description": "Add Storybook Configuration to the workspace.",
"$id": "init-storybook-plugin",
"type": "object",
"properties": {
"uiFramework": {
"type": "string",
"description": "Storybook UI Framework to use.",
"enum": [
"@storybook/angular",
"@storybook/react",
"@storybook/html",
"@storybook/web-components",
"@storybook/vue",
"@storybook/vue3",
"@storybook/svelte",
"@storybook/react-native"
],
"x-prompt": "What UI framework plugin should storybook use?"
}
},
"presets": []
},
"description": "Add Storybook configuration to the workspace.",
"aliases": ["ng-add"],
"hidden": true,
"implementation": "/packages/storybook/src/generators/init/init.ts",
"path": "/packages/storybook/src/generators/init/schema.json"
},
{
"name": "configuration",
"factory": "./src/generators/configuration/configuration",
"schema": {
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxStorybookConfigure",
"title": "Storybook Configuration",
"description": "Add Storybook configuration to a UI library or an application.",
"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"
},
"uiFramework": {
"type": "string",
"description": "Storybook UI Framework to use.",
"enum": [
"@storybook/angular",
"@storybook/react",
"@storybook/react-native",
"@storybook/html",
"@storybook/web-components",
"@storybook/vue",
"@storybook/vue3",
"@storybook/svelte"
],
"x-prompt": "What UI framework plugin should storybook use?"
},
"configureCypress": {
"type": "boolean",
"description": "Run the cypress-configure generator.",
"x-prompt": "Configure a cypress e2e app to run against the storybook instance?"
},
"cypressDirectory": {
"type": "string",
"description": "A directory where the Cypress project will be placed. Added at root by default."
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": ["eslint", "tslint", "none"],
"default": "eslint"
},
"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": false
},
"standaloneConfig": {
"description": "Split the project configuration into `<projectRoot>/project.json` rather than including it inside `workspace.json`.",
"type": "boolean"
}
},
"required": ["name"],
"presets": []
},
"description": "Add Storybook configuration to a UI library or an application.",
"hidden": false,
"implementation": "/packages/storybook/src/generators/configuration/configuration.ts",
"aliases": [],
"path": "/packages/storybook/src/generators/configuration/schema.json"
},
{
"name": "cypress-project",
"factory": "./src/generators/cypress-project/cypress-project",
"schema": {
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "cypress-configure",
"title": "Cypress Configuration",
"description": "Add cypress E2E app to test a ui library that is set up for Storybook.",
"type": "object",
"properties": {
"name": {
"type": "string",
"aliases": ["project", "projectName"],
"description": "Project for which to generate the cypress E2E app.",
"$default": { "$source": "argv", "index": 0 },
"x-prompt": "For which project do you want to generate the Cypress E2E app?",
"x-dropdown": "projects"
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files.",
"default": false
},
"directory": {
"type": "string",
"description": "A directory where the project is placed."
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": ["eslint", "tslint", "none"],
"default": "eslint"
},
"standaloneConfig": {
"description": "Split the project configuration into `<projectRoot>/project.json` rather than including it inside `workspace.json`.",
"type": "boolean"
}
},
"required": ["name"],
"presets": []
},
"description": "Add cypress e2e app to test a UI library that is set up for Storybook.",
"hidden": false,
"implementation": "/packages/storybook/src/generators/cypress-project/cypress-project.ts",
"aliases": [],
"path": "/packages/storybook/src/generators/cypress-project/schema.json"
},
{
"name": "change-storybook-targets",
"factory": "./src/generators/change-storybook-targets/change-storybook-targets",
"schema": {
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "change-storybook-targets",
"title": "Change Storybook targets",
"description": "Change the Storybook target executors of Angular projects to use the native Storybook for Angular executor schema.",
"type": "object",
"properties": {},
"required": [],
"presets": []
},
"description": "Change storybook targets for Angular projects to use @storybook/angular executors",
"hidden": false,
"implementation": "/packages/storybook/src/generators/change-storybook-targets/change-storybook-targets.ts",
"aliases": [],
"path": "/packages/storybook/src/generators/change-storybook-targets/schema.json"
}
],
"executors": [
{
"name": "storybook",
"implementation": "/packages/storybook/src/executors/storybook/storybook.impl.ts",
"schema": {
"title": "Storybook Dev Builder",
"cli": "nx",
"description": "Serve up storybook in development mode.",
"type": "object",
"presets": [
{
"name": "Default minimum setup",
"keys": ["uiFramework", "port", "config"]
}
],
"properties": {
"uiFramework": {
"type": "string",
"description": "Storybook framework npm package.",
"enum": [
"@storybook/react",
"@storybook/html",
"@storybook/web-components",
"@storybook/vue",
"@storybook/vue3",
"@storybook/svelte"
],
"default": "@storybook/react",
"hidden": true
},
"port": {
"type": "number",
"description": "Port to listen on.",
"default": 9009
},
"host": {
"type": "string",
"description": "Host to listen on.",
"default": "localhost"
},
"https": {
"type": "boolean",
"description": "Serve using HTTPS.",
"default": false
},
"sslKey": {
"type": "string",
"description": "SSL key to use for serving HTTPS."
},
"sslCert": {
"type": "string",
"description": "SSL certificate to use for serving HTTPS."
},
"watch": {
"type": "boolean",
"description": "Watches for changes and rebuilds application.",
"default": true
},
"staticDir": {
"type": "array",
"description": "Directory where to load static files from, array of strings.",
"items": { "type": "string" },
"x-deprecated": "In Storybook 6.4 the `--static-dir` CLI flag has been replaced with the the `staticDirs` field in `.storybook/main.js`. It will be removed completely in Storybook 7.0."
},
"config": {
"type": "object",
"description": ".storybook configuration.",
"properties": {
"configFolder": {
"type": "string",
"description": "Directory where to load Storybook configurations from."
},
"pluginPath": {
"type": "string",
"description": "Path to storybook plugin.js file."
},
"configPath": {
"type": "string",
"description": "Path to storybook preview.js file."
},
"babelrcPath": {
"type": "string",
"description": "Path to storybook .babelrc file."
},
"srcRoot": {
"type": "string",
"description": "Project source path."
}
}
},
"docsMode": {
"type": "boolean",
"description": "Build a documentation-only site using addon-docs.",
"default": false
},
"quiet": {
"type": "boolean",
"description": "Suppress verbose build output.",
"default": true
}
},
"definitions": {},
"required": ["uiFramework", "config"]
},
"description": "Serve Storybook.",
"aliases": [],
"hidden": false,
"path": "/packages/storybook/src/executors/storybook/schema.json"
},
{
"name": "build",
"implementation": "/packages/storybook/src/executors/build-storybook/build-storybook.impl.ts",
"schema": {
"title": "Storybook Builder",
"cli": "nx",
"description": "Build storybook in production mode.",
"type": "object",
"presets": [
{
"name": "Default minimum setup",
"keys": ["uiFramework", "outputPath", "config"]
}
],
"properties": {
"uiFramework": {
"type": "string",
"description": "Storybook framework npm package.",
"enum": [
"@storybook/react",
"@storybook/html",
"@storybook/web-components",
"@storybook/vue",
"@storybook/vue3",
"@storybook/svelte"
],
"default": "@storybook/react",
"hidden": true
},
"outputPath": {
"type": "string",
"description": "The output path of the generated files.",
"x-completion-type": "directory"
},
"styles": {
"type": "array",
"description": "Global styles to be included in the build.",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"input": {
"type": "string",
"description": "The file to include.",
"x-completion-type": "file"
},
"bundleName": {
"type": "string",
"pattern": "^[\\w\\-.]*$",
"description": "The bundle name for this extra entry point."
},
"inject": {
"type": "boolean",
"description": "If the bundle will be referenced in the HTML file.",
"default": true
}
},
"additionalProperties": false,
"required": ["input"]
},
{ "type": "string", "description": "The file to include." }
]
}
},
"stylePreprocessorOptions": {
"type": "object",
"description": "Options to pass to style preprocessors.",
"properties": {
"includePaths": {
"type": "array",
"description": "The paths to include. Paths will be resolved to workspace root.",
"items": { "type": "string" }
}
}
},
"config": {
"type": "object",
"description": "`.storybook` file configuration",
"properties": {
"configFolder": {
"type": "string",
"description": "Directory where to load Storybook configurations from."
},
"pluginPath": {
"type": "string",
"description": "Path to storybook `plugin.js` file."
},
"configPath": {
"type": "string",
"description": "Path to storybook `preview.js` file."
},
"srcRoot": {
"type": "string",
"description": "Project source path."
}
}
},
"docsMode": {
"type": "boolean",
"description": "Build a documentation-only site using addon-docs.",
"default": false
},
"quiet": {
"type": "boolean",
"description": "Suppress verbose build output.",
"default": true
}
},
"definitions": {
"extraEntryPoint": {
"oneOf": [
{
"type": "object",
"properties": {
"input": {
"type": "string",
"description": "The file to include.",
"x-completion-type": "file"
},
"bundleName": {
"type": "string",
"pattern": "^[\\w\\-.]*$",
"description": "The bundle name for this extra entry point."
},
"inject": {
"type": "boolean",
"description": "If the bundle will be referenced in the HTML file.",
"default": true
}
},
"additionalProperties": false,
"required": ["input"]
},
{ "type": "string", "description": "The file to include." }
]
}
},
"required": ["uiFramework", "config"]
},
"description": "Build Storybook.",
"aliases": [],
"hidden": false,
"path": "/packages/storybook/src/executors/build-storybook/schema.json"
}
]
}