Vite + Vue + Vuex プロジェクトに Storybook を導入する

Vite
ViteVueフロントエンド

Vue 2 の場合は、vue-cli + Vue 2 で Webpack を使うケースが多いですが、Vue 3 では Nuxt.js を利用しない場合は、Vite が有力な候補になります。

この記事では Vite + Vue 3 で Storybook を使う方法を説明します。

Vite 自体は 公式のサイト は日本語版もありますので、そちらをみていただくのが早い理解につながると思いますが、何より起動が webpack と比べて桁違いに早いです。

環境

  • node: 16.14.2
  • yarn: 1.22.19
  • Vue: 3.2.37
  • Vite: 3.0.2
  • Storybook: 6.5.9

プロジェクト作成

1.Vite プロジェクト作成。create vite するだけです。

yarn create vite   

yarn create v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Installed "create-vite@3.0.0" with binaries:
      - create-vite
      - cva
✔ Project name: … vite-storybook
✔ Select a framework: › vue
✔ Select a variant: › vue-ts

2.依存関係のインストールと起動

yarn
yarn dev

http://127.0.0.1:5173 へのアクセスで以下が表示されます。

ちなみに、Volar は VSCode の拡張機能で Vue3 を利用する際に使います。Vue2 までは Vetur を使います。

http://localhost:5173 アクセス結果
http://localhost:5173 アクセス結果

Storybook の導入

1.Storybook と、Vite ビルダーのインストール。

// --builder オプションをつける方法でもOK
npx storybook init
yarn add --dev @storybook/builder-vite

2.Storybook の起動

yarn storybook

そのままだとエラーになります。

yarn storybook
yarn run v1.22.19
$ start-storybook -p 6006
info @storybook/vue3 v6.5.9
info 
ERR! Error [ERR_REQUIRE_ESM]: require() of ES Module /vite-storybook/.storybook/main.js from /vite-storybook/node_modules/@storybook/core-common/dist/cjs/utils/interpret-require.js not supported.
ERR! main.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
ERR! Instead rename main.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /vite-storybook/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

storybook init で生成された .storybook/main.js の拡張子を cjs に変更します。

mv .storybook/main.js .storybook/main.cjs

再度行うと Storybook が起動できます。

Storybook 起動結果
Storybook 起動結果

このままホットリロードもできます。普段 webpack 使っていると、Vite は動いてないのかな?と思うくらい更新が早いです。

Storyの作成

Storybook init をした時点で、サンプルがあるのでわかりやすいですね。以前はメジャーバージョンが変わるごとに書き方が変わっていて、すごく悩んだのですが。普通に Story を書くぶんには初期のサンプルで十分で、改めて書くまでもなかったので、ここでは Vuex を使う方法を。

Storybook で Vuex だったりを使う場合には、@Storybook/vue3 が必要になります。Vuex と合わせて追加します。

yarn add vuex @storybook/vue3

次に、テスト用の store を用意します。ここではシンプルに state に hoge という変数を用意。

// src/store.js

import { createStore } from 'vuex';

export default createStore({
  state: {
    hoge: 'vuex state!!!'
  }
});

Storybook で store を読み込ませます。

// .storyboo/main.js

import { app } from '@storybook/vue3';
import store from '../src/store';

app.use(store);

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
}

横着して、サンプルで生成される Button.vue を少し変えます。

// src/stories/Button.vue(一部省略しています)

<template>
  <button type="button" :class="classes" @click="onClick" :style="style">{{ label +  ":" + hello }}</button>
</template>

<script>
import './button.css';
import { reactive, computed } from 'vue';
import { useStore } from 'vuex';

export default {
  ~~~
  setup(props, { emit }) {
    props = reactive(props);

    const store = useStore();

    return {
      hello: store.state.status,
      ~~~~
    }
  },
};
</script>

保存すると表示名に store にあるデータが表示されます。

Storybook で useStore を利用すると、Vuex の state にアクセスできます
Storybook で useStore を利用すると、Vuex の state にアクセスできます。

これで使えるようになりました。

コメント