こんにちは、フロントエンド開発をしている id:cw-nishiguchi です。 ChatWork Advent Calendar 2017の13日目のエントリーは、チャットワークのクラスをリファクタリングした話をしたいと思います。 クラスといっても、HTMLの各要素につけるclass属性のことです。
これまでチャットワークでは、マルチクラス設計を採用していました。 マルチクラスは、構造と装飾や、コンテナ要素とコンテンツ要素などに分離してクラスを定義し、それらのクラスを組み合わせることでスタイルの定義をします。各クラスをその役割で分離していくことで、再利用しやすくなり、結果的にコードの量も少なくなる、という利点があるかと思います。
そういう利点はもちろんありましたが、複数人で開発していく中で問題点というのもいくつかありました。
各クラスがどこで使われているのか、影響範囲の調査が大変
スタイルを変更したときに思わぬ場所に影響が出て表示が崩れてしまうということが…
似たようたクラスが増えてしまうことがある
クラスが増えてくると、どういうクラスがあるのか網羅し辛くなり、似たような役割を持ったクラスが知らず知らずのうちに増えていってしまうことが…
影響範囲などを考えて意図的に作られたクラスもあるかもしれないですが、コメントなどが残っていないと、作った本人しかその意図がわからない…
クラスの役割が曖昧になる
その役割を明確に表すクラス名にしないと、作った本人以外には、何のためのクラスなのかがわかり辛くなり、関係のないプロパティを追加されてしまうことが起こってしまう…
どういうリファクタリングをおこなったか
以上のような問題点が実際に発生することがありましたので、クラス設計を見直すことを考え始めました。ただ、それを実施するには、チャットワークの規模になると、かなりのコストが必要なことが明白で、また、機能開発と同時に進める必要があり、一度にすべてリファクタリングをおこなうことはできなかったので、実施するかどうか慎重な判断が求められました。
しかし、今後の新機能開発や拡張性を考えたときに、設計を見直したほうが、CSSの影響範囲を狭め、スムーズな開発が出来るだろうと考え、クラス設計の見直しを実施することにしました。
では、どういったリファクタリングをおこなったのかですが、
シングルクラスを採用
新たなクラス設計は、シングルクラスを採用しました。文字通り、各要素に付与するクラスはひとつで、複数クラスを組み合わせてスタイルを当てるマルチクラスとは異なる設計です。
マルチクラス、シングルクラスなど、どういった設計手法を採用するにしても、運用次第でそれぞれにメリット、デメリットはあるかと思います。 私達のチームでは、複数人開発でメンテナンス時の影響範囲を狭めるメリットを重視して、シングルクラスを取り入れました。
BEMベースの命名
クラスの命名には、BEMをベースとしたものを取り入れました。
コンポーネントのベースをBlockとし、
roomList
そのコンポーネントを構成する各要素のElementを__(アンダースコア2つ)でつなぐ規則としました。
roomList__avatar
そして、その要素の状態を表すModifierを--(ハイフン2つ)で繋いで、各要素を表現するような規則にしました。
roomList__avatar--selected
共通スタイルをmixin化
シングルクラス設計では、各要素に振られたそれぞれのクラスにCSSのルールセットを定義していきますので、似たようなスタイルの記述も増えていきます。特にボタンなどはアプリ全体で使用されるので、そのルールセットも増えがちです。
そういった同じようなスタイルは、mixinにして利用するようにしました。
@mixin buttonShapeBase { ボタンの構造を定義する } @mixin buttonPrimaryBase { ボタンの見た目を定義する } .messageInput__sendButton { @include buttonShapeBase; @include buttonPrimaryBase; }
このようにmixinを組み合わせるのは、マルチクラスでクラスを組み合わせるのとあまり違いがないので、mixinを編集する際は影響範囲に注意が必要です。 そのため、ボタンやアイコンなど、全体に渡り共通のデザインで使用されるもの以外は、あまり広範囲で使用する想定にはせず、mixinの影響範囲を極力狭めるようにしました。
改善された点
このリファクタリングで次のような効果が得られました。
メンテナンス性が向上した
シングルクラス化により、スタイルを定義するルールセットは一箇所だけになるため、その影響範囲も明確になり、思わぬ場所で思わぬスタイルが当たってしまう、ということがなくなりました。
ただし、先にも書きましたが、そこで利用されているmixinを触る場合は、その影響範囲を調査する必要はあります。
HTMLが読みやすくなった
HTMLのクラス属性に記述するものは、1つだけになり(一部JavaScriptで使用するクラスが必要な箇所では2つ)、マルチクラスのときに比べて読みやすくなったのでは、と感じています。
構造がわかりやすくなった
命名規則がBEMベースとなったことで、各コンポーネントの構造が以前に比べてわかりやすくなりました。
まとめ
チャットワークで今年取り組んだ、CSSのクラス設計を見直したことについて書いてみました。
まだすべて終わったわけではありませんが、複数人での開発、今後の機能開発やメンテナンスを見据えると、これまでに掛けてきた工数に見合う効果は得られたのではないかと考えています。