5

Build your design system with Storybook + Nx

 3 years ago
source link: https://blog.nrwl.io/build-your-design-system-with-storybook-nx-e3bde4087ad8
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Build your design system with Storybook + Nx

If you are part of a large organization or team, chances are you need a design system. There are tons of tools out there to help you develop and organize that design system, but in this article we will see how a combination of Nx and Storybook will make that process more efficient, more enjoyable, and definitely more scalable.

What is a design system

First of all, what is a design system? A design system is the set of styles, rules and reusable components that an organization or an application uses. Brad Frost has a great definition of what a design system is. Part of it: “… a design system [ is ] the official story of how your organization designs and builds digital products”.

What is Nx

Nx is a smart, extensible build framework that helps with monorepo-style development, by providing plugins and integrations with modern tools. Nx, in other words, is an ecosystem, and within that ecosystem live a collection of runtime libraries, linters, code generators and scripts that will help a team build, test, organize, develop, integrate and deploy their software, using modern web frameworks and technologies. Due to its nature and the tools it offers, it also helps developers collaborate across their organizations on large code bases.

Core Concepts

Let’s, briefly, see the core concepts of Nx, with links for further reading:

  • Code generation / scaffoldinggenerators generate applications, components, standard pieces of code (like cookie-cutters) — they also help you migrate across versions
  • Dependency graph and code change analysis — only build/test/lint projects that are affected by a code change — Nx understands your workspace, and makes optimizations — it also visualizes the dependencies with the dependency graph
  • Speedcomputation caching will ensure that when you rerun the same command, the results will be fetched from the cache — together with the affected command and distributed task execution and Nx Cloud you never build/test/lint the same code twice
  • Nx CLI — Integrated environment with consistent syntax for executing commands.
  • Plugins — for modern web technologies and tools include their own executors and generators which will help you develop projects using the tools you like
  • IDE integration — Nx Editor Plugins give you access to all that the Nx CLI can do, but from a GUI. That way, you can more easily browse your options when generating components and stories, or when running and building Storybook.

You can read more about how Nx works in this blogpost.

What is Storybook

From the Storybook website: “Storybook is an open source tool for building UI components and pages in isolation. It streamlines UI development, testing, and documentation.

What does this mean, though, in practice? Storybook gives you the ability to develop and run a component in isolation. This means that you do not need to start up a complex dev stack whenever you want to develop, test, demonstrate, and run a component. You develop entire UIs by focusing on building one building block at a time. You focus solely on a component’s look and feel and functionality, without having to worry about whatever’s wrapping it. Storybook helps with testing as well, because you end up writing less tests, as you describe various scenarios/use-cases (the so-called stories) for each of your components. These stories help the developer or the designer or any member of your team to browse or trigger different states dynamically.

1*71wcGSIDqgF-4HRrhe4LeA.png?q=20
build-your-design-system-with-storybook-nx-e3bde4087ad8
Here’s an example of a story describing different button states — taken from the actual Storybook design system storybook.

Why Storybook + Nx for Design systems?

From what we have already written, it’s almost self-evident how the coupling of these two great tools can make your organization’s life easier. You can take a look at Storybook’s guide of how to develop a Design System with Storybook. Storybook, as you can already understand from the descriptions so far, can enable you to create a component library, a component catalogue, and documentation for your UI library (or your design system, right?).

How Nx helps

Automatically add Storybook setup to any Nx library

With Nx you can generate code, build, test and run tasks seamlessly in an integrated environment

Generates stories for you

Nx can generate stories for you from your React components. It analyses your props, and it creates the controls that you need in your stories. So, the only thing you would need to do, would be to decide which components you want for your design system, add them and separate them in the libraries you need. Then, all you have to do is run the right Nx command to generate your stories (nx g @nrwl/react:stories — name=my-project-name or nx g @nrwl/react:storybook-configuration — name=my-project-name). Then, if you need to cover more complex scenarios, you can enrich and extend these stories.

Generates e2e tests with Storybook

Nx will also generate e2e tests for you for your components with Storybook, so that you can integrate them into your CI as well.

Generates Storybook configuration

Nx allows for customization, of course. By default, Nx generates a root .storybook directory with some general configurations for all your Storybook instances across your projects. These root settings, then, get imported into the individual project-level configurations. So, you can either control all your Storybook instances with the contents of the root .storybook, or you can customize each one individually. Thanks to storybook composition, you can still set up all your individual storybooks and view them together.

Generators that migrate your code to latest versions

Nx also offers code generators that will help you migrate from one version to another. The migrators will take care of migrating your settings or your actual stories. The result will be that there will be a lot less work for a developer or a team to do when changing versions. You can upgrade hassle-free and keep up to date with the latest versions, without having to think about upgrading as a time-consuming and difficult task. Nx offers Storybook-specific migrators, as well, on command.

Helps you organize your code

