LoginSignup
15
11

More than 3 years have passed since last update.

Nuxt(Vue)でStorybookの環境を作る。VuetifyやSASSの読み込みも

Last updated at Posted at 2020-01-09

Storybookとは

ざっくりいうと【UIコンポーネントの簡易カタログ作成ツール】です。
チーム内のエンジニアだけではなく、デザイナーとのやりとりにも便利です。
詳しくは以下のサイトを見ていただけるとイメージが分かるかと思います。

公式サイト
Storybookがなぜ必要か?(Vue.js編)

まずは導入

手動で入れる方法もあるのですが、CLIで簡単に導入してから細かく自己設定を増やしていく方をおすすめします。
CLI Options

# 対象のディレクトリ直下で行ってください
$ npx -p @storybook/cli sb init

or

$ yarn add -D @storybook/cli
$ yarn sb init

最初はおすすめのaddon(拡張ツール)なども入っているので、のちのち不要であれば消してしまってください。

以下のディレクトリが追加されます

.storybook/
src/stories/

ビルド用コマンドも自動で追記してくれます

package.json
"scripts": {
    ~
    "storybook": "start-storybook -p 9009 -s public",
    "build-storybook": "build-storybook -s public"
  }

なんて便利なんでしょう!
(これ手動で作ってたときはえらい手間でした・・・)
追加されたファイルなどをざっと確認したら、早速実行してみてみましょう

# 以下面倒なのでyarnの書き方で統一します
$ yarn storybook

story(ページ)を追加する

src/stories配下にtest.sotires.jsというファイルを追加してみましょう。
適当にv-data-tableを表示したページを作ります。

test.stories.js
import { action } from '@storybook/addon-actions';

export default {
  title: 'Vue'
};

export const DataTable = () => ({
  template: `
    <div>
      <h2>【DataTable】Vue既存のコンポーネント</h2>

      <v-data-table
      :headers="[
        { text: 'ID', value: 'id' },
        { text: '名前', value: 'name' },
        { text: '編集', value: 'action', align: 'center', sortable: false }
      ]"
      :items="[
        {id: 0, name: '名前0'},
        {id: 1, name: '名前1'},
        {id: 2, name: '名前2'},
        {id: 3, name: '名前3'},
        {id: 4, name: '名前4'},
        {id: 5, name: '名前5'},
        {id: 6, name: '名前6'}
      ]"
      :items-per-page="10"
      multi-sort
      class="elevation-1"
    >
      <template v-slot:item.action="{ item }">
        <v-icon @click="action" color="grey" dark>
          mdi-pencil
        </v-icon>
      </template>
    </v-data-table>
    </div>
  `,
  methods: {
    action: action('clicked')
  }
});
export const Title = () => ({
  template: `
    <div>
      <h1>H1タイトル</h1>
      <h2>H2タイトル</h2>
    </div>
  `
});

すると左のメニューにVueというリンクが追加されたかと思います
スクリーンショット 2020-01-09 15.08.44.png

このように xxx.stories.jsを追加していけばページを作ることができます。

Vuetifyを導入する

私の環境ではVuetifyを導入していたので、storybookでも使えるようにします。
.storybook配下にconfig.jsを作成してください。

.sorybook/config.js
import { configure, addDecorator } from '@storybook/vue';

import Vuetify from 'vuetify';
import colors from 'vuetify/es5/util/colors';
import 'vuetify/dist/vuetify.min.css';

const vuetifyOptions = { }

Vue.use(Vuetify, {
  customVariables: ['../src/assets/variables.scss'],
  theme: {
    dark: false,
    themes: { // うちではこのように設定していますが、それぞれの環境に合わせてください
      dark: {
        primary: colors.blue.darken2,
        accent: colors.grey.darken3,
        secondary: colors.amber.darken3,
        info: colors.teal.lighten1,
        warning: colors.amber.base,
        error: colors.deepOrange.accent4,
        success: colors.green.accent3
      }
    }
  }
});

addDecorator(() => ({
  vuetify: new Vuetify(vuetifyOptions),
  template: `<v-app><story slot="story" /></v-app>`
}));

configure(require.context('../stories', true, /\.stories\.js$/), module);

プラグインを導入する

プラグインを入れている環境の場合、storybookでも同様に入れてあげます。
先程作ったconfigに以下を追記しましょう。
今回はToggleButtonを入れてあげます

.sorybook/config.js
import Vue from 'vue';
import ToggleButton from 'vue-js-toggle-button'

Vue.use(ToggleButton);

エイリアスを設定する

src/hoge/hoge...のようにフルパスを書くのは面倒なので、aliasを設定してあげましょう。
.storybook/webpack.config.jsという設定ファイルを作ってください。

.sorybook/webpack.config.js
const path = require('path')
const rootPath = path.resolve(__dirname, '../src')

module.exports = ({ config }) => {
  config.resolve.alias['@']           = rootPath
  config.resolve.alias['@components'] = `${rootPath}/components`
  config.resolve.alias['@assets']     = `${rootPath}/assets`

  return config
}

SASSを使える環境にする

.storybook/webpack.config.jsファイルに以下のように追記します
style-loadercss-loadersass-loaderがinstallされていない環境の場合、installをお願いします。

.sorybook/webpack.config.js
module.exports = ({ config }) => {

  config.module.rules.push({
    test: /\.scss$/,    
    loaders: ['style-loader', 'css-loader', 'sass-loader']
  });
  return config
}

共通CSS(SASS)をimportする

