Skip to content

Commit

Permalink
Merge branch 'storybookjs:next' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
The-Code-Monkey committed May 10, 2022
2 parents 117892a + a17ea78 commit eb952ec
Show file tree
Hide file tree
Showing 55 changed files with 995 additions and 56 deletions.
2 changes: 1 addition & 1 deletion addons/actions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"prop-types": "^15.7.2",
"react-inspector": "^5.1.0",
"regenerator-runtime": "^0.13.7",
"telejson": "^5.3.3",
"telejson": "^6.0.8",
"ts-dedent": "^2.0.0",
"util-deprecate": "^1.0.2",
"uuid-browser": "^3.1.0"
Expand Down
2 changes: 1 addition & 1 deletion app/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"read-pkg-up": "^7.0.1",
"regenerator-runtime": "^0.13.7",
"sass-loader": "^10.1.0",
"telejson": "^5.3.3",
"telejson": "^6.0.8",
"ts-dedent": "^2.0.0",
"ts-loader": "^8.0.14",
"tsconfig-paths-webpack-plugin": "^3.3.0",
Expand Down
16 changes: 8 additions & 8 deletions docs/addons/writing-presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
title: 'Write a preset addon'
---

[Storybook preset addons](./addon-types.md#preset-addons) are grouped collections of `babel`, `webpack`, and `addons` configurations that support specific use cases in Storybook, such as typescript or MDX support.
[Storybook preset addons](./addon-types.md#preset-addons) are grouped collections of `babel`, `webpack`, and `addons` configurations that support specific use cases in Storybook, such as TypeScript or MDX support.

This doc covers the [presets API](#presets-api) and how to use the presets mechanism for [advanced configuration](#advanced-configuration).

## Presets API

A preset is a set of hooks that is called by Storybook on initialization and can override configurations for `babel`, `webpack`, `addons`, and `entries`.

Each configuration has a similar signature, accepting a base configuration object and options, as in this webpack example:
Each configuration has a similar signature, accepting a base configuration object and options, as in this Webpack example:

<!-- prettier-ignore-start -->

Expand Down Expand Up @@ -46,7 +46,7 @@ For example, Storybook's Mihtril support uses plugins internally and here's how

### Webpack

The webpack functions `webpack`, `webpackFinal`, and `managerWebpack` configure webpack.
The Webpack functions `webpack`, `webpackFinal`, and `managerWebpack` configure Webpack.

All functions take a [webpack4 configuration object](https://webpack.js.org/configuration/).

Expand All @@ -62,11 +62,11 @@ For example, here is how Storybook automatically adopts `create-react-app`'s con

<!-- prettier-ignore-end -->

- `webpack` is applied to the preview config after it has been initialized by storybook
- `webpack` is applied to the preview config after it has been initialized by Storybook
- `webpackFinal` is applied to the preview config after all user presets have been applied
- `managerWebpack` is applied to the manager config

As of Storybook 6.3, Storybook can run with either `webpack4` or `webpack5` builder. If your addon needs to know which version of Webpack it's running inside, the version and the actual webpack instance itself are both available inside your preset:
As of Storybook 6.3, Storybook can run with either `webpack4` or `webpack5` builder. If your addon needs to know which version of Webpack it's running inside, the version and the actual Webpack instance itself are both available inside your preset:

<!-- prettier-ignore-start -->

Expand All @@ -81,7 +81,7 @@ As of Storybook 6.3, Storybook can run with either `webpack4` or `webpack5` buil

### Manager entries

The addon config `managerEntries` allows you to add addons to Storybook from within a preset. For addons that require custom webpack/babel configuration, it is easier to install the preset, and it will take care of everything.
The addon config `managerEntries` allows you to add addons to Storybook from within a preset. For addons that require custom Webpack/Babel configuration, it is easier to install the preset, and it will take care of everything.

For example, the Storysource preset contains the following code:

Expand Down Expand Up @@ -176,9 +176,9 @@ Entries are the place to register entry points for the preview. For example it c

## Advanced Configuration

The presets API is also more powerful than the [standard configuration options](../configure/webpack.md#extending-storybooks-webpack-config) available in Storybook, so it's also possible to use presets for more advanced configuration without actually publishing a preset yourself.
The presets API is also more powerful than the [standard configuration options](../builders/webpack.md#extending-storybooks-webpack-config) available in Storybook, so it's also possible to use presets for more advanced configuration without actually publishing a preset yourself.

For example, some users want to configure the webpack for Storybook's UI and addons ([issue](https://github.com/storybookjs/storybook/issues/4995)), but this is not possible using [standard webpack configuration](../configure/webpack.md#default-configuration) (it used to be possible before SB4.1). However, you can achieve this with a private preset.
For example, some users want to configure the Webpack for Storybook's UI and addons ([issue](https://github.com/storybookjs/storybook/issues/4995)), but this is not possible using [standard Webpack configuration](../builders/webpack.md#default-configuration) (it used to be possible before SB4.1). However, you can achieve this with a private preset.

If it doesn't exist yet, create a file `.storybook/main.js`:

Expand Down
163 changes: 163 additions & 0 deletions docs/builders/builder-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
---
title: 'Builder API'
---

Storybook is architected to support multiple builders, including [Webpack](https://webpack.js.org/), [Vite](https://vitejs.dev/), and [ESBuild](https://esbuild.github.io/). The builder API is the set of interfaces you can use to add a new builder to Storybook.

![Storybook builders](./storybook-builders.png)

## How do builders work?

In Storybook, a builder is responsible for compiling your components and stories into JS bundles that run in the browser. A builder also provides a development server for interactive development and a production mode for optimized bundles.

To opt into a builder, the user must add it as a dependency and then edit their configuration file (`.storybook/main.js`) to enable it. For example, with the Vite builder:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-vite-builder-install.yarn.js.mdx',
'common/storybook-vite-builder-install.npm.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-vite-builder-register.js.mdx',
]}
/>

<!-- prettier-ignore-end -->

## Builder API

In Storybook, every builder must implement the following [API](https://github.com/storybookjs/storybook/blob/next/lib/core-common/src/types.ts#L170-L189), exposing the following configuration options and entry points:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-builder-api-interface.ts.mdx',
]}
/>

<!-- prettier-ignore-end -->

In development mode, the `start` API call is responsible for initializing the development server to monitor the file system for changes (for example, components and stories) then execute a hot module reload in the browser.
It also provides a **bail** function to allow the running process to end gracefully, either via user input or error.

In production, the `build` API call is responsible for generating a static Storybook build, storing it by default in the `storybook-static` directory if no additional configuration is provided. The generated output should contain everything the user needs to view its Storybook by opening either the `index.html` or `iframe.html` in a browser with no other processes running.

## Implementation

Under the hood, a builder is responsible for serving/building the preview `iframe`, which has its own set of requirements. To fully support Storybook, including the [Essential addons](../writing-stories/introduction.md) that ship with Storybook, it must consider the following.

### Import stories

The `stories` configuration field enables story loading in Storybook. It defines an array of file globs containing the physical location of the component's stories. The builder must be able to load those files and monitor them for changes and update the UI accordingly.

### Provide configuration options

By default, Storybook's configuration is handled in a dedicated file (`storybook/main.js|ts`), giving the user the option to customize it to suit its needs. The builder should also provide its own configuration support through additional fields or some other builder-appropriate mechanism. For example:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-builder-api-configuration-options.ts.mdx',
]}
/>

<!-- prettier-ignore-end -->

### Handle preview.js exports

The [`preview.js`](../configure/overview.md#configure-story-rendering) configuration file allows users to control how the story renders in the UI. This is provided via the [decorators](../writing-stories/decorators.md) named export. When Storybook starts, it converts these named exports into internal API calls via virtual module entry, for example, `addDecorator()`. The builder must also provide a similar implementation. For example:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-builder-api-preview-exports.ts.mdx',
]}
/>

<!-- prettier-ignore-end -->

### MDX support

[Storybook's Docs](../writing-docs/introduction.md) includes the ability to author stories/documentation in MDX using a Webpack loader. The builder must also know how to interpret MDX and invoke Storybook's special extensions. For example:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-builder-api-mdx.ts.mdx',
]}
/>

