シンクロ・フード エンジニアブログ

飲食店ドットコムを運営する、株式会社シンクロ・フードの技術ブログです

リポジトリを横断したコンポーネント(Sass)管理を行う

シンクロ・フードの四之宮です。
前回ブログを書いてからかなり時間が経ってしまいましたが、その間に自作キーボードデビューしました。
Mint60, レツプリ, Helix, Fortitude60, ErgoDash を作りました。
社内の自作キーボード勢もかなりいるので、いずれ社内のキーボード紹介があるかもしれません?
(僕は作ったことないですが、Iris, Corne, Lily58 勢もいます)

さて、挨拶はこのくらいにして、今回は「リポジトリを横断したコンポーネント(Sass)管理を行う」について書いていきます。
コンポーネントと言い切ってしまっていますが、Utilityなどの普通のclassも可能です。
「リポジトリをまたいで CSS (Sass) を共通化したい」そんな要望を満たすための方法になります。
タイトルだけだとよくわからないと思いますので、弊社の現状をふまえて説明していきたいと思います。

運営サービスと以前の状態

弊社では、複数のサービスを運営しています。
代表的なものとして、飲食店.COM, 求人@飲食店.COM があります。
そして、基本的にサイトによってリポジトリ(プロジェクト)が別になっています。
そのため、飲食店.COMで作成したSassファイルを、求人@飲食店.COMで使用する際は、ファイルコピーで対応していました。

しかし、リポジトリが別でも同じCSSを使用したいということもあるのではないでしょうか?
例えば、Utility系のクラスや、LPのような説明ページ、社内でよく使用するパーツなど、こういったものはリポジトリ毎にコードを書くことになってしまっていました。
また、とあるサイトでコンポーネント化を行うと、他サイトでも同じものを使用したいという要望がよくあがってきました。

更にそういった状況の中、CSS設計やコンポーネントというものを本格的に考え始めたのですが、この状態はとても厳しいものでした。
会社でコンポーネントなどの共通CSSを管理していくには、なにか方法を考える必要がありました。

対応案

これらの問題を考える際、対応案は下記の2つありました。

  • git submodule
  • npm package

検討した結果、 npm package で運用していくことに決めました。

npm package の選定理由

運用のしやすさという観点で、 npm package に軍配が上がりました。
選定理由は下記の通りです。

git submodule で運用する場合は、そのものの仕組みを知る必要がありました。
弊社では git submodule を使用している箇所はなかったので、チームメンバーへの普及や学習といったところのコストが大きいと判断しました。
それに比べ、 npm package での運用は、意識することが少なく、すぐに運用できると判断しました。
開発時も、 yarn install するだけでいいという手軽さです。
あとは、import の方法を伝えればそれで終わりです。
使用側が意識することが少ないというのが、大きなメリットでした。

また、後述しますが、「共通CSSリポジトリも変更しつつ、サービスのアプリケーション側のリポジトリも変更する」という場合もあるかと思います。
これも、npm package であれば、解決することができます。
これも選定の理由の1つでした。

導入までの流れ

共通化するCSSを管理するリポジトリの作成

まずは、共通管理するCSSを新規のGitリポジトリで作成します。
その際、 package.json は下記のような記述にします。
重要なのは repository のところです。
(common-css という名前で作成した例)
必要に応じていろいろ追加してください。
ちなみに、弊社では、このリポジトリだけで Sass のコンパイルが行えるような設定まで行いました。

{
  "name": "common-css",
  "version": "1.0.0",
  "description": "サービス間での共通cssをまとめたもの",
  "main": "index.js",
  "private": true,
  "repository": {
    "type": "git",
    "url": "git+<repository-url>"
  }
}

その後、master にマージしたら、git tag でタグ付けし、git push --tags で tag を push します。
記念すべき v1.0.0 の誕生です。

共通CSSを使用する方法

上記の例だと、common-css を使用するために必要な手順を説明していきます。

まず package.json に下記を追記します。

"devDependencies": {
  "common-css": "git+<repository-url>/common-css#v1.0.0"
}

