Nuxt.js に Storybook を導入する 前編

Storybookを利用して Nuxt.js のプロジェクトに スタイルガイドを導入する手法を紹介します。はじめは、Nuxt.js プロジェクトでの Storybook 構築手法についての紹介です。

Storybook は Vue.js のスタイルガイドを作成するためのツールです。 もともとは React のために作成されたツールでしたが、Vue.js にも公式で対応したため、現在は様々な Vue.js のプロジェクトでも利用されるようになりました。Storybookの公式でも Vue.js でのスタイルガイドのデモが用意されており、その機能を確認することが出来ます。

https://release-3-4–storybooks-vue.netlify.com/

Nuxt.js のプロジェクトでも様々なコンポーネントを管理する上で、スタイルガイドの存在は必要不可欠です。長期に渡って保守可能なプロジェクトづくりのためにも Storybook を利用してコンポーネントのスタイルガイドを作成する手法を理解しておきましょう。

Storybook on Vue

まずは、Nuxtのプロジェクトテンプレートを構築します。

$ vue init nuxt-community/starter-template my-project
$ cd my-project
$ npm i 
$ npm run dev

ストーリーブックのインストールを行います。

$ npm i @storybook/vue
$ mkdir .storybook
$ touch .storybook/config.js

.storybook/config.js の中身は以下の内容で構築します。

import { configure, addDecorator  } from '@storybook/vue'

const loadStories = () => {
  require("../stories/index.stories.js")
}

configure(loadStories, module)

一旦ここでは ../stories/index.stories.js というストーリーを読み込んでいます。StoryBookでは、ストーリーと呼ばれるファイルを作成して各種ドキュメントを生成していきます。他のファイルと区別しやすいよう .stories.js という拡張子を利用するのが良いでしょう。

設定がまとまったところで、次にストーリーの作成を行います。以下のコマンドでストーリーファイルを作成して下さい。

$ mkdir stories
$ touch stories/index.stories.js

stories/index.stories.js の中身は以下のような内容で記述します。

import Vue from 'vue';

import { storiesOf } from '@storybook/vue';

import Message from '../components/message.vue';

storiesOf('MyButton', module)
  // .add('story as a template', () => '<message></message>')
  .add('story as a component', () => ({
    components: { Message },
    template: '<message></message>'
  }));

ここで読み込む ../components/message.vue はシンプルなコンポーネントとして定義しておいてください。

最後に 以下のコマンドを実行して完了です。

$ ./node_modules/.bin/start-storybook -p 9000 -c .storybook/

http://localhost:9000 でストーリーブックが閲覧できるようになります。適宜 package.json を編集して簡単に実行できるようコマンド化しておきましょう。

{
  "script":{
    "storybook": "start-storybook -p 9000 -c .storybook/"
  }
}

トラブルシューティング

このままではシンプルなコンポーネントしか描画出来ません。より実践的な利用のためには、 Storybookのカスタマイズが必要になります。

Nuxt 固有の Webpack エイリアスを解決する

Nuxt で一般的に用いられる ~@などのパスのエイリアスを解決するためには Storybook の Webhook 設定に手を加える必要があります。

Storybook の Webpack 設定に手を入れるには、 .storybook/webpack.config.js を作成して以下のように記述します。

const path = require('path')
const rootPath = path.resolve(__dirname, '../')

module.exports = (baseConfig, env, defaultConfig) => {
  defaultConfig.resolve.alias['@'] = rootPath;
  defaultConfig.resolve.alias['~'] = rootPath;

  return defaultConfig;
}

グローバルな SCSS 設定を追記する

コンポーネント固有のスタイルではなく、例えば nuxt.config.js の CSS セクションなどで グローバルな SCSS を読み込んでいる場合、 Storybook でもコレを適用したいと思うかもしれません。

Storybook 全体のテンプレート構造をカスタマイズするには decorator と呼ばれる仕組みを利用するのが便利です。

まず .storybook/Decorator.vue を作成して以下のように記述します。

<template>
  <div class="decoarator">
    <slot name="story"></slot>
  </div>
</template>

<script>
  export default {
    name: 'Decorator'
  }
</script>

<style lang="scss">
  /*必要なSCSS群を読み込み*/ 
  @import "~/assets/scss/bootstrap.scss";
  @import "~/assets/scss/app.scss";
</style>

ここで Storybook 全体で使用する SCSSの設定を記述したら、次に .storybook/config.js を以下のように変更します。

import { configure, addDecorator  } from '@storybook/vue'
import Decorator from './Decorator.vue'

addDecorator((story) => ({
  components: { Decorator },
  template: `
    <decorator>
      <story slot="story"></story>
    </decorator>
  `
}))

const loadStories = () => {
  require("../stories/index.stories.js")
}

configure(loadStories, module)

‘@storybook/vue’から addDecorator 関数を追加でimportし、作成した Decorator.vueaddDecorator 関数内で利用しています。

これで Storybook 内での View で Decorator.vueがテンプレートとして利用されるようになります。

グローバルな CSS や JS の 利用

中には Webpack 経由で読み込まないような 外部の JS ファイル、CSSファイル、Webフォントなどを利用するケースもあるでしょう。通常 nuxt.config.js の head エントリに記述されるこれらのファイルを Storybook 上で利用するには、.storybook/preview-head.html を作成して以下のように HTMLタグを記述します。

<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=xxxxxx">
....  その他必要なリソース等

.storybook/preview-head.html は作成するだけで自動的に認識されるため、.storybook/config.js を編集する必要はありません。

これで概ねNuxt.js 内でのコンポーネントをドキュメント化する準備は出来ました。

冒頭で紹介したVue.js の Storybook デモで利用されているような Addon を利用した機能の追加については次回移行で紹介していきます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です