<!-- prettier-ignore-end -->

### Generate source code snippets

Storybook annotates components and stories with additional metadata related to their inputs to automatically generate interactive controls and documentation. Currently, this is provided via Webpack loaders/plugins. The builder must re-implement this to support those features.

### Generate a static build

One of Storybook's core features it's the ability to generate a static build that can be [published](../sharing/publish-storybook.md) to a web hosting service. The builder must also be able to provide a similar mechanism. For example:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-builder-api-build-server.ts.mdx',
]}
/>

<!-- prettier-ignore-end -->

### Development server integration

By default, when Storybook starts in development mode, it relies on its internal development server. The builder needs to be able to integrate with it. For example:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-builder-api-dev-server.ts.mdx',
]}
/>

<!-- prettier-ignore-end -->

### Shutdown the development server

The builder must provide a way to stop the development server once the process terminates; this can be via user input or error. For example:

<!-- prettier-ignore-start -->

<CodeSnippets
paths={[
'common/storybook-builder-api-shutdown-server.ts.mdx',
]}
/>

<!-- prettier-ignore-end -->

### HMR support

While running in development mode, the builder's development server must be able to reload the page once a change happens, either in a story, component, or helper function.

### More information

This area is under rapid development, so the documented is still in progress and subject to change. If you are interested in writing your builder, we encourage you to check [webpack](https://github.com/storybookjs/storybook/tree/next/lib/builder-webpack4), [Vite](https://github.com/storybookjs/builder-vite), and Modern Web's [dev-server-storybook](https://github.com/modernweb-dev/web/blob/master/packages/dev-server-storybook/src/serve/storybookPlugin.ts) source code. In addition, we have a wonderful contributor community on [Storybook Discord](https://discord.gg/storybook) if you have questions. Ping us in the [#contributing](https://discord.com/channels/486522875931656193/839297503446695956) channel.

#### Learn more about builders

- [Vite builder](./vite.md) for bundling with Vite
- [Webpack builder](./webpack.md) for bundling with Webpack
- Builder API for building a Storybook builder
24 changes: 24 additions & 0 deletions docs/builders/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
title: 'Builders'
---

Storybook, at its core, is powered by builders such as Webpack and Vite. These builders spin up a development environment, compile your code—Javascript, CSS, and MDX—into an executable bundle and update the browser in real-time.

![Storybook builder overview](./storybook-builder-workflow.png)

## CLI basics

Before diving into setting up Storybook's builders, let's look at how the CLI configures them. When you initialize Storybook (via `npx sb init`), the CLI automatically detects which builder to use based on your application. For example, if you're working with Vite, it will install the Vite builder. If you're working with Webpack, it installs the Webpack builder based on your current version.

Additionally, you can also provide a flag to Storybook's CLI and specify the builder you want to use:

```shell
npx sb init --builder <webpack4 | webpack5 | vite>
```

## Manual setup

Storybook uses the Webpack 4 builder by default if you don't specify one. If you want to use a different builder in your application, these docs detail how you can set up Storybook's supported builders.

- [**Vite builder**](./vite.md) for bundling your stories with Vite with near-instant HMR.
- [**Webpack**](./webpack.md) for bundling your stories with Webpack with improved performance
Binary file added docs/builders/storybook-builder-workflow.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/builders/storybook-builders.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit eb952ec

Please sign in to comment.