Storybook 6.0が出たことだしNuxt+Storybook 6.0のプロジェクトを立ち上げる

この記事は「[株式会社オープンストリーム "小ネタ" Advent Calendar 2020](https://qiita.com/advent-calendar/2020/opst-mini)」の 5 日目の記事です。

Web 向け UI コンポーネント開発ツールの Storybook が 6.x になって、5.x まで使えたやり方 (`storiesOf` など) が通用しなくなりました。

ここでは、2020/12/05 時点で最新の Storybook 6.0.10 を用いて最小構成で始めてみます。

## 環境

- Nuxt.js 2.14.9
- Storybook 6.0.10

```
$ node -v
v14.5.0

$ yarn -v
1.22.5
```

## Nuxtプロジェクトの立ち上げ: `create-nuxt-app`

最新の `create-nuxt-app` でプロジェクトを作成できる `npx` を用いて Nuxt のプロジェクトを立ち上げます。

```
$ npx create-nuxt-app .

create-nuxt-app v3.4.0
✨  Generating Nuxt.js project in .
? Project name: app
? Programming language: TypeScript
? Package manager: Yarn
? UI framework: Bulma
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Linting tools: ESLint, Prettier, Lint staged files, StyleLint, Commitlint
? Testing framework: Jest
? Rendering mode: Single Page App
? Deployment target: Static (Static/JAMStack hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript), Semantic Pull Requests, Dependabot (Fo
r auto-updating dependencies, GitHub only)
? Continuous integration: None
? What is your GitHub username? ysd-marrrr
? Version control system: Git

```

## Storybook の導入

`sb init` を実行するだけで、現在のプロジェクト構成を自動認識して `@storybook/vue` などの最適な Storybook が導入されます。
こちらも `sb` をインストールしなくても `npx` を用いて最新の `sb` を用いてStorybookを導入します。

必ず Nuxt のプロジェクトを作成してから Storybook を導入するという順番にします。

> sb init is not made for empty projects

```bash
npx sb init
```

動作確認するには `storybook` を yarn で呼び出します。
`sb init` と同時にサンプルの Story がセットされているので、これを見ることができます。

```bash
yarn storybook
```

## Story ファイルの場所を変更する

Storybook で使うファイルは `.storybook` 内の設定ファイルと、 `stories` に配置された story ファイルがあります。
story ファイルの場所を変えるには `.storybook/main.js` の `stories` を変更します。

Vue コンポーネントと story ファイルを同梱させる場合は `components` と指定します。

```js:.storybook/main.js
  stories: [
    "../components/**/*.stories.mdx",
    "../components/**/*.stories.@(js|jsx|ts|tsx)"
  ],

```

サンプルの Story は不要なので、 `stories` ディレクトリを削除します。

## Story ファイルを作成する

`stories` で設定したパスに Story ファイルを作成します。

まずは Story にする Vue コンポーネントを用意します。 `create-nuxt-app` で導入した CSS フレームワークを使うようにしています。

```vue:components/CustomButtons.vue
<template>
  <div>
    <p class="introduction">好きな<strong>処理</strong>を選択してください</p>
    <div class="buttons">
      <button class="button is-primary">かんたん</button>
      <button class="button is-link">むずかしい</button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.introduction {
  strong {
    color: red;
    font-size: 150%;
  }
}
</style>
```

次に Story ファイルを作成します。 `.stories.js` のファイル名を付けます。
[Component Story Format](https://medium.com/storybookjs/component-story-format-66f4c32366df) の形式で Story を作成します。

```ts:components/buttons.stories.ts
import CustomButtons from "./CustomButtons.vue";

export default {
  title: "Button",
};

export const custom_buttons = () => ({
  components: { CustomButtons },
  template: "<custom-buttons />",
});
```

## StorybookがCSS(パッケージ)/SCSSを扱えるように設定する

`create-nuxt-app` で CSS フレームワークを導入しても Storybook では別に設定しないと反映されません。
また、Vue コンポーネントで SCSS を使っている場合も Storybook 側で設定が必要です。

はじめに、SCSSを読み込むための `sass-loader` パッケージを導入します。

```bash
 yarn add -D sass sass-loader
```

Storybook でも Webpack を使いますが、その設定ファイルは 6.x から `.storybook/main.js` になりました。
`sass-loader` を使うために設定ファイルを変更します。

```js:.storybook/main.js
const path = require("path");

module.exports = {
  stories: [
    "../components/**/*.stories.mdx",
    "../components/**/*.stories.@(js|jsx|ts|tsx)",
  ],
  webpackFinal: (config) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: ["style-loader", "css-loader", "sass-loader"],
      include: path.resolve(__dirname, "../"),
    });
    return config;
  },
};
```

次に、Storybook で使用したい CSS フレームワークを設定します。
Bulma の場合はパッケージで導入した Bulma を読み込む SCSS を作成します。

```scss:.storybook/global.storybook.scss
@charset "utf-8";
@import "~bulma/bulma";
```

そして、 `.storybook/preview.js` でその SCSS を読み込みます。

```js:.storybook/preview.js
// Global SCSS
import "./global.storybook.scss";
```

ここで `yarn storybook` を実行して、該当の Story を開くと SCSS が使えて CSSフレームワークが適用された Vue コンポーネントを見ることができます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216963/1c2982e9-62c2-cfa0-9c5e-867fbe52d36b.png)


## 参考

Storybook: UI component explorer for frontend developers
https://storybook.js.org/

[基本編] .storybook/main.js の作成｜ Vue と CSF によるモダンな Storybook 6 のはじめかた
https://zenn.dev/sa2knight/books/aca5d5e021dd10262bb9/viewer/e61f4f

Nuxt.js(TypeScript) × Vuetify × Storybook を使用して開発環境を再構築してみる - Ikkyu's Tech Blog
https://ikkyu.hateblo.jp/entry/2020/04/03/191112