既存サービスにCSS設計(コンポーネント管理)を導入する方法
1からサービスを開発するときなら、1からCSS設計を行うことができますが、自社サービスの開発だとなかなかそんな状況には出くわしません。
既存サービスのぐちゃぐちゃなCSSに対して、開発をしていくことになります。
しかし、少しずつでもCSS設計を導入していきたいという場面があるかと思います。
既存CSSの依存を完全に断ち切れればいいのですが、そうはいかかないのではないでしょうか?
そんなとき、どのように設計(コンポーネント管理)を行うべきか、ということについてまとめていきます。
コンポーネント管理は可能な限り大きな単位で行いたい
この考え方の元進めてきます。
なるべく大きな単位で行っていた方が、いろいろなところで使用することができます。
よくある、一覧と詳細という単位で考えてみます。
一覧でAというコンポーネントを作ったとします。
一覧で何回か同じ見た目がでてくるので、これをコンポーネントAとしました。
そのため、list.component
のようなディレクトリを作成し、この中に、_A.scss
をおきました。
そして、 list
下に index.scss
を作成して、この中で _A.scss
を import しました。
今度は、詳細を考えていきます。
先ほどとは別の人が開発したとします。
そしてこのひとは詳細という中で、コンポーネント管理を行うことにしました。
そのため、detail.component
のようなディレクトリを作成し、この中に、_B.scss
をおきました。
そして、 detail
下に index.scss
を作成して、この中で _B.scss
を import しました。
結果以下のような構成になりました。
sass/ ├ detail/ │ ├ component │ │ └ _B.scss │ └ index.scss │ ├ list/ │ ├ component │ │ └ _A.scss │ └ index.scss
でもこのまま進むと、 detail と list は別々のまま進んでいきます。
もし detail で _A.scss
を使用したくなったらどうしましょうか?
コンポーネントの呼び出し
そのまま detail.scss で _A.scss
を import する。
この対応はどうでしょうか?
Sass的にも可能な方法です。でもこれはちょっと気持ちが悪くないでしょうか?
特に、_A.scss
からしてみれば、list 以下のコンポーネントとして作成されているはずなのに、なぜか全然違う箇所から呼び出されています。
僕はこれは絶対にやって欲しくない方法です。混乱しか招きません。
sass 下に common 的なものを作る
下記のような構成に変更します。
sass/ ├ common/ │ └ _A.scss │ ├ detail/ │ ├ component │ │ └ _B.scss │ └ index.scss │ ├ list/ │ ├ component │ │ └ 移動 │ └ index.scss
この後はいろいろな対応ができます。
1. 必要なコンポーネントを各自で import する
毎回 import を追加したりしないといけないので、正直面倒です。
あまりオススメしません。
2. view 側で読み込むcssを増やす
これは common 下でも index.scss を作る必要があります。
common + 各ページ のCSSで1ページを構成することになります。
方針次第かなと思います。別に間違った方法ではないです。
レイアウト用の view ファイルで読み込んでおくというのいいと思います。
3. 各ページで import するためのファイルを用意する
1, 2 の組み合わせといった感じでしょうか。
全ての common を読み込むけど、css は1枚になります。
common 下に 一括 import 用のファイルを用意しておくと便利です。
今回の例では common が sass 直下に用意していますが、階層によってはもっと深いところに common が存在していることもあります。
大きなサービスだと、この状態になることが多いと思います。
そんなときはこの方法がオススメです。
詳細については後述します。
4. コンポーネントの枠を取っ払う
コンポーネントの管理を一括で行うということです。
各ページ単位では component ディレクトリを作成して切り出しません。
こうなっていれば、管理はとても簡単です。
ディレクターやデザイナーを巻き込んで対応した際の究極がここかもしれません。
コンポーネントが出揃えばページを作成する際に、ほとんどCSSを書く必要のないレベルが目指せます。
まぁ現実的にはここまでは厳しいです。
総合的に見て 3 がオススメです。
既存ページにも採用しやすいです。
ディレクトリについて
途中から採用する場合も、徐々に階層を上げていくことで、段階を踏んでリファクタが可能になります。
ただし、クラス名にプレフィックスをつけるなどの対応を取らないと、クラス名が衝突する可能性があるので注意が必要です。
徐々に階層を上げていくことで、最終的にはサイト全体に関わるものとなります。
最初から、わかっていればいいのですが、そういったことはなかなかありません。
なので、他に影響しない可能な限り大きな単位で、コンポーネント管理をしていくこをオススメします。
これが上記で 3 をオススメした理由です。
一番よくあるのは機能単位の開発だと思います。
そういったときは、その機能単位でコンポーネントを意識してCSS設計するだけでも、練習にもなるしスッキリすると思います。
ページ単位の場合、例に上げたような状況に出くわすこともあります。
そんなときは、なるべくいい方法で対応しましょう。
最初に作成した人がCSS設計を心がけていても、その後の対応次第ではぐちゃぐちゃになってしまいます。
まとめ
以上が、既存サービスにCSS設計(コンポーネント管理)を導入する方法になります。
チームで開発をする際は、一人で進めても間違った対応が入ってしまうと結局破綻するので、チームでルールを決めておく必要があります。
コンポーネント化ができないメンバーがいたとしても、設計を破綻させないようにルールだけは守れるようにしておきましょう。
import や view からの読み込みルールだけでも守れれば、破綻に向かうことはかなり軽減されるはずです。