Nx helps with imposing an architectural structure. The monorepo style development, with the code separation in apps and libs and tools will help the team take advantage of keeping things separate, and helping with better testing and collaboration. Nx makes it easy to work with code that’s been broken up into libraries, and this type of workspace structure helps teams work more independently. Parts of the code are independent of each other, so making a small change at one place does not instantly mean that a whole project needs to be rebuilt again. This, also, makes team collaboration easier.

Linting and formatting out of the box

Tools for linting and formatting which are integrated in the Nx ecosystem are vital in a design system where many different teams may collaborate on. That way, a single style of writing and formatting code can be adopted, which will ensure uniformity and quality across all parts of the system.

Integrates with CI

Nx integrates perfectly with your CI tools, as well. You can add the power of the cache and the dependency graph to your CI, and make your pipelines shorter. The fact that Storybook is also integrated within your workspace, and as part of the CLI and Nx, makes it even easier to add the Storybook testing and building in your pipelines. Take a look at the workflow chapter in the Storybook design systems guide, to see how else you can take advantage of your Storybook.

Cypress

Nx integrates with Cypress, too. By default, when creating a new frontend application, Nx will use Cypress to create the e2e tests project. But Storybook integrates with Cypress, too. You can do component testing reusing the stories and the configuration you have already created in Storybook in Cypress.

Nx Cloud

Nx Cloud will help you minimize your CI time, using distributed cache. It also integrates with GitHub and you can monitor your actions easily. This will help you keep track of your deployment and the status of your published Storybook.

Nx Console

If you prefer a graphical user interface rather than a CLI, you can install Nx Console on VS Code, which gives you access to all that the Nx CLI can do, but from a GUI. That way, you can more easily browse your options when generating components and stories, or when running and building Storybook.

How to add Storybook to your Nx workspace

If you’re developing a project from scratch

If you’re developing a project from scratch, you can generate an Nx workspace directly using the create-nx-workspace command.

npx create-nx-workspace my-org

When you run this command, you will be presented with a number of options as to what application to include when the workspace is first created. You can go with empty, but let’s choose React.

0*0rGiQ2jiAW111bg9?q=20
build-your-design-system-with-storybook-nx-e3bde4087ad8

Then, you will have to choose the stylesheet format.

0*Pci0BfLQJQFpSVCq?q=20
build-your-design-system-with-storybook-nx-e3bde4087ad8

Following the guide of Storybook for a design system, we will go with Styled Components. But you can see all the variety of different stylesheet formats that Nx supports with React.

Once your workspace is ready, you can jump to the “Add the Nx Storybook Plugin” paragraph.

If you already have a project in place

If you already have a project in place, you will get to transform it into an Nx workspace. To do that, you can use the “npx add-nx-to-monorepo” command if you’re already on a monorepo. Or you can use any of the three commands described in this package, to transform your CRA into an Nx workspace (npx cra-to-nx) or to transform your Angular CLI project into an Nx workspace (npx make-angular-cli-faster). You can read more about this process in this article. Recently, the Storybook repo added Nx, to benefit from the caching and speed improvements that Nx comes with.

Once your workspace is ready, you can jump to the “Add the Nx Storybook Plugin” paragraph.

Add the Nx Storybook Plugin

In the root of your project, run the following command to add the Nx Storybook plugin to your project:

yarn add -D @nrwl/storybook

Generate a library to add Storybook support

You can add Storybook to both your applications and your libraries. Building a Design System, however, you will most likely organize your code and add your UI components in thematic libraries that you will import in your apps. So let’s first generate a React library in our new React Nx workspace. In the root of your project run the following command:

nx g @nrwl/react:lib ui

This command will generate a new React project in the libs folder and it will also add all the required script targets in your workspace.json. Let’s take a look at the workspace.json structure for our new project. The new entry will look like this:

"ui": {
"root": "libs/ui",
"sourceRoot": "libs/ui/src",
"projectType": "library",
"targets": {
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["libs/ui/**/*.{ts,tsx,js,jsx}"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/libs/ui"],
"options": {
"jestConfig": "libs/ui/jest.config.js",
"passWithNoTests": true
}
}
}
}

The targets configure the tools which will be used to run certain commands. Our new ui library contains lint and test targets. That means that we can run nx test ui (or nx run ui:test) and nx lint ui (or nx run ui:build) and for that we will use @nrwl/jest:jest and @nrwl/linter:eslint accordingly.

Now, let’s configure our new library with Storybook. In the root of your project run the following command, and accept all the prompts:

nx g @nrwl/react:storybook-configuration --name=ui

