こんにちは。いつも青い服を着ているエンジニアの堀口です。
nanapi.jpでは様々な観点から検証サイクルを回しサービス改善を行っています。デザインもその例外ではありません。しかし多くのメンバーが関わるプロジェクトでABテストや機能改修を繰り返していると、コードのスパゲッティ化が問題になってきます。複雑に絡み合ったマークアップは検証サイクルを鈍化させるだけでなく、やがて影響範囲がわからないから消せない負のスパイラルに陥り、しまいには手の付けられない状態になってしまいます。
そこでデザインの検証サイクルを加速させるべく、nanapiではマークアッププロセスの改善に取り組んでいます。今回はその事例のご紹介です。
なお、nanapiの別プロダクトであるIGNITIONもほぼ同時期にマークアップ改修作業を行っており、その様子も前々回のブログにてご紹介しています。
マークアッププロセスの改善にむけたnanapiの取り組み
今回、マークアッププロセスの改修にあたり重視した要件は次の4点です。
- いつでも消せること (粗結合)
- DRYであること
- 属人性が排除されていること
- 作業がめんどくさくならないこと (自動化)
これらの実現のために、マークアップ作業におけるテクニカル面とオペレーション面を見直し、以下のような取り組みを行いました。
SMACCS + mindBEMを組み合わせたマークアップ規約の制定
マークアップの設計手法としてOOCSS, SMACCS, BEMなどが有名です。
twitter Bootstrapに代表されるOOCSSはCSSレベルでDRYな構造であり、マルチクラスを活用する事で非常に高速なマークアップが可能です。一方で緻密な設計が要求されるため、ビルド&スクラップを繰り返すプロジェクトにとっては非常に運用の難易度の高い設計手法でもあります。
そこでSMACCSの設計をベースにし命名規約としてmindBEMを組み合わせた下記のマークアップ規約を制定しました。
分類 | 命名規約・概要 |
---|---|
Base | スタイルのリセットや、aタグの基本色などの定義に用いる。クラス等は用いずに要素セレクタレベルで定義する。 |
Layout |
layout__hoge ナビゲーション領域, コンテンツ領域などの定義に用いる。粒度の目安はCakePHPのLayoutエレメントで定義するくらい。 |
Module |
module-name__element[--modiffer] リストやメニューなどのコンポーネントの定義に用いる。mindBEM的な --modifferは極力用いずにStateとThemeを利用する。 |
State |
is--status コンポーネントの状態によって見た目が変化する場合の定義に用いる。JSやテンプレートエンジンとの相性を考慮しマルチクラスで記述。 |
Theme |
theme--theme-name スキンのようなテーマの定義に用いる。State同様にマルチクラスで記述。nanapi.jpでは記事の属するカテゴリ(恋愛, 生活, 趣味など)によって異なる見た目を定義するときに用いています。 |
シングルクラスでの実装
コンポーネントを粗結合にするため、上記のようなシングルクラスでのマークアップを基本とし、マルチクラスはStateとTheme以外では用いないようにしています。もちろん
.clearfixなどの汎用クラスも使いません。
OOCSS的なマルチクラス運用はきちんと設計,運用すれば非常に強力な手法ですが、本来の利用範囲を逸脱したハック的な運用をはじめてしまうと負のスパイラルに陥るという危険な側面もあります。
新陳代謝が高く様々な習熟度のメンバーが関わるプロジェクトでは、冗長でもシングルクラス運用の方が安定した生産性を発揮できると判断しました。
スタイルガイド駆動の開発
新たなコンポーネントを作成する際、まずはスタイルガイドの作成からはじめています。
スタイルガイドジェネレータにはStyledoccoを利用しています。
他にも有名どころのKSS, Kalei Styleguideなどを検討しましたが、
- 1つのファイルでマークアップもSassも記述できる(テンプレートが分離していない)
- 導入が簡単
という2点からStyledoccoを選択しました。
スタイルガイドを開発の中心とすることで
- コンポーネント内で完結する粗結合なマークアップが行いやすい
- マークアップとSassを同時に見渡せるため作業効率がよい
- 作業完了時にはドキュメントが完成しているため、エンジニアやディレクターとの連携がスムーズ
といったメリットがありました。非常にオススメです。
Sass + CompassでDRYなコーディング
CSSをシングルクラスで記述するとコードは非常に冗長になり全くDRYではありません。そこでプリプロセッサを活用してDRYに記述していきます。プリプロセッサは常識となって久しいですね。
nanapiではプリプロセッサとしてSass(SASS)を利用しています。機能はSCSSと全く同じなので両者には趣味程度の違いしかありませんが、SASSはシンタックスがHaml的でより厳密なのが特徴です。nanapiではデザイナーもマークアップやコーディングを行っているのですが、シンタックスに厳密なSASSを用いる事でキレイなコードを書く習慣が身に付きやすいのではないかと期待しています。
またSassフレームワークとしてCompassを使い、mixinなどの車輪の再発明を抑止しています。nanapiの場合、Compassを用いることで全コンポーネントで横断的に使用する独自のmixinの記述量が劇的に減りました。
スプライトイメージ作成の自動化
スプライトイメージは”消しやすいマークアップ”にとって厄介な問題です。精緻に組まれたスプライトイメージの一部から不要になったリソースを取り除く作業は精神的にも工数的にも大きな負担であり、もし自動化されていなければ真っ先に放置されてしまうことでしょう。
そこでCompassのスプライトイメージ生成機能を活用しています。これだけでもCompassを採用する理由にできるほど強力な機能です。
さらにnanapiではスプライトイメージ自動生成とsvgを組み合わせて、retinaディスプレイ対策とsvgフォールバックを同時に行う取り組みも行っています。
定期的なリファクタリング期間の確保
Sassの変数やextendsは気持ちがいいのでついつい多用してしまいがちですが、不必要にグローバル変数やextendsを追加すると後の掃除が大変になってしまいます。この先どのように進化するのわからないコンポーネントに対しては、一旦ハードコーディングをして検証結果を待つ事も大切です。そのような実装を行った際は、refactorタグなどをつけてissue管理しておくとロストを防げます。そして今後の方向性や他のコンポーネントとの共通性が明らかになってきた段階で必ずリファクタリングを行うようにしています。
ペアプログラミングやプルリクエストで設計思想を共有
nanapiではデザイナーも上述のようなコーディング作業を行っています。そこで重要になるのが設計思想の共有です。
はじめはコーディング力が「見た目はキレイに整えられるレベル」だったデザイナーも、ペアプログラミングやプルリクエストでのレビューを繰り返す事で構造化されたコーディングを行えるようになりました。
初期コストは多少増えますが、プロジェクトコミットするメンバー全てが設計思想を共有する事でコードのスパゲッティ化を未然に防ぐことが出来ることを考えれば、とても効率的であると思います。
まとめ
いかがでしょうか。今回のブログでは、新陳代謝の高いプロジェクトでも破綻のしにくいnanapi流マークアップ手法をご紹介しました。設計の見直しや自動化ツールの導入といったテクニカル面での取り組みや、チームにおける設計思想の共有やリファクタリング工数の確保といったオペレーション面での取り組みは、そのひとつひとつは特に目新しいものではありません。しかし総合的にコツコツと取り組むことでより効率的なマークアップ体制が整えられると考えています。
今後もさらに開発体制を強化するべく、様々な取り組みに挑戦していきます。
nanapiでは新しい開発手法に挑戦したいデザイナー・エンジニアを募集しています
一緒にすばらしい開発体制とイケてるプロダクトを作りましょう!