#v1.0.0 まで記述することで、指定したバージョンを落としてくることができます。
この状態で、 yarn install します。これによって node_modules 下に配置されるはずです。

Sass のビルドの設定を行っている箇所に対して、パス周りの修正をする必要があります。
node_modules 下に入ってきた共通CSSまでのパスを通す必要があります。
使用している環境に応じて適宜設定を行ってください1

theme ファイルの作成

共通CSSとはいえ、使用するサービスで調整したいことはあります。
一番よくあるのは、そのサービスカラーに合わせた色の指定かと思います。
そんなときは、変更したい値を変数管理することで解消できます。

common-css

共通CSS側は下記のような形にします。

_import.scss

//_import.scss

@import "./theme";
@import "./box";

_theme.scss

//_theme.scss

$box_bg-color: #fff !default;

!default をつけていくことで、$box_bg-color に値が設定されていない時のみ、指定した値を割り当てるようにすることができます。

_box.scss

//_box.scss

.box {
  backdround-color: $box_bg-color:
}

使用する側

共通CSSを使用する側は下記のような形にします。

_theme.scss

//_theme.scss

$box_bg-color: #ffffe0;

index.scss(最終的に出力されるファイル)

※設定次第でパスの記述方法が変わるので適宜修正してください

//index.scss

@import "theme";
@import "common-css/_import"; 

$box_bg-color には値がセットされることになります。
そのため、!default が指定された #fff が有効になることはありません。
!default がないと、$box_bg-color の値は上書きされてしまうので注意してください。

このように管理することで、使用する際に、適宜テーマを変更することができるようになります。

共通CSSの更新

master にマージしたら、git tag でタグ付けし、git push --tags で tag を push します。
その際、しっかりとリリースノートを記入しておきます。2

各サイトの開発者はこれを確認しつつ、必要に応じて使用するバージョンを上げます。
package.json の # 以下を書き換えるだけです。

ただ、この運用は一例でしかないので、会社にあった運用をしていただければと思います。

注意点

共通CSSの更新ですが、原則として破壊的ではない変更のみがいいと思います。
バグの場合は仕方がないですが、CSSに対する変更は使用箇所によっては崩れてしまう可能性があります。
そのため、可能なかぎり破壊的変更はしないようにしましょう。

開発中の対応

本来であれば共通CSSを先に開発して、その後別プロジェクトでこれを使用する、というのが理想ですがそうはいかないことも多いかと思います。
そんなときに必要な手順になります。
そこで開発時だけは、手元の共通 CSS リポジトリを参照するように設定するという運用にしました。
これは npm link (yarn を使っている場合は yarn link) コマンドを使います。

弊社では Yarn を使っているので、ここからはそれを前提としたコマンドとなっています。

参照される側(common-css)での作業

common-css 下で下記のコマンドを実行し、他のリポジトリから yarn link できるようにします。

yarn link

参照する側(各プロジェクト)での作業

yarn link common-css

やめたい場合は、下記を実行

yarn unlink common-css
yarn install

まとめ

以上が、リポジトリを横断したコンポーネント(Sass)管理を行う方法になります。
この方法で対応すれば、複数サイトの運営を別リポジトリ(プロジェクト)で管理している場合でも、共通CSSとして管理することが可能になります。
これにより、リポジトリ毎ではなく、会社としてのコンポーネント管理が進み、Sassファイルをゴッソリとコピペする必要がなくなります。

今回はバージョン管理をしっかりと行う方法をメインに紹介しましたが、これが不要で常に最新でいいということであれば、本番ビルドなどでも yarn link を使う方法もあります。
しかし、意図しないときに更新が入ってしまう恐れがあるので注意が必要になります。
運用方法はいくつかあると思いますので、環境に合わせた運用をしていただければと思います。

最後に…この記事は ErgoDashで書きました。


  1. webpack を使用している場合は、sass-loader の includePaths に node_modules を指定する形になります。今のところ遅さというものは気になっていませんが、気になるようでしたら調整してください。

  2. 弊社では GitHub Enterprise を使っているため、Releases 機能を使ってリリースノートを管理しています