Expo ReactNativeのStorybookを0から入れ直す

こんにちは、カミナシの@tomiです。

本日は、ExpoでのStorybookの導入について書いていきます。

StorybookのサイトにReactNativeでの導入方法が記載されていますが、それ通りだけでは上手く動かなかったので、ExpoでStorybookを使いたい人の参考になればと思います。

なぜStorybookを入れようと思ったのか

現在カミナシのデザインチームでは、ブランドガイドラインを固めてくれています。それを基に新たに0からデザインシステムを作り、現行デザインをリプレイスする予定です。

デザインシステムができてからエンジニアが動き出しては、時間がなくて殴り書きのコードができあがってしまうのが、予想できます。。

せっかくデザインシステムを作ったのに、それが守られなかったりデザインシステムに振り回されては本末転倒なので、今のうちから準備しておこうというのと、Storybook使ったことなかったので勉強のために導入してみました。

さよなら古のStorybook・・・😭

以前にも導入した形跡がありましたが、1年以上前からメンテナンスが止まっています。

どうやらまだサービスがローンチされる前に、モックとしてお客様にお見せするために使っていたようです。

コードの中身も大分変わってしまい動かなくなっていたので、Storybookをまるっと入れ直したいと思います。

f:id:kaminashi-developer:20210406085003p:plain

ようこそNew Storybook

ベースはこちらドキュメントに沿って、導入していきます。

https://storybook.js.org/tutorials/intro-to-storybook/react-native/en/get-started/

npx -p @storybook/cli sb init --type react_native

早速パッケージをインストールしようとしたら、エラーが発生。

f:id:kaminashi-developer:20210406085142p:plain

yarnのバージョンが1.22.4だとエラーが起こっているぽかったので、1.19.0に落としてインストールを進める。

yarn policies set-version 1.19.0

npx -p @storybook/cli sb init --type react_native

こちらのバージョンでは問題なくインストールできました。

yarn policiesで追加された変更(.yarn/releases.yarnrc内のyarn-path)を削除して、元の1.22.4のバージョンでに戻して、再度パッケージをインストールする。

rm -f .yarn/releases
rm -f .yarnrc
yarn

無事サンプルのStoryBookが追加されました。

f:id:kaminashi-developer:20210406085212p:plain

サンプルが動くか確認するため起動しようとしたが、エラー発生。

yarn storybook

f:id:kaminashi-developer:20210406085244p:plain

https://github.com/storybookjs/storybook/issues/5919と似ていたので、@storybook/theming をインストールする。

バージョンも他の依存パッケージと合わせる。

yarn add -D @storybook/theming@^5.3

改めて起動。

yarn storybook

f:id:kaminashi-developer:20210406085447p:plain

無事起動したかと思いきや、、、なにかおかしい。

サイドメニューが表示されない。

f:id:kaminashi-developer:20210406085505p:plain

アプリも起動しないといけないようでした。

yarn start

f:id:kaminashi-developer:20210406090432p:plain
メニューは表示されたが、右側の表示が切り替わらない。。

スマホに依存しているパッケージが入っていてExpo Webで起動できないのが原因で、ブラウザでは確認できないのかも。

アプリでStorybookを確認する

どうやらアプリ側のApp.tsxで、Storybookの自動生成されたコンポーネント./storybook/index.jsを呼び出すと、アプリで確認が可能になるようなので試してみます。

環境変数でStorybookを起動するかアプリを起動するかを切り替えられるようにする↓

STORYBOOK_ENABLED=1 yarn start --ios

app.config.js

export default {
  extra: {
    storybookEnabled: process.env.STORYBOOK_ENABLED,
  },
}

App.tsx

import Storybook from './storybook'
...
export default Constants.manifest.extra.storybookEnabled ? Storybook : App

さらに、Expoを使っているので./storybook/index.jsのコメントに書いてある通り少し編集します。

2箇所、Expoでは不要なコードがあるのでコメントアウトしておく。

// if you use expo remove this line
// import { AppRegistry } from 'react-native';

// If you are using React Native vanilla and after installation you don't see your app name here, write it manually.
// If you use Expo you should remove this line.
// AppRegistry.registerComponent('%APP_NAME%', () => StorybookUIRoot);

これでStorybookを起動。

STORYBOOK_ENABLED=1 yarn start

無事シミュレータ内で起動しました!

f:id:kaminashi-developer:20210406085524p:plain

welcomeページから切り替わらないよ、という場合はエディタで適当な*.stories.jsを開いて保存すると表示されるようになるかと思います。

また、ブラウザで開かれている方は相変わらず表示されませんが、サイドメニューを操作するとアプリ側にも同期されるので、プロパティの変更などには使えます。

f:id:kaminashi-developer:20210406090500p:plain
ブラウザでHello KAMINASHI !と変更したものがシミュレータに反映された

最後に

今回は一旦起動まで。

storyディレクトリに*.stories.js があると絶対にメンテナンスされなくなるので、コンポーネントが置かれている場所に置いて管理するのと、StoryShotsで自動スナップショットテストの導入などもやりたかったです。

yarnのバージョンによってはインストールできなかったり、start-storybookが動かずドキュメント通りにはいかなかったり、想定よりも導入に時間がかかってしまいました。

今度改めて、より使いやすいStorybookを目指して改良していこうと思います。

(書いてる途中で思ったけど、Expoのフォルダ内で管理するよりも、WebUIとアプリUI用のリポジトリを作成して、そこにStorybookを導入した方が良いかも。)