This command will:

  • Install the required dependencies (all the required @storybook/* packages )
  • Setup the necessary scripts to run and build Storybook
  • Add the default Storybook configuration (a root .storybook folder and a project level .storybook folder)
  • Generate stories for your existing components (if any)
  • Add targets to your workspace.json to serve and build Storybook
  • Generate a Cypress based e2e project for your library using the components and their stories

So, let’s see how workspace.json was changed, and the new targets that were added in the ui project:

"storybook": {
"executor": "@nrwl/storybook:storybook",
"options": {
"uiFramework": "@storybook/react",
"port": 4400,
"config": {
"configFolder": "libs/ui/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
},
"build-storybook": {
"executor": "@nrwl/storybook:build",
"outputs": ["{options.outputPath}"],
"options": {
"uiFramework": "@storybook/react",
"outputPath": "dist/storybook/ui",
"config": {
"configFolder": "libs/ui/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
}

This means that we can now run and build our new Storybook with these commands:

nx run ui:storybook# ornx storybook ui# andnx run ui:build-storybook# ornx build-storybook ui

And these commands will use the @nrwl/storybook:storybookand @nrwl/storybook:build executors.

Generate stories from components

Now let’s generate a new React component in our ui library. You can do so by running the following command in the root of your project:

nx g @nrwl/react:component button --project=ui --export

Or you can alternatively use the Nx Console if you’re using VS code.

0*Ppcg0wybK0m4ozvz?q=20
build-your-design-system-with-storybook-nx-e3bde4087ad8

You will want to export your component, because you will be using it in your other projects.

Now that you have a new component in your ui library, you can use the stories generator from the @nrwl/storybook package to generate stories for that new component. Let’s see. In the root of your project run the following command:

nx g @nrwl/react:stories --project=ui

This command will also generate the corresponding e2e specs. You can also run this command, and all Nx commands, from the VS Code extension.

Generate e2e tests with Cypress

The e2e spec for our button component looks like this:

describe('ui: Button component', () => {
beforeEach(() => cy.visit('/iframe.html?id=button--primary'));
it('should render the component', () => {
cy.get('h1').should('contain', 'Welcome to ui!');
});
});

Notice how Cypress will visit /iframe.html?id=button — primary. This is the URL of the button component, when we run Storybook for our ui library. If we take a look into apps/ui-e2e/cypress.json we will see the base URL set as follows:

"baseUrl": "http://localhost:4400"

This is the URL where Storybook runs.

Let’s take a look at our workspace.json and see what the ui-e2e project entry looks like:

"ui-e2e": {
"root": "apps/ui-e2e",
"sourceRoot": "apps/ui-e2e/src",
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nrwl/cypress:cypress",
"options": {
"cypressConfig": "apps/ui-e2e/cypress.json",
"tsConfig": "apps/ui-e2e/tsconfig.e2e.json",
"devServerTarget": "ui:storybook"
},
"configurations": {
"ci": {
"devServerTarget": "ui:storybook:ci"
}
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["apps/ui-e2e/**/*.{js,ts}"]
}
}
}
}

When we run the e2e tests for the ui-e2e project, the dev server will run Storybook. So, then, Cypress will visit http://localhost:4400/iframe.html?id=button--primary to interact with our button component!

Migrating across versions

Nx also offers the ability to migrate from one version to another, using nx migrate. This command will update your packages and run the necessary scripts to transform your files. For Storybook specifically, there are optional migrators to help you move from older Storybook versions to the latest, by upgrading your packages and fixing your configuration files. You can read more about how migrations work in this article.

Nx and Design Systems without a monorepo

What if your organization does not use a monorepo, and you need to create UI libraries independently, and have components that you can share across teams, repos and apps? You can do that with Nx, as well!

Nx libraries are “workspace” libraries. This means that they do not need to be published if you want to use them across your applications and libraries in the same Nx workspace (in the same monorepo). They can be referenced directly thanks to the TypeScript path mapping in the tsconfig.base.json. This brings lots of benefits in a monorepo scenario, where your apps live in the same monorepo as your design system components, and you do not have the burden of managing the whole publishing and versioning process.

However, with Nx, you can generate a publishable library. Then you can build it and publish it to your organization’s npm registry, or even publicly, if you prefer to not work on a monorepo.

Conclusion

In this article we saw how Nx can help your team develop a scalable design system with Storybook painlessly. The ability to generate code enables the team to progress more efficiently and fast. The integrated building and testing of Storybook and Stories within the same environment that is used for the rest of the project, makes things simpler and faster. One CLI to remember commands for, one environment to keep track of, one set of dependencies and tools to keep in sync. Of course, all these are powered by the dependency graph/code analysis and the computation cache that will enhance your speed and CI. Also, Nx Cloud will help you keep track of your deployment and the status of your published Storybook.

You can read much more on how to take advantage of the Nx Storybook plugin here. You can always read more about Nx and learn all things about the benefits of using Storybook.

What we learned:

  • What is Nx
  • What is Storybook
  • What is a design System
  • How Nx helps you build your design system with Storybook
  • Using Nx for design systems outside a monorepo

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK