【超簡単フロントエンド開発】Storybook6.1 + Nuxtjs (+Vuetify) : フォローアップ


## はじめに

以前に、こんな記事を書きました。  

[【超簡単フロントエンド開発】Storybook6.1 + Nuxtjs (+Vuetify)](https://qiita.com/kaku3/items/05a0de729da7faba9ce4)

が、導入後色々あって超簡単に使うには少しコツが必要でしたのでフォローアップ記事を書きます。

## Storybook 実行時 v-data-table等、一部 Vuetify コンポーネントが利用できない

storybook 実行時に Vuetify が見えていないのが原因。
以下2点追加する。

1. plugins フォルダに storybook から参照用に vuetify object を作る

``` [nuxt-root]/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'

Vue.use(Vuetify)

const opts = {}

export default new Vuetify(opts)
```

2. stories.js で template に vuetify を注入する

``` [your-component-path]/[your-component-name].stories.js
// [your-component-path] / [your-component-name] 部分は、実際のコンポーネント名に置き換えてください。
import vuetify from '@plugins/vuetify' // ★追加
import { action, configureActions } from '@storybook/addon-actions'
import [your-component-name] from './[your-component-name]'

const Template = (args, { argTypes }) => ({
  vuetify, // ★追加
  props: Object.keys(argTypes),
  components: { [your-component-name] },
  template: '<[your-component-name] v-bind="$props" />',
})

export const Default = Template.bind({})
Default.args = {}
```
(参考：神がワークアラウンドを提示しているissue)
https://github.com/storybookjs/storybook/issues/13532

## storybook 実行時、@/ などのパスが解決できない

Storybook の設定ファイル main.js に webpack 設定が書ける。
必要なパスを追加する。

``` [nuxt-root]/.stories/main.js
module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials"
  ],
  // Storybook側での webpack 設定に設定を追加できるように hook が用意されている。
  // ★追加 -->
  webpackFinal: async (config, { configType }) => {
    config.resolve.alias = Object.assign(config.resolve.alias, {
      '@': path.resolve(__dirname, '..'),

  })
  // ★<-- 追加
}
```

## テスト用のデータを .stories.js に定義するのが面倒くさい

backend を FastAPI(Python)で作成する、または OpenAPI を手書きするなどして openapi.json を用意する。

openapi-sampler を利用して json の雛形を取得し、テストデータを埋める。

### 事前準備

1. json-loader 追加

```
yarn add json-loader json-import-loader -D 
```

2. json を load 出来るように main.js 修正

``` [nuxt-root]/.stories/main.js
  webpackFinal: async (config, { configType }) => {
    // ★追加
    config.module.rules.push({
      test: /\.json$/,
      type: 'javascript/dynamic', // only for webpack 4+
      use: [
        {
          loader: 'json-import-loader',
          options: {
            processPath: path => path,
          }
        },
        { loader: 'json-loader' }
      ]
    })
    ...
```

### テストデータ定義例

``` SampleGenerator.js
const json = require('./openapi.json')
const OpenAPIsampler = require('openapi-sampler')

class SampleGenerator {

  static getSample() {
    // 任意のスキーマのデータを返却
    // 実際は faker なども使って定義：https://www.npmjs.com/package/faker
    return OpenAPIsampler.sample(json.components.schemas.sample)
  }
}
module.exports = SampleGenerator
```

``` [your-component-path]/[your-component-name].stories.js
import vuetify from '@plugins/vuetify'
import { action, configureActions } from '@storybook/addon-actions'
import SampleComponent from 'SampleComponent'

import SG from '@test-data/SampleGenerator' //★ 追加

const Template = (args, { argTypes }) => ({
  vuetify,
  props: Object.keys(argTypes),
  components: { SampleComponent },
  template: '<SampleComponent v-bind="$props" />',
})

export const Default = Template.bind({})
Default.args = {
  sample: SG.getSample()    //★ 追加
}
```

## おわりに

Storybook開発で一見手間が増えている様に見えますが、動作するモックと仕様書と自動リグレッションテスト用のデータを同時に作成していて、ある意味 **アジャイルの風**を感じました。

設計者・開発者・試験担当者の境界が曖昧になっていますが、低予算・短納期のプロジェクトの場合全て一人でやることも想定されますし、エクセルの仕様書や試験項目を作るよりは動くモック、動く試験データもできるのでよいのかなと思いました。