疎結合なコンポーネントを心がけた話

こんにちは、たじまです。

最近はコロナに加え猛暑の毎日ですが皆さんいかがお過ごしですか? 私は外出ただけで溶けてしまいそうだったので大人しくエアコンの効いた部屋に閉じこもることにしました。

さて、今日は先月公開した eeNotes というサービスについてやってたことを少しだけまとめてみようと思います。

eenotes.work

よければ少しだけ触ってみてください。 Twitterもやってます!

eeNotes とは

Treasure2019のチームで開発したプロダクトをそのままリリースまでしよう!と継続開発して先々月の6月24日にリリースされた ノート共有サービス です。

簡単に説明すると、全員がノートのまとめ先を同じにしちゃえばテスト前にまとめるの上手い人のノートが見えるし、取ってない講義がどんな感じかわかるし、ノートを取ってる人は自分のポートフォリオとしても使えちゃう最高のサービスです。

私はデザインとフロントエンドを担当しました。

サイト経緯

Treasureで完成した時はこんな感じでした。

// TODO 昔のトップ画像探す。

ある程度やってる人ならわかる、Material Design ごりごりのデザインです。 整っていて、UIも複雑でなくわかりやすいのですが逆に言うと単調でぱっとしないですね。

継続開発を続けるうちに、このデザインだとあまり胸を張って宣伝できないなということになり旧デザインを一掃することになりました。

新しい全体像はこんなかんじ。デザインの作成は私のゴリ押しでFigmaを使いました。いいですよね、Figma

何をしたか

技術選定

さて、ここからやっと本題です。 今回はデザインの改修に合わせ、設計まわりは Atomic Design で進めていくことにしました。

圧倒的にフロント周りのタスクが多い中、CSSアレルギーを発症してしまう人が多かったので小さいコンポーネントCSS+αを書く人、APIをつなげる人でそれぞれ分担しました。 Atomic DesignでいうとCSSの人が ~Template までを担当して、APIつなげる人が Template ~ Page を触るといった方針です。

私はCSSを書く担当になりました。コンポーネント単体を確認するためにstorybookを使いました。

storybook.js.org

storybookとは

Storybook is an open source tool for developing UI components in isolation for React, Vue, Angular, and more. It makes building stunning UIs organized and efficient.

Storybookを使うとコンポーネントをカタログ一覧にまとめることができます。 また、スタイルやロジックを一つのコンポーネントに閉じ込めることができるので疎結合コンポーネントを作ることができます。

デザインがきっちり決まってる上でstorybookを使うとパズルゲームをしてるようでとても気持ちいいです。

実際に

CSS担当がどうつくるか考えてみます。

f:id:tjmschk:20200816213820p:plain
ユーザー画面

figmaのスクショです。 今回はこのユーザーのタグの部分を作ってみます。

f:id:tjmschk:20200816215212p:plain
この部分

実はこれとほぼ同じものが実はノート詳細画面にもありました。(右上のユーザー情報が出てる部分)

f:id:tjmschk:20200816215313p:plain
ノート詳細画面

内容は全く変わらず、当たるスタイルが変わってるだけそうなので再利用できそうですね。

|
|___Atoms
|         |___Tag
|         |        |___UserTag
|         |                 |___UserTag.tsx
|         |                 |___index.stories.tsx
|         |                 |___index.ts
|         |___Icon
|                   |___DeterminIcon
|                           |___DeterminIcon.tsx
|                           |___index.stories.tsx
|                           |___index.ts
|___Molecules
         |___Tag
                  |___UserTagGroup
                          |___UserTagGroup.tsx
                          |___index.stories.tsx
                          |___index.ts
         

ファイル構造はこんな感じになりました! (Codepen作ったんだけど動かない...😢)

storybookのファイル内ではコンポーネントを単体で表示しています。 (本番と同じようにするために背景だけstorybookのファイル上で付け足しました。)

storybookの画面はこんなかんじになりました!

f:id:tjmschk:20200816221216p:plain
ユーザー画面のほう

f:id:tjmschk:20200816221219p:plain
ノート詳細のほう

ユーザー詳細画面の方のタグと、ノート詳細にあるタグの違いはpropで分けられるようにしています。

UserTagGroup という名前にしちゃったのですが、そこにどんな種類の文字列が入るかとかはこのコンポーネントが知っておく必要はないかなと思い可変長の配列を入れられるようにしました。

storybook を使うとコンポーネントのpropをコードを変更することなくGUIで操作できるのでデバッグもしやすくなります。バージョンが上がってまた使いやすくなったみたいなので詳細はこちらから。

storybook.js.org

storybook使ってみて

メリット

圧倒的にこれはメリットでした。prop で渡す値を外部から変えたり、 action で変わるコンポーネントの挙動などを単体でテストできたのでバグが少なくすみました。

デメリット

  • Files changed が増える
  • (慣れてないと)実装にかかる時間も増える
    f:id:tjmschk:20200816224807p:plain
    これはとあるフロントの1pr

と言う感じでした。これはファイル構造のせいもあるのですが export する用の index.ts, storybookのファイル、コンポーネントの中身のファイルと一つ作るだけで3つのファイルが誕生するので、 1 pageつくるのに差が大きかったです。 また安心安全にかけるのですが慣れていなかったり速度を優先する場合には向いてないのかもしれません。

終わりに

今回は storybook について言及させていただきました。自分的にとても体験が良かったのでチームメンバーにも是非進めていきたいところです。

ありがとうございましたー!

おまけ

同じチームの仲間が eenotes の記事を書いているので読んでみてください!

qiita.com

qiita.com

qiita.com

note.com