【最小手順2021/01】Nuxt.js + Storybook6.1 + Storyshots

## はじめに

Nuxt.js と storybook6.1 インストールまでは割とさっくり動きましたが、Storyshots 実行に必要な手順が現時点では不安定な様なので記事にしました。
※そのうち直ると思われますが import 文などなどが動かなかったり、公式の手順が微妙だったりしてハマります。

## StoryShots とは

Storybook で作成した Stories の jsdom スナップショットを取得・比較してくれる Storybook の addon です。
変更したつもりがないところまで変更されていたのに気づくのに便利そうです。

[StoryShots](https://www.npmjs.com/package/@storybook/addon-storyshots)

## インストール

以下の手順で導入します。

1. nuxt app 作成
2. Storybook インストール
3. StoryShots addon インストール

### nuxt app 作成

`npx create-nuxt-app {projectName}` で作成します。

対話式コンソールに回答してプロジェクトを作成します。
ポイントは StoryShots ではテストに Jest を利用するので、Testing framework に Jest を選択することです。

今回は `sample` というプロジェクトを作成することにします。

```
npx create-nuxt-app sample
? Project name: sample
? Programming language: TypeScript 
? Package manager: Yarn
? UI framework: None
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Testing framework: Jest
? Rendering mode: Single Page App    
? Deployment target: Static (Static/JAMStack hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Continuous integration: None
? Version control system: None
```

- [ ] nuxt app が起動するか？(http://localhost:3000 にアクセスしてページを確認)

```
cd sample
yarn dev
```

![00-nuxt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/c53b7905-760d-7a42-3bc7-19ea71010fed.png)

### Storybook インストール

```
cd sample
npx sb init
```

- [ ] フォルダ`.storybook/`, `stories/` が生成されているか？

```
sample/
  .storybook/  # ★
  stories/     # ★
  components/
  ...
```

- [ ] storybook が起動するか？(http://localhost:6006 にアクセスしてページを確認)

```
yarn storybook
```

![10-storybook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/f9dd8245-9dcb-4923-80d1-12b9834d16b0.png)

※実際の開発は components/ フォルダ以下での開発になるので、.storybook/main.js の書き換えが必要になるが、今回は動作確認を目的としているので、stories フォルダに生成されるサンプルの story を storyshots でスナップショットを取る方針とする。

### Introduction.stories.mdx の記述を大きく削除

上記スクリーンショットの通り、豪華なページとなっており、これを Storyshots で動作させるのは少々面倒。
開発では、基本的な mdx のコードが書ければ支障がないため動作しないコードを削除する。

(削除対象)

- svg import
- style 定義
- html コード

``` 削除後-Introduction.stories.mdx
import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="Example/Introduction" />

# Welcome to Storybook

Storybook helps you build UI components in isolation from your app's business logic, data, and context.
That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA.

Browse example stories now by navigating to them in the sidebar.
View their code in the `src/stories` directory to learn how they work.
We recommend building UIs with a [**component-driven**](https://componentdriven.org) process starting with atomic components and ending with pages.

```

### StoryShots インストール

```
cd sample
yarn add @storybook/addon-storyshots -D
```

#### StoryShots を実行するテストコードを記述(公式サイト通り)

```　test/Storyshot.spec.js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots();
```

※デフォルトで入っている`test/Logo.spec.js`は消しておいた方がトラブルシューティングがしやすいです。

#### jest.config.js を修正

- mdx の transpile でエラーになる
- css の import でエラーになる

```
module.exports = {
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/$1',
    '^~/(.*)$': '<rootDir>/$1',
    '^vue$': 'vue/dist/vue.common.js',
    '\\.(css|scss)$': 'jest-css-modules', // ★追加(css, scss の import処理)
  },
  moduleFileExtensions: [
    'ts',
    'js',
    'vue',
    'json'
  ],
  transform: {
    '^.+\\.mdx?$': '@storybook/addon-docs/jest-transform-mdx',  // ★追加(mdx処理)
    "^.+\\.ts$": "ts-jest",
    '^.+\\.js$': 'babel-jest',
    '.*\\.(vue)$': 'vue-jest'
  },
  collectCoverage: true,
  collectCoverageFrom: [
    '<rootDir>/components/**/*.vue',
    '<rootDir>/pages/**/*.vue'
  ]
}
```

対応モジュールもインストール

```
cd sample
yarn add -D jest-css-modules
yarn add -D @storybook/addon-docs/jest-transform-mdx
```

#### .babelrc 修正

```
{
  "env": {
    "test": {
      "presets": [
        [
          "@babel/preset-env",
          {
            "targets": {
              "node": "current"
            }
          }
        ]
      ],
      // ★追加(import -> require変換)
      "plugins": [
        "@babel/plugin-transform-modules-commonjs",
      ]
    }
  }
}
```

- [ ] StoryShots が実行出来るか確認

```
yarn test
```

※2回実行して以下の様なログが出ていれば成功。

```
  Storyshots
    Example/Button
      √ Primary (28 ms)
      √ Secondary (7 ms)
      √ Large (6 ms)
      √ Small (6 ms)
    Example/Header
      √ Logged In (30 ms)
      √ Logged Out (27 ms)
    Example/Page
      √ Logged In (25 ms)
      √ Logged Out (25 ms)
```

※Vueファイルで大量のエラーが出るが、Storybookのサンプルの問題なので今回はスルー。

## おわりに

Storyshots は簡単で便利という記事が多くて、簡単にやったら時間が足りなくて大変でしたので作業整理も兼ねて記事にしました。
ぶっちゃけ、まだ便利さを実感できていないのですが、ちょっと設定を追加しておくと後で便利になるならやっておいて損はないと思ってます。
後で作業される方のお役に立てれば幸いです。