.storybook/Decoretor.vueというファイルを作りましょう

.storybook/Decoretor.vue
<template>
  <div class='decoarator'>
    <slot name='story'></slot>
  </div>
</template>
<script>
  export default {
    name: 'decorator'
  }
</script>

<style lang='scss'> // ここにimportしたいファイルを入れます。
@import '@assets/variables.scss';
@import '@assets/app.scss';
</style>

config.jsにてDecoretorをimportします。
以下のように追記してください。

.sorybook/config.js
import decorator from './Decorator';

addDecorator(() => ({
  components: { decorator }, // componentを使えるようにします
  vuetify: new Vuetify(vuetifyOptions),
  template: `<v-app><decorator><story slot="story" /></decorator></v-app>` // Vuetifyも使いたいので、一段decoratoreをはさみます
}));

addonを導入

addonは以下のファイルにまとめてimportします。
最初の導入時からあるファイルです。必要なaddonを入れてください。

.storybook/addons.js
import '@storybook/addon-actions/register';
import '@storybook/addon-storysource/register';

source-loader

source-loaderは開いているsotyies.jsのコードを表示してくれるアドオンです。
こんな感じでコードが読めます。
docs入れるほどじゃないプロジェクト向けです。
スクリーンショット 2020-01-09 14.36.51.png
こちらはページごとに設定して使うのではなく、全体反映です。
webpack.configファイルに以下のように追記します

.sorybook/webpack.config.js
module.exports = ({ config }) => {
  config.module.rules.push({
    test: /\.stories\.jsx?$/,
    loaders: [require.resolve('@storybook/source-loader')],
    enforce: 'pre',
  });

  return config
}

気になってるaddon

Storybookの新しいアドオン addon-docs がいい感じ
Storybookの便利なaddon機能のご紹介

トラブルシューティング

困ったことと、その対応をざっくりまとめておきます。

Error node-sass??

自分の環境ではnode-sassを導入していたのですが、storybookでsassを導入したあと動かなくなり、困りました。

エラー文言
SassError: Invalid CSS after " @content": expected "}", was "($material-light);

エラー文言を読んでいると、なにやらnode-sassではなくsassを入れろ!という事が書いてありました。

sass導入
$ yarn add sass

するとpackege.jsonからnode-sassが消え、sassオンリーになりました。
これで動くようになりました。
詳しくはnode-sassの何が悪いのかわかりません。
node-sassを消したくなかったので、この方法以外の解決法はないかといろいろ調べましたが、
結局みつからず・・・

install core-js??

山程のエラーが出て、ビルドできなくなりました。
エラー文言の最後に以下のようなcore-jsをinstallしろ!という文言がありました。

エラー文言
To install them, you can run: npm install --save core-js/modules/es6.array.find core-js/modules/es6.array.iterator core-js/modules/es6.date.to-string core-js/modules/es6.function.name core-js/modules/es6.object.assign core-js/modules/es6.object.keys core-js/modules/es6.object.to-string core-js/modules/es6.promise core-js/modules/es6.regexp.constructor core-js/modules/es6.regexp.match core-js/modules/es6.regexp.replace core-js/modules/es6.regexp.search core-js/modules/es6.regexp.split core-js/modules/es6.regexp.to-string core-js/modules/es6.string.includes core-js/modules/es6.string.iterator core-js/modules/es6.string.repeat core-js/modules/es6.string.starts-with core-js/modules/es6.symbol core-js/modules/es7.array.includes core-js/modules/es7.promise.finally core-js/modules/es7.symbol.async-iterator core-js/modules/web.dom.iterable

なのでinstallしてみたのですが、

$ yarn add core-js

なおもエラー。
困ったところ、こちらのサイトが参考になりました。
Nuxt2.5でのエラー:core-js/modules/es6.array.find in ./.nuxt/client.js
2.6.2を入れなくちゃいけないようでしたので、入れてみました。

$ yarn add core-js@2.6.2

するとみごと解決!
issueも出ていて解決済ってあったんですけどね。まだcore-jsとの依存性はあるようです。

sassの定数を読み込んでもらえない

Decoretor内で定数をimportしていたのですが、

.storybook/Decoretor.vue
<style lang='scss'>
@import '@assets/variables.scss'; // ※@assetsはaliassの登録をしています
@import '@assets/sass/app.scss';
</style>

定数を使ったvueファイルを読み込むとエラーが起きてしまいました。
↓例:buttonコンポーネント

button.vue
<template>
  <v-btn class="test-button">mdi-pencil</v-btn>
</template>

<style lang="scss">
.test-button {
  background-color: map-get($grey, lighten-2);
}
</style>

仕方がないので各compoent内でも定数が書かれたファイルをimport

button.vue
<style lang="scss">
@import '@assets/variables.scss';
</style>

これで動くようにはなりましたが、他にいい解決方法がないかと大分模索しました><
アドバイスございましたらお願いしますm(_ _)m

感想

以上の工程などを行い、storybookを導入してみました。
まとめきれない導入トラブルなんかもあって、とにかく疲れました。。。
webpackとか初心者だからというのものあるのですが、もっとさっくり気軽に導入できるかと思っていたので(^^;

でも一旦環境をつくってしまえば、あとの更新などはとっても簡単なので、
こだわりすぎなければとても使い勝手の良いカタログになりそうです!

導入コストを呑めるのであればおすすめします!

ざっくりなまとめなので不明な点などございましたら
ご質問・編集リクエストくださいませm(_ _)m

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11