From accc7a6bab35ff4c3c55e78b3811e5a75e7736e7 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Wed, 3 Aug 2022 14:01:59 +0300 Subject: [PATCH] docs(storybook): fix composition guide (#11421) #11353 ISSUES CLOSED: #11353 --- docs/generated/packages/storybook.json | 2 +- .../storybook/storybook-composition-setup.md | 98 ++++++++++++++++++- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/docs/generated/packages/storybook.json b/docs/generated/packages/storybook.json index 9d5435dd12..f7e044c28e 100644 --- a/docs/generated/packages/storybook.json +++ b/docs/generated/packages/storybook.json @@ -58,7 +58,7 @@ "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`](https://nx.dev/l/a/cli/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=4`), 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\nYou can just do:\n\n```bash\nnx run-many --target=storybook --projects=main-host,one-composed,two-composed,three-composed --parallel=4\n```\n\nBefore running the above command 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=4` 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" + "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`](https://nx.dev/l/a/cli/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 @nrwl/workspace: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" } ], "generators": [ diff --git a/docs/shared/guides/storybook/storybook-composition-setup.md b/docs/shared/guides/storybook/storybook-composition-setup.md index e6186fed78..2440d03872 100644 --- a/docs/shared/guides/storybook/storybook-composition-setup.md +++ b/docs/shared/guides/storybook/storybook-composition-setup.md @@ -44,16 +44,24 @@ You can always read more in the [official Storybook docs](https://storybook.js.o It'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. -Nx provides the [`run-many`](https://nx.dev/l/a/cli/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=4`), 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 +Nx provides the [`run-many`](https://nx.dev/l/a/cli/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 flag, 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). -You can just do: +In order to get get it working for you, you need to two two things: + +1. Make sure your "composed" Storybook instances are running. For that you can do: ```bash -nx run-many --target=storybook --projects=main-host,one-composed,two-composed,three-composed --parallel=4 +nx run-many --target=storybook --projects=one-composed,two-composed,three-composed --parallel=3 ``` -Before running the above command to actually compose our Storybook instances under the **`main-host`** project, we would need to do the following adjustments to our workspace: +2. Start your host Storybook in another tab of your terminal: + +```bash +nx storybook main-host +``` + +Before 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: ### Adjust the Storybook ports in `project.json` @@ -81,7 +89,7 @@ In your project's targets, in the `storybook` target, you will notice that the d We 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: -- When the `nx run-many --target=storybook --parallel=4` command executes, it will go and look into your `project.json` file to see the port you have assigned for that project's Storybook. +- 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. - 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). Since 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. @@ -112,3 +120,83 @@ module.exports = { }, }; ``` + +### Optional: use `run-commands` and create a `storybook-composition` target + +If 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. + +The 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: + +```json + "storybook-composition": { + "executor": "nx:run-commands", + "options": { + "commands": [ + "nx storybook one-composed", + "nx storybook two-composed", + "nx storybook three-composed" + ], + "parallel": true + } + } +``` + +which you can then invoke like this: + +```bash +nx run main-host:storybook-composition +``` + +which will take care of starting all your "composed" Storybook instances, before you run `nx storybook main-host`. + +#### Generating a new `target` in our `main-host` + +Let's first generate a new `target` called `storybook-composition` for our `main-host`. + +Run the following command: + +```bash +nx generate @nrwl/workspace:run-commands storybook-composition --command='nx storybook one-composed' --project=main-host +``` + +This will create a new `target` in your `apps/main-host/project.json`: + +```json + "storybook-composition": { + "executor": "nx:run-commands", + "outputs": [], + "options": { + "command": "nx storybook one-composed" + } + } +``` + +Now, change the `command` option to be `commands`, add the `"parallel": true` option, and add all the other "composed" Storybook commands: + +```json + "storybook-composition": { + "executor": "nx:run-commands", + "options": { + "commands": [ + "nx storybook one-composed", + "nx storybook two-composed", + "nx storybook three-composed" + ], + "parallel": true + } + } +``` + +Now, you can start all your "composed" Storybook instances by running: + +```bash +nx run main-host:storybook-composition +``` + +**After** all of your "composed" Storybook instances have started, you can run in a new terminal: + +```bash +nx storybook main-host +``` + +This approach takes the "burden" of writing the `run-many` command manually, and makes it easier to add/remove "composed" Storybook instances.