MF KESSAIの現在のフロントエンド環境について

MF KESSAI(以下MFK)のフロント担当、井原です。 今回は、2018年10月現在のMFKフロントエンド事情について書いていきます。

はじめに

その時々の状況で一番作りやすそうな形を模索しながら構築してきました。 そのためサービスによって環境に多少の差異があります。

ただ、共通して必ず何か新しい技術、フレームワーク、やり方等を取り入れてみるというのを取り組んでいます。 これを通して、少しずつ自分たちにとって一番作りやすい方法を模索しています。

MFKにはUIのあるシステムがいくつかあり、それぞれで異なる技術が使われています。 それらの構成について紹介します。

大雑把な分類

現在MFKには、画面のあるサービスが大雑把に分けると4つあります。

  1. コーポレートサイト系
  2. オペレーター用画面
  3. ユーザ用画面
  4. カスタマーサポート用画面

必要要件と作られた時期によって、これらは環境がだいぶ違うものになっています。

コーポレートサイト系

コーポレートサービスLPやこの開発ブログのようなサイトがこれに含まれます。 これらのサイトは、テキスト情報が中心のため、簡素に作られています。

  • Hugo
  • jQuery
  • Bootstrap (SCSS)

HTML生成にHugoが使われているのは、前の記事でも記載した通りです。 JSに関しては、これらのサイトはアプリケーションではないため、部分的に使いやすいライブラリが揃っているjQueryを採用しています。

オペレーター用画面

  • Go
  • Vue.js + TypeScript
  • Bootstrap

会社として最初に作られたシステムです。 デザインもなく、とにかくとりあえず動くものをと作ったので、GoのテンプレートでHTMLを生成しています。

ただ運用しているうちに、データ量が多すぎてレンダリングに時間がかかりすぎる状態になるページもあったため、 部分的にJSを使ってページネーションや遅延読込などの実装を行なっています。 その際、Vue.jsとTypeScriptの組み合わせを導入してみました。

Vue.jsを採用した理由としては、とにかくぱっと見が簡単なことです。 初見が重くないことによって、普段フロントのコードを触っていない人が、小さい修正ぐらいはやれると思ってもらえるのが大きいです。 今の弊社のようにフロントエンジニアが少ないような環境では有効だと思っています。

ただ、そういう意味ではTypeScriptはちょっと重かったかなと思うこともあります。 しかし、型があることで多くのエディタ、IDEでしっかり補完されるため実装を追わずとも期待されているものがわかるのはとても良いです。 もちろん、その状態を維持するために気をつけて実装して行く必要があるコストもありますが、後のことを考えるとそのコストを割く価値があると思っています。

ユーザ用画面

  • Go
  • Vue.js + TypeScript
  • Bulma + SCSS

開発開始時SPAで作っていくのもアリではという話をしていたものの、日和ってオペレーター用と同じようにGoのテンプレートで動的にHTMLを生成しています。 ただ、オペレーター用に比べてアプリらしくページ全体をJSで作っていたりもするハイブリッドな実装です。

というのも、当初は動きのあるページが少なかったため負担は少なかったのですが、ページを拡張していくうちにやりたいことが増えていきました。 その際にhtml/templateはリッチなUIを作るには向いていないため、自分たちで多くの機能を作らないといけない状態になり疲弊してしまいました。

そのため、GoからはベースHTMLとスクリプトを配信して、クライアント側で組み立てるという実装の形式が増えてきました。 ページによってはrouter的な実装しているところもあったりして非常にカオスなことになっています。 次はSPAでいこうなって話しながら、新しい項目を作るときは次でも使えそうなコンポーネントになるよう作っています。

このサービスは、SPAのチャレンジをしない代わりに、BootstrapをやめてBulmaを採用してみました。 ボタン等のコンポーネントに色やサイズを指定するクラスを足していくだけで見た目を変えられるのは非常にモダンで、cssの設計の仕方という点でも参考になりました。 しかし、細かいところで困ることが多く、長く使われているだけあってBootstrapは枯れたフレームワークであることを実感しました。

Vue.js, TypeScriptは継続しました。 Flowも試してみようかと考えました。 ですが、このタイミングで当時Vue.jsがTypeScriptサポートを公式で行うことを発表したので、TSのままで行くことにしました。

カスタマーサポート用画面

  • Nuxt.js + TypeScript
  • GraphQL (Apollo Client)

ユーザ用画面での反省を踏まえ、SPAでやってみようとNuxt.jsでやっています。

また、このサービスからはサーバとのやりとりをGraphQLにしました。 弊社のシステム間プロトコルはgRPCでブラウザから直接叩くのは難しいので、中継サーバが必要でした。 RESTやJSONRPCでもよかったのですが、技術検証の意図も含めてGraphQLでやりとりするようにしました。

この辺りの話はこちらの記事で詳しく書かれていますので読んでみてください。 GraphQLのフロント側実装の戦いはまた別の記事にまとめようと思っています。

さらに、これまでのVue.jsの使い方は、完全にCSSは別ファイルに分離して使っていました。 このサービスではscoped cssを使ったコンポーネント単位での切り分けを意識しながら書いてみています。

今まで使ってきたVue.jsそのまま、面倒なSPA,SSRの設定をほぼしないでいいNuxt.jsは非常に使いやすいのですが、少し辛いところは、TypeScript対応が弱いところです。 nuxt-communityからvue-class-componentやvue-property-decoratorのnuxt拡張が出てはいるので基本的なところは問題ありません。 しかし、そこにapollo-moduleやaxios-module等のmoduleまで入れてくるとdifinition fileがなかったりするので、都度拡張して使っています。 あとはvuexのstateやactionにコンポーネント側からアクセスする際に型付けができないのもしんどいなぁという思いです。 Vue.js + TypesScriptはそこまで辛くないですが、周辺技術についてはまだまだ利用時にフォローしながら作らないといけません。

さいごに

以上のように、少しずつ新しいこと(最後は思いっきりジャンプしていますが)を導入しながら、自分たちが作りやすい環境を模索してフロントの開発を進めています。

こんな感じの環境に興味がある方、ぜひこちらからご連絡ください。 一緒に試行錯誤しましょう。お待ちしています。