こんにちは、freee株式会社 の @ymrl です。フロントエンドエンジニアなるものをしています。
この記事は freee Engineers Advent Calendar の2日目です。
#革命について
freee では最近フロントエンド開発を取り巻くいろいろなものを大きく変化させていて、これを 革命《レボリューション》 と呼んでいます。これはフロントエンド界の地殻変動の速さに付いて行きづらくなっているRailsアプリケーションのフロントエンドをエイヤッと近代化して、具体的にはRailsが用意している Sprockets によるフロントエンドの precompile のレールからはずれようとする動きです。
主力サービスである 会計freee は、最初のgitリポジトリへのコミットが2012年7月で、開発初期から jQuery UI や各種 jQuery プラグインや Backbone.js を使っていたようです。その後 Backbone.js に手を入れて独自MVCフレームワークっぽくしてみたり、jQuery プラグインを使い続けるのをやめたり、 Vue.js みたいな MVVM フレームワークを使ってみたり、ライブラリの導入に Rails 用の Rubygems を使っていたのを Bower にしてみたり、その1年くらいあとには Bower はオワコンとか言われていたり、新しいサービスがいろいろ立ち上がってRailsアプリケーションの数が増えたりと、たった3年ほどの期間に数々の地殻変動が発生してきました。
2015年のいま、フロントエンド開発の潮流は npm を中心としたエコシステムに集約されようとしています。この潮流に対して Rails の引いたレールの上からアプローチするのはとてもむずかしく、特に現在稼働しているコードを稼働させつつ、機能追加や改善などのイテレーションをしていくのと同時並行で移行するコストはとても巨大に見えました。
もちろん、流行に流されずに今までのやり方を続けていくこともできます。しかし新しい技術が本当に自分たちのやりたいことに即しているのかを見極めるためにも、いつでもそういったものを導入できる体制を作っておく必要がありました。また、本当にこれから Rails を使い続けていくべきなのか未知数であるという面でも、 Sprockets を捨てることでコードの可搬性は高くなります。
そういう中で、過去から作り上げてきた資産であり、見方によっては負債にもなり得る大量のコードが開発の足かせとなり始めているんじゃないの?という意識が生まれてきました。これらを抱えたままにしておけば時代の変化に会社ごと取り残されてしまうし、やがて保守していくことすらも難しくなってしまいます。
そこで革命が始まります。Sprockets は Gulp や Webpack や Browserify へ。CoffeeScript は Babel と ECMAScript 6 へ、 jQuery による DOM 職人芸あるいは1年くらい前の僕らの夢だった MVVM は React + Flux へ。レールを外れてナウいツールやライブラリを導入したりするためには当然コストがかかりますが、それら導入することによる開発速度や品質の向上、古いコードに依存し続けることへの不安の払拭などを考えれば多少のコストは払ってでもやるべきと考えています。
革命と呼びだしたことは画期的な発明で、革命という位置づけをすることで、保守的になりすぎず先進的なテクノロジーを導入することができるようになります。デプロイでトラブったり、多少の学習コストが必要になることも 革命には痛みがつきもの なので仕方がありません。もちろん、無理をして品質を下げてしまったり、先進的になりすぎてすぐにオワコンになりそうなモノを選んでしまったりしないように細心の注意を払う必要はあります。
詳細は革命家の @joe-re や @yo_waka あたりが書いてくれると思います。たぶん。
きょうはそんな革命まっただ中の freee での CSS の話をします。
freeeのスタイルシートのこれまで
Rails には標準で Sass (SCSS) が採用され、 freee でも開発初期から SCSS が採用されてきました。デザイナーが不在だった初期の freee では Bootstrap が採用され、のちにそれをベースとしながら新しい機能に必要なものを SCSS で書き足したり、 freee らしいスタイルになるように上書きされたりしていきました。
その量は古めのIEでは表示できなくなる程度には膨大で、 CSS に詳しいデザイナーもエンジニアも社内にいないという状況でそれらの多くはほとんど無計画に書かれていましたが、 SCSS でセレクタのネストが表現でき、グローバル変数はよくないというエンジニア間の暗黙の合意があったおかげで、ある機能でしか使わないスタイルはスコープを絞って記述するというようなことができていました。
// いろんな機能で使うスタイルはグローバルに記述する
.foo-btn {
background-color: #cccccc;
//..
}
// ある機能でしか使わないスタイルはスコープを絞っておく
// (その機能で使う要素は必ず #bar-feture 要素の中にあるようにする)
#bar-feature {
.baz-btn {
//...
}
}
やがて会計 freee 以外にも新サービスの開発が始まって、Railsアプリケーションが複数になってくると、上の例でグローバルに記述していたような freee として共通で使うスタイルはそれらとは別の git リポジトリで管理する必要が出てきました。そこでそのリポジトリを Rails 向けの gem として呼び出せるように実装し、app/assets/stylesheets
以下に SCSS ファイルを配置していくという方法をとるようになりました。
これによって複数のアプリケーション間で共通する部分については常に同じスタイルを充てることができ、ユーザーは違和感を感じることなく freee の複数のサービスを横断して使えるようになりました。
一方でスタイルシートとも密接に関わる JavaScript の実装は、このように共通化することがどんどん難しくなっていきました。ここ最近の JavaScript 界隈の地殻変動はとても激しく、数カ月前に持て囃されたライブラリやフレームワークがいつの間にかオワコン化していることなど日常茶飯事です。新しく作るサービスには最新のライブラリやフレームワークを適用していきたい一方で以前からあるサービスに一気に書き換えるわけにはいかない、結果として各サービスでJavaScriptの構成は全く違うものとなっています。
#革命とCSS
もともと JavaScript の事情が中心ではじまった革命でしたが、その中でこの共通スタイルシートの扱いにも変化が起きました。具体的には Sass (SCSS) のビルドが ruby ではなく node.js (Gulp) で行われるようになり、その関係で Rubygems 以外の方法でスタイルシートを提供する必要が出てきました。
そこで gem として作ったリポジトリのルートに package.json
を配置してnpmモジュールとしても使えるようにして、その main
となるスクリプトではスタイルシートの入ったパスをexportできるようにして、Gulp の gulp-sass で includePaths
に含めてやり、そしてアプリケーションの SCSS ファイル内で @import
するということをしています。現段階ではまだ革命が完遂していないので ruby で Sass をビルドしているアプリケーションもあり、gem としても npmモジュールとしても使えるという不思議な状態になっています。
これからの話
freee では統一感のある UI を提供するために UX チームが中心となって「UI/UX ガイドライン」というドキュメントを作成して、よく使う UI パーツについてはこの中で定義しています。このドキュメントに載っている UI パーツを組み合わせていけば画面が実装できるようになっています。
UI/UX ガイドラインには UI パーツの色やサイズや適切な使われ方などとともに、ユーザーがそれらのパーツを操作することでどのようなインタラクションが得られるかについても触れられています。ところが前述のとおり、現状では各プロジェクトでJavaScript の構成が大きく違い、JavaScript とスタイルシートの管理が分かれてしまっているために、 UI/UX ガイドラインには「こういう class を付けて HTML を書けばいいよ」というようなことは書けるのですが、その振る舞いについては各プロジェクトごとにゼロから実装する必要が出てきてしまっています。
今後、革命によって社内の各プロジェクトの構成が React 寄りになってくると、 社内で React Component を共通で使い回すことも多くなきて、現在の体制を続けていくのは限界が来ると予想されます。見た目の統一感を出すベースは今のままスタイルシートだけで独立させたままにするとしても、やっぱりある程度の規模のある UI パーツについては JavaScript とスタイルシートの両方を一緒に管理するリポジトリがあったほうが良いでしょう。その Component のサンプルコードが UI/UX ガイドラインに載っていれば、見た目だけでなく振る舞いの面でも統一感を出すことができます。
そういうわけで、スタイルシートの管理についても革命に乗り遅れることなく、より開発しやすい世界にしていきたいなと思っています。
#宣伝
freee は革命家《フロントエンドレボリューショニスト》を募集しています。よろしくおねがいします。
明日はfreeeが誇る 狂戦士《モバイルバーサーカー》の @yonekawa です。