東京都の新型コロナ対策サイトはなぜNuxtJSだったのか? ─ シビックテックのベストプラクティス
東京都が3月初旬に公開した新型コロナウィルス感染症対策サイトは、モダンなWeb技術を使いオープンソースの手法で開発されました。シビックテックの活動から生まれたベストプラクティスについて、開発者のお2人に聞きました。
東京都が2020年3月3日深夜に公開した新型コロナウイルス感染症対策サイトは、都内の感染動向が見やすく整理されているだけでなく、NuxtJSベースのSSR(Server Side Rendering)で静的ホスティングにNetlifyを採用したサーバレスなSPA(Single Page Application)というモダンな技術選定がWebエンジニアの間で注目を集めました。
ソースコードはGitHub、UIデザインをFigmaで管理しているため、社会的な問題の解決に協力したいエンジニアが改善提案などをコントリビュートでき、開発環境ではCI/CDも整備されており、適切なオープンソースライセンス(MIT License)が付与されているので各地方自治体向けの派生版を自由に作成できる──。
こういったオープンソースのマナーに則ったこの対策サイトは、元ヤフーCEOの宮坂学(@miyasaka)東京都副知事が組織した特別広報チームの委託を受け、関治之(@hal_sk)さんが代表を務めるCode for Japanが開発しました。
東京都新型コロナウイルス感染症対策サイトを開発|コード・フォー・ジャパン
Code for Japanは、行政ではなかなか手が届かない地域の課題をテクノロジーの力で手助けするシビックテックという活動をしている一般社団法人で、2011年の東日本大震災後直後に開発者コミュニティから立ち上がった支援の動きの中から生まれました。
急を要する対策サイトにおいてなぜこのようにモダンな技術要素が選定でき、実際にはどのように開発を進めたのか? サイトのローンチまで少数で開発にあたったコアチームのメンバーである小副川健さんと池田達哉さんに、今回のプロジェクトを支えた技術の背景から、シビックテックに携わるエンジニアのあり方までお話を伺いました。
- なぜNuxtJSだったのか? あるいはjQueryでなかったか?
- 偶然に決まったNetlifyは開発にとても役立った
- 後でコンポーネントを変更改善できるよう小さく作る
- ベストエフォートでの開発体制
- リリース直後から届いたエンジニアの反響
- シビックテック活動のベストプラクティス
なぜNuxtJSだったのか? あるいはjQueryでなかったか?
── まず最初に、今回の技術的なバックグラウンドから聞かせてください。一見すると行政が関係した仕事とは思えない現代的な技術選定のWebサービスですが、この構成はどうやって決まったのでしょうか?
小副川 私が最初に話を振られた時点では、最終的にデータを静的なサイトに表示する仕組みが必要というだけで、特に技術的な決定事項はありませんでした。
ただ、Vue.jsのフレームワークであるNuxtJSを使うこと自体は、これまでCode for Japanで開発してきた経験からすんなりと決まった感じです。
── 詳しく教えてください。
小副川 2018年7月に西日本で発生した集中豪雨に伴う水害を機に開発された「紙マップ」というアプリケーションがあって、現在はNuxtJSで開発されています。
このサイトでは、避難場所などの地図を紙に印刷するのに最適な状態でWebブラウザ上に表示できるのですが、当時はjQueryで書かれていました。地図を扱うのにLeafletというJavaScriptライブラリを使っていて、もちろんTypeScriptではありませんでした。
── 2018年にjQueryだと、すでに時代遅れ感がありますよね。
小副川 はい。しかし、そのときはむしろ「jQueryでうまくいったね」という認識だったんです。そのプロジェクトで集まったのは、私を含めて「jQueryなら書ける」という30代のエンジニアが多かったので、メンバーに合わせた技術が採用できました。
── このサイトをどこかのタイミングでNuxtJSに置き換えたわけですね。
小副川 去年(2019年)の台風19号です。千葉県を中心とする被害の情報公開で、西日本豪雨のプロジェクトを再利用しようと改めて複数人で開発を始めたんですが、jQueryだとどうしてもコンフリクトが多発してしまう。
これはコンポーネントベースの仕組みに移行しないとまずいということで、Vue.jsで書き直しました。
── ということは、東京都のサイトもわざわざモダンな仕組みを狙ったのではなく、これまでの開発経験からの選択だったんですね。
小副川 はい。全員が触りやすく、コンポーネントベースで、複数人で開発してもコンフリクトが起きにくいものを選んだら、自然とNuxtJSになりました。選択肢としてはReactもあったのですが、紙マップの経験があったのでVue.jsを選んだわけです。
── 結果的には、その選択が功を奏して、「この技術だったら参加したい」という形でコントリビューターが一気に増えた面もありそうですね。
池田 確かに、これがjQueryと最小限のHTMLで作ったサイトだったら、これほどエンジニアから注目されることはなかったかもしれないですね。
小副川 もちろんエンジニアの反応を見越して技術を選定したわけではありませんが、後になってから「Vueにしておいてよかった」という話を関さんとした覚えはあります。
池田 フロントエンドにおいて、日本ではVue.jsやNuxtJSの技術コミュニティが発展していることもある気がします。
偶然に決まったNetlifyは開発にとても役立った
── ソースコードをGitHubで公開することは最初から決まっていたと思うんですが、ホスティングでNetlifyを採用したのはなぜでしょう?
小副川 静的コンテンツなので、最初はGitHub Pagesでよいのではという話になっていました。それがNetlifyになったのは、聞いた話ですが、SSLサーバ証明書の関係で要件を満たせるサービスとして選択肢に上がってきたようです。
── ちなみに、Netlifyは新型コロナウイルスに関する情報提供でのサービス利用については無料期間を延長することを3月22日に発表していますが、東京都のサイトのリリースはその前でしたね。
小副川 はい。最初は無料プランで登録していて、途中からビルド回数か何かの制限に達して有料プランに移行したようです。
池田 Netlifyにしたおかげで、レビューがものすごく楽になったんですよ。
GitHub Pagesに書き出していたときは、各自に撮ってもらったスクリーンショットをもとに判断したり、細部を確認するにはビルド結果を毎回自分たちで生成する必要があったんですが、Netlifyだとビルド結果をもとにステージング環境を勝手に作ってくれるんです。
小副川 公開後にコントリビューターが増えたときにも、Netlifyにしていたおかげでプルリクエストのレビューがしやすくて助かった面もあります。CIを適切に設定すれば「このプルリクエストをビルドしてデプロイした結果」のURLを教えてくれるんです。
これがなかったら、プルリクエストをローカルに取り込んでビルドしてから確認することになっていたと思うので……。
── ちょうど話に出たCIなどの自動化も話題になっていましたが、工夫されたことはありますか。
池田 CIではGitHub Actionsも使っていて、マージ前に必ず一回はESLintが走るようにしたりとか……。
小副川 ESLintはありがたかったです。
池田 エディタによって自動整形されて、本来の差分が分かりづらくなるという問題があったんです。また、レビューの際に打ち間違えやインデントなど細かいことで時間が取られるともったいないので、開発の初期段階から、コミット前にlintをかけたりインデントの自動修正をしたりする設定を導入していました。
小副川 GitHub Actionsはデータの取り込みなどでも使っていますね。自動化では池田さんが手を動かしてくれました。
池田 最初は人手が足りない状況でマンパワーが求められたので、ひたすらコンポーネントを作って、ページを組み立てていきました。開発環境については特に指定していなかったのですが、コントリビューターの数が増えていくとさまざまなケースを考慮する必要がありました。
Dockerで開発している場合など、開発環境によってはコミット前のフックがうまく動かずにlintをスキップしてしまう事例もあったので、GitHub Actions経由でもreviewdogでESLintを回して二重チェックし、lintが通らないとマージできないような設定にすることで、ある程度のコード品質を保てるようにしていました。
後でコンポーネントを変更改善できるよう小さく作る
── 小副川さんは、主にどういった開発を担当されたのでしょうか?
小副川 nuxt init
コマンドを実行した初期状態からテーマを差し替えたり不要なコンポーネントを整理したりして、それを最初に東京都のリポジトリにプッシュしました。
それから対策サイトでは、カード形式の四角い枠がいくつか並んで表示されるのが基本構成で、その枠の中に棒グラフやテーブルが表示されるようになっています。これは、例えばDataView
などのVueのコンポーネントとして作り、そのSlotに中身を差し込むことで実現しています。
そういったコンポーネントをそれぞれ作り込みながら、いろいろなデータで使える共通の部品にする作業をしていました。私が雑に作った棒グラフやテーブルに、Cookpadの藤井謙士朗(@kenshir0f)さんがデザインを当てていたり。
── UIデザインでは藤井さんと宇野雄(@saladdays)さんが参加されていたんですね。
東京都の新型コロナサイト誕生秘話、行政らしくない爆速開発はDXのシンボル | 日経クロステック(xTECH)
小副川 その後もいろいろな人が改良を加えてくれているので、私が書いたコードが今も残っているかは分かりませんが……。
── どんなライブラリを使うかなどは、実際に手を動かすエンジニアの裁量で進めていたのでしょうか?
小副川 大前提としては「使える人が多い」ことで、ある程度の軽さがあるものをみんなで考えました。
例えば、グラフを描画するJavaScriptライブラリではd3.jsが大好きなのですが、これは学習コストが比較的高い。そのため、どちらかといえば使える人が多く、変なグラフが作られにくい構造のchart.jsを選択しました。
もちろん導入した後で「こっちの方がいい」と指摘されて直すこともありました。時間表示のライブラリで、最初はmoment.jsを使っていたのですが、チームで「day.jsの方が軽い」という会話があって途中から変更しています。
── 四角い枠のカードは、サイトが公開された時点ではコールセンターの相談件数など4つくらいでしたよね。
小副川 はい。あとは、感染者数の推移、検査人数、感染者の年齢や性別の一覧表あたりだったと思います。
── それが今では13枚になっています(2020年5月15日現在1)。公開後に情報が増えることを見越して共通の部品を作っていったわけですね。
小副川 最初はとにかく急いでいたので、きちんと作り切れていないと自覚していた部分もありますが、見た目をそろえようといったことは意識していました。
── サイトに掲載できる情報は東京都が用意できるかどうかに依存するわけですから、勝手に考えておくことは難しいですよね?
小副川 具体的には分かりませんが、後で追加される準備中のデータがあるといった話は間接的に聞いていました。
いずれにせよ、まったくサイトがない時点では誰にも正解が分からないので、いったんミニマムなものを作ろうという方針にしてよかったと思います。
── 宮坂学副知事が組織した東京都の特別広報チームでも、そういった方針だったとインタビューで答えられていますね。開発期間もかなり短かったようですが……。
東京都の新型コロナ対策サイト“爆速開発”の舞台裏 オープンソース化に踏み切った特別広報チームの正体 (1/4) - ITmedia NEWS
小副川 感染状況を独自にまとめているWebサイトは報道機関のものを含めてすでにいくつかありましたし、個人的にも「早くリリースしないと都民のためにならない」という思いでやっていましたから、開発スケジュールがタイトであることに違和感はありませんでした。
── 開発初期に意識されていたことは他にありますか?
小副川 ちょっと違いますが、感染者数などの数字に3桁ごとのカンマをいれるフォーマッターを修正しているときに「このフィルターが使われないといいですね」と話していたことが印象に残っています。つまり、数字が1,000
に届かないことを願っていたのですが……。
── リリースした日はまだ新規感染者数が4人でしたね……。
小副川 棒グラフの横幅も固定長のままだったんです。エンジニアリング的には長く使えるよう可変長にするんですが、長期化する前提でコードを書くことにちょっとした抵抗がありました。半ば「祈り」と言ってよいかもしれません。
ベストエフォートでの開発体制
── 最初は何人のエンジニアで開発されていたのでしょうか?
小副川 4、5人でした。そのうちCode for Japanの活動などでもともと知り合いだったのは、2人です。
── 開発中のコミュニケーションはどうされていたのでしょうか?
小副川 Zoomをつなぎっぱなしにしながら、各自で作業していました。オンライン会議になっているけれど、基本的に会話はせず、分からないところがあったら聞くという感じで。
エンジニアが集まってひたすらコードを書く「もくもく会」というイベントがありますよね。それをオンラインで毎日やっていた雰囲気です。
── ハッカソンのようですね。ほとんど不眠不休で作業されていたのでしょうか?
小副川 人によるとは思いますが、私はわりと人間的な生活をしていたと思います。日中は本業をやりつつ、夜に自宅に帰ってきてから深夜までコードを書くという形でした。
10時くらいに「家族と過ごすから落ちます」といって開発から離れる人もいたので、そういう意味で特にブラックな印象はなかったです。
池田 私は、1つのことに夢中になってしまうと止められない性格で、集中すると眠れなくなるので、リリースまでは寝食を忘れて取り組んでいた感じです。
── 他のメンバーは入れ替わり立ち代わり自分のペースでやって来るけれど、池田さんはずっとZoomにいるというわけですね。
池田 そんな感じでしたね。リリース後の数日まではかかりきりでした。一点集中の性格なので、下手に複数を並行してやるとどちらも「なあなあ」になってしまうんです……。
── 開発体制やチームマネジメントで気をつけたことはありますか。
池田 イシューやプルリクエストのテンプレートは私が用意しました。まず素案を作り、関さんにレビューしてもらって運用しはじめました。
参加者が増えた後でも、内容がないイシューが飛んでくると混乱しますし、ある程度はフォーマットが決まっている方がイシューを立ててもらうのも楽だろうということで、早いうちに作っておいて本当によかったと思います。
さらに後になってから改善用とバグ用でそれぞれテンプレートができたりした土台にもなっていて、少ない労力でレバレッジが効いたなと思います。
小副川 初期メンバーで開発している最中は「ベストエフォート」を原則にしていました。つまり、「あいつ何もやっていないじゃないか」みたいなことを絶対に言わないということです。経験上、そうじゃないとシビックテックのような活動は継続できないんですよね。
── GitHubのcontributorsを見ると、池田さんの活動はリリース前後の一週間に集中していてピークがはっきりしている一方、小副川さんはリリースされた後も開発をじんわりと続けられていたり、本当にいろいろなタイプの貢献方法があるんですね。
池田 自分は立ち上げ初期のマンパワーですね。個人的にも得意なフェーズの作業なので、自分なりのやり方で貢献できてよかったと思います。
── サイトを開発しているときには、この存在を自分たちだけが知っているという高揚感みたいなものもあったのでしょうか。
小副川 これも人によると思いますが、私自身は特に盛り上がっていたことはなく、行政を助けて市民が知りたいことを知れる正しいものを作るべく、単純に集中していました。すでに同じような活動を十数回はやっているので、シビックテックにおけるいつも通りの活動のひとつという感覚ですね。
リリース直後から届いたエンジニアの反響
── リリース後の反響についてお聞きします。GitHubやFigmaのURLが早々にTwitterに流れて、エンジニアの間で開発に参加する気運が高まりましたね。
小副川 実は、公開直後(3月4日)はまだ改善提案を積極的に集める段階ではなかったんです。小池都知事の記者会見に合わせてコントリビューターも募集すると聞いていました。もちろん、公開されているサイトのソースからリポジトリは調べられますが†。
† 現在はaboutページにリポジトリのURLが掲載されているが、これはオープンデータのリンクとともに3月5日に追加されたもの。
池田 技術者としては純粋にうれしくて、率直にテンションが上がりつつも、リポジトリの方が先に注目を集めるとは思っていなかったので驚きが隠せませんでした。プルリクエストやイシューがどんどん増えていくなかで「どうやって回していこう」という焦りもかなりありましたね。
小副川 オープンソースプロジェクトとしてライセンスなどの準備は進めていたものの、レビューの方法などを決めていたわけではなかったので、早々にプルリクエストが届きはじめると全く捌(さば)ききれず、落ち着くまで待ってもらうことになってしまいました。多くの方の「貢献したい気持ち」に対して自分たちがボトルネックになってしまったわけで、申し訳ない気持ちがありました。
池田 レビューの量が多かったことも大変でしたが、東京都の公式だから慎重にならざるを得ないこともあり、デザインや仕様にかかわる修正提案にはコードを見るだけでは判断できず、もどかしいこともありました。
── リリース後の体制はどのように整えたのでしょうか?
池田 関さんの一声から始まって、週末に急遽、誰でも参加できるオンラインハッカソンを開催しました。Code for JapanのSlackにプロジェクトチャンネルがあり、興味ある方が続々と集まっていたので周知しました。
そこでは、さまざまな領域の知見を持っている方も参加してこられたので、TypeScriptへの書き換えを進める班、アクセシビリティを整備する班、翻訳を進める国際化班といったように、領域ごとのプロジェクトが自然と生まれていきました。どれも大事なテーマです。
コミュニケーション量も多かったので、イベントが終わった後も進めやすかったのかなと思います。そこでオーナーシップを持って進めていた方は、自然とコアチームに加わり、意思決定などもスムーズに行われるようになったので、開発スピードも上がっていきました。
── 一般のオープンソースプロジェクトでも、後から参加して熱心にパッチを送った人がコミッターとなり、立ち上げメンバーが別の領域に活動を移していくことがありますが、それに近いことが起きているわけですね。
池田 そういう意味では、小さくリリースしたことで、それぞれの専門家が建設的な議論を進めてくれるという貴重な経験ができたと思います。
── 今回は、Code of Conduct(CoC、行動規範)があることや、その「我々はなぜここにいるか」に共感した方も多かったように思います。
小副川 CoCやコントリビューションガイドについては、シビックテックの活動を続けてきた経験上、必要であることは認識していたので、今回も最初から用意していました。
池田 最初は関さんが書いたものがGitHubのWikiにあったのですが、リリース後に私がコードと同じリポジトリ上に移動しました。
今回のように全く知らない人たちからコントリビューションがある状況では、参加にあたって共通認識を確立する上である程度は効果があったのかもしれませんね。GitHubが公開しているOpen Source Guidesというオープンソースのコミュニティ運営についての情報が分かりやすくまとまっているサイトがあり、とても参考になりました。
小副川 一方で、自分たちもCoCの意義を完全には理解できていなかったと反省することがアクセシビリティに関する議論でありました。
池田 今回のプロジェクトがこれだけ大きく注目されたことで、シビックテックがCoCを大事にしていたことの真意が初めて分かったように思います。
── 東京都版の開発に参加する方がいる一方で、派生した地方版もたくさんフォークされていますね。
小副川 私たちが開発したソースコードをフォークして各地方自治体で自由に使ってもらうというのは、シビックテックの活動として最初から狙っていることなので、それが実現したのはよかったです。
ただ、事前にもっと考慮できていれば作り込んでおけたところもいくつかあります。文字として現れる「東京都」のような情報を環境変数にしておくとか……。
── 逆に、うまくいったと思う部分はありますか?
小副川 その地域で必要な情報や、まとめられるオープンデータは自治体ごとに変わってきますから、カードを切り替えるだけで対応できるようにコンポーネントベースの技術を使っていたことは、その点でもよかったと思います。
東京都 新型コロナウイルス感染症対策サイトのリポジトリがGitHubのTrendingトップに!!!!!こんな大きなムーブメントになるとは・・・スクショとりまくったhttps://t.co/U8wFlwxE6O pic.twitter.com/51GjWg2kwU
— 🏠 (@yokinist) March 6, 2020
シビックテック活動のベストプラクティス
── お2人はどのような経緯でCode for Japanやシビックテックの活動をされるようになったのでしょうか?
小副川 きっかけになったのは、2011年の東日本大震災におけるsinsai.infoでした。この活動には参加していなかったのですが、報道で知って感動し、自分も何か協力できないかと思いました。
実際に初めて参加した活動は、「税金はどこへ行った?(Where does my money go?)」の日本語版プロジェクトで、2012年から2013年ごろです。
池田 私は、大学の政治学科で学んでいて、ITで地域や行政の課題を解決するという領域に興味がありました。それでCode for Japanと関さんのことを知り、たまたま2016年に「関治之の右腕募集」というインターン企画2を見つけて応募したのがきっかけです。
そのときにお手伝いしたのは、シビックテックのコミュニティを盛り上げるオフラインイベントの開催や運営などですが、政治の問題であっても投票だけではなく技術を使って自分たちの力で解決できる領域があることを知り、憧れもあって、独学で開発の勉強を始めました。
学生という立場もあり、エンジニアのアルバイトやスタートアップのインターンにもありがたいことにパッションだけで受け入れてもらえたので、そこで実務経験を重ねたり、勉強も兼ねて事あるごとにCode for Japanの開発プロジェクトにも参加してきました。
今回も、そうしたつながりから関さんに声をかけてもらったので「ぜひやらせてください」と参加しました。
── Code for Japanに参加しているみなさんは、普段はどのような形で活動をされているのですか?
小副川 Code for Japan自体は一般社団法人なので、その活動を支える理事などはいますが、私自身はそういった立場で参加しているわけではありません。今回のプロジェクトがあるたびに随時参加したり招集されたりする形です。
ボランティアベースのコミュニケーションはSlackが中心で、何らかの災害や日常的な課題に対して、誰かが「こういう仕組みを作ろう」という意志を表明し、共鳴したエンジニアやデザイナ、課題の当事者などが参加します。誰でも声を上げられますね。
── シビックテック活動の良さはどこにあるのでしょうか?
池田 普段は出会えないような多様なバックグラウンドを持った方とつながることができ、持っている知見やスキルを掛け合わせながら問題を解決していけることだと思います。シビックテックの活動では立場や上下関係など関係なく、みんな「一市民」として自分ならではの貢献の仕方で関わることができます。
また、オープンソースとしての面白さもあります。1つはさまざまな地域に横展開され、作ったものが全国に広がり、各地の求められる形に進化していくこと。逆に言えば、リポジトリをクローンしてきて自分の住んでいる地域版を作ることもできるということです。東京都のオープンソースを活用した新型コロナウイルス感染症対策サイトは、なんと全国47都道府県にムーブメントが広がっています。
もう1点は、ベストプラクティスが溜まってくるところです。今回のように大きいプロジェクトであれば、個人では気付けないことも多く、プルリクエストを見ているだけで勉強になります。そもそも私はVueを触ったのも今回が実は初めてで、CI周りやTypeScriptなども含めて、このプロジェクトを通して学んだことはかなり多いです。先ほど話に出たアクセシビリティの議論なども含めて、生きている教科書のようだと思いました。
小副川 私はシビックテックの活動に何度も参加してきましたが、今回は本当に多くのコントリビューターから反応が得られたことで、「今までこういう景色が見たくてやってきたのかもしれない」という実感が湧きました。すごく感動的な出来事でした。
シビックテックでは、行政からオープンデータが得られなくて市民が必要な情報を集められなかったり、情報を継続して追えなかったりといった課題もありますが、今回のように大勢のエンジニアが活動に参加し、それに後押しされて自治体もさらにオープンになるとしたら、それはとてもうれしいです。
── これまでのベストプラクティスを次のプロジェクトに生かそうというシビックテックの活動がベースにあったからこそ、今回は技術的にもプロジェクトマネジメントの面でも多くのエンジニアが参加できる環境になったと言えるかもしれませんね。今日は本当にありがとうございました。
取材・執筆:鹿野 桂一郎(技術書出版ラムダノート)
協力:陣内 一樹(Code for Japan)