【Nuxt3】Storybookを導入する

# はじめに

前回の記事

https://qiita.com/keitaMax/items/1a28eea86f163fd2952f

前回作成したものもとに開発していきます。

今回は、Storybookを導入して画面を確認することができるようにします。

https://storybook.js.org/docs/get-started/install

公式のStorybookのインストール手順に従っていきたいと思います。


# Storybookをインストールして実行する

以下コマンドでStorybookをインストールします。
```
npx storybook@latest init
```

インストールが終わったら以下のコマンドで起動させます。

```
npm run storybook
```
そうするとブラウザが立ち上がりStorybookの画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/1a0bd989-e1f4-0fb6-8568-70198ffef7c1.png)

しかし、少し時間がたった後、以下のようなエラーが出てしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/6073fa76-7d22-8e7c-f7aa-0f297aab8842.png)

`vite.config.js`ファイルを作成しなくてはいけなかったようです。

そのため、以下のサイトであるような`vite.config.js`を作成しました。

https://ma-vericks.com/blog/vite-nuxt-vue/

```js:vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()]
})
```

これでもう一度Storybookの起動コマンドを再実行すると、以下のようにエラーがなくなり、デフォルトで入っているStorybookのボタンなどが見れるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/6d72741f-17dd-21f9-30c6-51d67ef0c68a.png)


# 自分で作成した画面をStorybookで見る

前回作成したカウントアップする画面をStorybookで見ることができるようにしたいと思います。

まずは、`views/CountView/index.tsx`と同じ階層に`index.stories.ts`を用意します。

```ts:index.stories.ts
import MyPage from './index.vue';

export default {
  title: 'Views/CountView',
  component: MyPage,
  parameters: {
    layout: 'fullscreen',
  },
};
export const Default = {
  args: {
    label: 'CountView',
  },
};
```

読み込むファイルを`views`配下も含めてあげるようにするため、`.storybook/main.js`を以下のように修正します。
```js:main.js
/** @type { import('@storybook/vue3-vite').StorybookConfig } */
const config = {
  stories: [
    // '../stories/**/*.mdx',
    // '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)',
    '../views/**/*.stories.@(js|jsx|mjs|ts|tsx)',
  ],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@chromatic-com/storybook',
    '@storybook/addon-interactions',
  ],
  framework: {
    name: '@storybook/vue3-vite',
    options: {},
  },
  docs: {
    autodocs: 'tag',
  },
};
export default config;
```

これでStorybookを立ち上げると、自分の作成したページを見ることができますが、カウンターが動きませんでした。

https://zenn.dev/disney_lady_san/scraps/58fa226b2718b8

どうやら、Nuxtには自動インポート機能があり、それがStorybookではインポートされないために起きているようです。

そのため、Nuxtの自動インポート機能をOffにして、composablesで書いていた処理をReactのように`hooks.ts`にしてindex.vueと同じ階層に置くことにしました。

`nuxt.config.ts`を以下のように修正し、
```ts:nuxt.config.ts
export default defineNuxtConfig({
  devtools: { enabled: true },
  css: ['~/assets/css/main.css'],
  postcss: {
    plugins: {
      tailwindcss: {},
      autoprefixer: {},
    },
  },
  components: ['@/components'],
  imports: {
    autoImport: false, //追加
  },
});
```
`hooks.ts`を以下のように作成しました。

```ts:hooks.ts
import { readonly, ref, type Ref } from 'vue';
const inc = (counter: Ref<number>) => () => counter.value++;
const dec = (counter: Ref<number>) => () => counter.value--;

export const useCounter = () => {
  const counter = ref(0);
  return {
    counter: readonly(counter),
    inc: inc(counter),
    dec: dec(counter),
  };
};
```
そこから、`index.vue`ファイルも`hooks.ts`を読み込むように修正しました。
```vue:index.vue
<script setup lang="ts">
  import { useCounter } from './hooks';

  const { counter, inc, dec } = useCounter();
</script>

<template>
  <div class="bg-red-600">
    カウンター: {{ counter }}
    <button @click="inc">+</button>
    <button @click="dec">-</button>
    <!-- <button
      class="bg-sky-700 px-4 py-2 text-white hover:bg-sky-800 sm:px-8 sm:py-3"
    >
      ...
    </button> -->
  </div>
</template>
```

これでStorybookを起動してみると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/0d19079d-fb69-f094-f99e-ed10d0db4bc6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/9b884ccb-1201-bd49-791e-3ed8e5453dc6.png)

このようにカウントアップが動いていることを確認することができました。



# おわりに

Next.jsと比べると色々やらなくてはいけないことが多いなという印象がありました。

もし、もっといいやり方があるや、間違っている部分があるといったご意見をいただければ幸いです。

今後はStorybookを用いてテストコードを書いていきたいと思っております。

最後まで読んでいただきありがとうございました。

# 参考
https://ma-vericks.com/blog/vite-nuxt-vue/


# 次の記事

https://qiita.com/keitaMax/items/8cee088b6edfc0a9266d