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/
ビルド用コマンドも自動で追記してくれます
"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を表示したページを作ります。
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
というリンクが追加されたかと思います
このように xxx.stories.js
を追加していけばページを作ることができます。
Vuetifyを導入する
私の環境ではVuetifyを導入していたので、storybookでも使えるようにします。
.storybook
配下に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を入れてあげます
import Vue from 'vue';
import ToggleButton from 'vue-js-toggle-button'
Vue.use(ToggleButton);
エイリアスを設定する
src/hoge/hoge...
のようにフルパスを書くのは面倒なので、aliasを設定してあげましょう。
.storybook/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-loader``css-loader``sass-loader
がinstallされていない環境の場合、installをお願いします。
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
});
return config
}
共通CSS(SASS)をimportする
.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します。
以下のように追記してください。
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を入れてください。
import '@storybook/addon-actions/register';
import '@storybook/addon-storysource/register';
source-loader
source-loaderは開いているsotyies.jsのコードを表示してくれるアドオンです。
こんな感じでコードが読めます。
docs入れるほどじゃないプロジェクト向けです。
こちらはページごとに設定して使うのではなく、全体反映です。
webpack.configファイルに以下のように追記します
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を入れろ!
という事が書いてありました。
$ 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していたのですが、
<style lang='scss'>
@import '@assets/variables.scss'; // ※@assetsはaliassの登録をしています
@import '@assets/sass/app.scss';
</style>
定数を使ったvueファイルを読み込むとエラーが起きてしまいました。
↓例:buttonコンポーネント
<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
<style lang="scss">
@import '@assets/variables.scss';
</style>
これで動くようにはなりましたが、他にいい解決方法がないかと大分模索しました><
アドバイスございましたらお願いしますm(_ _)m
感想
以上の工程などを行い、storybookを導入してみました。
まとめきれない導入トラブルなんかもあって、とにかく疲れました。。。
webpackとか初心者だからというのものあるのですが、もっとさっくり気軽に導入できるかと思っていたので(^^;
でも一旦環境をつくってしまえば、あとの更新などはとっても簡単なので、
こだわりすぎなければとても使い勝手の良いカタログになりそうです!
導入コストを呑めるのであればおすすめします!
ざっくりなまとめなので不明な点などございましたら
ご質問・編集リクエストくださいませm(_ _)m