こんにちは。APP・UXチームの大谷です。約1年ぶりくらいの投稿です。
最近は家にいることが多いので、ちょっと時間がかかる料理でもしてみよう。。
と餃子を皮から作ったりしています。餃子の皮を作る時は、お湯より水を使って練った方がモチモチ感がでて美味しいです。自分の好みにあった配合と焼き方を研究していきたい。
さて、今回は表題の通りNuxt.jsプロジェクトにStorybookを導入する方法について書いていきたいと思います。
Storybookとは?
StorybookとはUIコンポーネントをカタログのように一覧表示できたり、振る舞いをテストできるオープンソースのツールです。
なぜやるか?
新しく始まったプロジェクトをきっかけに、コンポーネントの管理方法やデザイナーとの連携について改めて整理してみようということでStorybookの導入が検討されました。
デザインチーム/フロントエンドチームで事前に用途についても協議してみました。
両チームとも基本的にコンポーネントの管理/共有に使いたい(ボタンやフォーム単位のパーツについて)という意見だったので、ページ全体など大きい単位での表示テストの用途には使わず、まずは小さい単位でのコンポーネントの管理/共有・スタイルガイドとして活用していこうという内容で認識を合わせました。
さっそくStorybookを導入してみる
まずはNuxtのサンプルプロジェクトを作成します。
% yarn create nuxt-app sample-project
作成したプロジェクト内でstorybookを導入していきます。
yarn add -D @storybook/cli yarn sb init --type vue yarn storybook
storybook/cliは現在のlatest版(5.3.19)を使っています。
無事Storybookが立ち上がりましたが、Nuxtアプリケーションの本体を立ち上げようとしたらエラーが発生してしまいました。
yarn run dev Type checking in progress... ERROR Failed to compile with 39 errors * core-js/modules/es6.array.from in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js ............. To install them, you can run: npm install --save core-js/modules/es6.array.find core-js/modules/es6.array.from 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でめちゃめちゃ怒られます。 Storybookを導入した時にbabelとcore-jsのバージョンで依存関係の問題が発生してしまうようです。解消するためにここでは明示的にcore-jsの2系を指定してインストールし直しました。
yarn add core-js@2
あとはstoriesファイルと設定を追加していきます。 今回はpropsやdescriptionを作るためのaddonも追加してみました。
yarn add -D @storybook/addon-knobs yarn add -D storybook-addon-vue-info
addon有効にする設定を追加します。
// .storybook/addons.js import 'storybook-addon-vue-info/lib/register'; import '@storybook/addon-knobs/register';
configファイルを追加します。
// .storybook/config.js import { configure, addDecorator } from '@storybook/vue'; import { withKnobs } from "@storybook/addon-knobs"; import { withInfo } from 'storybook-addon-vue-info' // xxx.stories.jsに対してaddonを反映 addDecorator(withInfo) addDecorator(withKnobs); // どのファイルを見るか設定する。今回は../components下のstoriesファイルを対象にする configure(require.context('../components', true, /\.stories\.(js|ts)$/), module);
storiesファイルを作成。
import { storiesOf } from '@storybook/vue' import { text, select } from '@storybook/addon-knobs' // サンプルで作成したコンポーネント import Button from '@/components/atoms/button/index.vue' const stories = storiesOf('Buttons', module) stories.add( 'button sample story', () => { return { // 対象のコンポーネント設定 components: { Button }, props: { colorStyle: { type: String, default: select('colorType', ['green', 'orange']) }, value: { type: String, default: text('default', 'sample') } }, // 描画する内容を設定 template: `<Button :value=value :colorStyle=colorStyle />` } }, { info: true } )
Buttonコンポーネントの表示を確認できるようになります。
GitLab Pagesで公開
毎回環境を立ち上げなくてもいいようにGitLab Pagesで公開するようにしました。 masterにマージされたタイミングでGitLab Pagesを更新するようにしたgitlab-ci.ymlファイルの設定がこちらです。
image: node:latest cache: paths: - node_modules/ pages: stage: deploy tags: - sample_runner only: - master before_script: - 'yarn install' script: - 'yarn build-storybook' - 'cp -pr storybook-static ./public' artifacts: paths: - public
最後に
今回は記載していませんが、Jestと連携してstoriesファイルのスナップショットテストをすることもできるようです。コンポーネントの管理/共有をするために便利なStorybookですが、更新せずに古くなってしまっては意味がないのでスナップショットテストと連携するなど必ず更新する仕組みをつくっていくことも課題になります。
実運用はまだはじまっていませんが、デザイナーとエンジニアお互いにとって幸せな開発環境にできれば良いなと思います!