Vue CLI で Storybook を使う（TypeScript）

## 追記：2018-08-14

先日 RC がとれた（リリースされた） Vue CLI 3.0 で使おうとするとこのやり方では出来なかったので、調べているとプラグインが出ていて、そちらを使うとうまく動いたので紹介します。

- [vue-cli-plugin-storybook](https://www.npmjs.com/package/vue-cli-plugin-storybook)

プロジェクトにインストールして

```bash
$ vue add storybook
```

ってやるだけで必要なファイルを生成して必要な依存を書き込んでくれます。 `webpack.config.js` を用意せずに

```bash
vue-cli-service serve:storybook -p 6006
```

でスタートできたりします。

（追記終わり）

---


Vue CLI, Storybook ともに中に webpack を持っていて、一緒に使おうとすると動いてくれませんでした。



今年（2018年）の3月に投稿されている https://medium.com/@almeynman/setup-vue-with-storybook-using-vue-cli-3-0-typescript-example-1be64a7cc7ac に解決策が書いてありますが、Vue CLI が Webpack 4 を使うようになってからそのまま使えなくなっているので、その補足としてこの記事を書きます。


コードだけ見たい方はこちら：https://github.com/kiyopikko/vue-storybook

## 環境

- Vue CLI: `3.0.0-beta.16`
- Node: `10.4.0`
- Yarn: `1.7.0`

## 手順

### セットアップ

```bash
$ vue create vue-storybook
```

今回は以下のように。

![](https://i.gyazo.com/418887b5cee16d1c03f914d51b03c696.png)

Storybook for vue をインストール。

```bash
$ cd vue-storybook
$ yarn add -D @storybook/vue@alpha
$ yarn add -D @types/storybook__vue
```

Webpack 4 を使うために Storybook の v4（アルファ版） を入れます。アルファなので十分にテストされていないですが、Storybook はユーザーに見てもらうところではないのでアリだろうという判断で...

addon もすべて `@alpha` をつけて add する必要があるので注意です。

```bash

# 必要ならば
$ yarn add -D @storybook/addon-actions@alpha
$ yarn add -D @types/storybook__addon-actions
```

### ストーリーの作成

`src/components` に `HelloWorld.vue` のストーリー `HelloWorld.story.ts` を作成します。

```typescript
// src/components/HelloWorld.story.ts

import { storiesOf } from "@storybook/vue";
import HelloWorld from "./HelloWorld.vue";

storiesOf("HelloWorld", module).add("default", () => ({
  components: { HelloWorld },
  template: '<HelloWorld msg="Hello from Storybook" />'
}));
```

### `.storybook` の作成

`config.js` を作成します。`src` の中の `＊.story.ts` というファイルを対象にします。

```js
// .storybook/config.js

import { configure } from "@storybook/vue";

const req = require.context("../src", true, /.story.ts$/);
function loadStories() {
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
```

https://medium.com/@almeynman/setup-vue-with-storybook-using-vue-cli-3-0-typescript-example-1be64a7cc7ac の記事を参考に V4 用の `webpack.config.js` を書きます。

```js
// .storybook/webpack.config.js

const merge = require("webpack-merge");

const createDefaultWebpackConfig = require("@storybook/core/dist/server/config/defaults/webpack.config.js").createDefaultWebpackConfig;
const wrapInitialConfig = require("@storybook/vue/dist/server/wrapInitialConfig").default;

const vueConfig = require("@vue/cli-service/webpack.config.js");

module.exports = (storybookBaseConfig) => {
  const storybookConfig = wrapInitialConfig(createDefaultWebpackConfig(storybookBaseConfig));

  return {
    ...vueConfig, // use vue's webpack configuration by default
    entry: storybookConfig.entry, // overwite entry
    output: storybookConfig.output, // overwrite output
    // remove duplicated plugins
    plugins: merge({
      customizeArray: merge.unique(
        "plugins",
        [
          "HotModuleReplacementPlugin",
          "CaseSensitivePathsPlugin",
          "WatchMissingNodeModulesPlugin"
        ],
        plugin => plugin.constructor && plugin.constructor.name
      )
    })(vueConfig, storybookConfig).plugins,
    resolve: {
      ...vueConfig.resolve,
      alias: {
        ...vueConfig.resolve.alias,
        vue$: storybookConfig.resolve.alias.vue$
      }
    }
  };
};

```

### 実行

最後に `package.json` に storybook 実行コマンドを入れて

```json
{
  ...
  "scripts": {
    ...
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"  
  },
  ...
}
```

実行します

```
$ yarn storybook
```

![](https://i.gyazo.com/2ff0fb71be7d18b572b814e96a917035.png)