こんにちは。特定非営利活動法人みんなのコード(以下、みんなのコード)CTOの田中です。
今回は、私達が開発しているプログラミング教材「プログル」がどんな技術で支えられているかを紹介したいと思います。
プログルは、2020年の小学校におけるプログラミング教育必修化に合わせて、「学校の授業ですぐに使える」ように設計されたプログラミング教材です。先生の意見を取り入れて開発されたシンプルな画面構成と、教科学習に特化したドリル型のコースで、誰でも簡単にプログラミング教育を実践することができます。
プログルを2017年4月にリリースしてから約2年が経過し、利用者累計28万人を突破しました。対象学年の小学校5年生の年間人数100万人で割ると、約4人に1人が使っているという計算になります。
技術的には、React.jsを利用したSPA(Single Page Application)で、GoogleのFirebase Hostingで提供しているサーバーレスのプロダクトになります。
この「プログル」を支えるため、以下に紹介するような技術を利用してサービスを展開しています。
※ プログル周辺技術の概観図です
プログルのインフラを支える技術
元々、リリース当時はAWSメインで運用していましたが、2017年11月にGoogleのFirebase Hostingに環境を全面移行しました。
移行して1年以上経過しますが、特に大きな問題もなく稼働しています。
しいて言えば、Basic認証を実装しづらく、社内確認用のプレビュー環境の構築には不向きなところでしょうか。
Firebase Hostingを選定した理由
FirebaseはGoogleが運営しているmBaaSです。iOS / Androidアプリのバックエンド環境として利用しているケースが多いかもしれませんが、Webアプリでも使用することができます。
Firebase Hostingはその中でもGoogleのCDNを利用した静的ホスティングサービスです。
開発チームが当時私ひとり(かつ週2日のパートタイム稼働だった)という状況で
- インフラに裂けるリソースが無く、なるべくアプリケーションの開発に専念したい
- インフラまわりの経験が浅めなため、なるべくインフラのことを考えなくて済むようにしたい
という理由や
- SPAとの相性が良さそう
- 費用が安い
- 面白そう
という(個人的なモノも含む)様々な理由から、Firebase Hostingで運用することにしました。
移行時の懸念点
CDNでリソースを配信するようになるため、配信元のサーバが国内に限らず世界中に存在することになります。
そのため、学校内のフィルタリングソフトにひっかかり、アクセスできない…という残念なケースが発生する可能性がありました。
公立の小学校は学校内のコンピュータにフィルタリングを設定していることが多く、海外のサーバは基本的にアクセス不可…ということもしばしばです。
一応Googleのサポートに問い合わせたところ、やはり弊社側でフィルタリングを回避する方法は無いとの回答を受け(まあそうですよね)ました。そこで、弊社と交流がある小学校の先生グループに協力を依頼して、フィルタリングの影響を受けないか報告してもらう…という事前確認をして、ようやく環境を移行することができました。
AWSで運用していた時期は、ELBにEC2というオーソドックスな構成に、自作のデプロイスクリプトをのせていました。Firebase Hostingに移行することで、サーバの管理費を大幅に削減でき、デプロイの自動化もしやすくなり、サーバ管理も不要と良いことづくめで、かなり運用が楽になりました。
その他、Route53やS3といったAWSのサービスも平行して利用しています。
プログルのサーバーサイドを支える技術
ぶっちゃけサーバーサイド実装はありません🤭
Cloud Functions for Firebase すら使っていません。
なぜサーバーサイド実装していないのか
この理由はシンプルで、「実装要件がないから」です。
プログルはユーザー登録不要で使えるようにしています。特に永続化しなければならない情報も現状無い(アクセス解析はGoogle Analytics、お問合せフォームなどのユーザー入力情報はGoogleフォームにそれぞれ集約)ため、サーバーサイド実装をせず、フロントエンドだけで完結するSPA構成にする意思決定を行いました。
サーバーサイド実装があると追々便利になることもありますが、要件が無いまま実装してもそれだけ気にしなければならないことが増えてしまいます。
インフラの項でも記載しましたが、少ない開発リソースをなるべく必要なところに注力できるよう、なるべく不必要な実装はしないようにしてきました。
プログルのフロントエンドを支える技術
プログルを支えるGoogle Blockly
プログルのフロントエンド技術の中で核となるライブラリがあります。
それが、Googleが開発しているビジュアルプログラミング開発環境の Google Blockly です。
https://developers.google.com/blockly/
プログルの右側(画像赤枠)にあるプログラミングスペースのUI構築を担うライブラリです。
この「〇〇前に進む」などのブロック一つひとつにJavaScriptのコードが埋め込まれており
ユーザーがブロックをつなげていくと、その組み合わせ方に合わせて、JavaScriptコードのコンテキストが出来上がり、evalなどを介して処理系に渡して実行する…というフローで、ビジュアルプログラミングを実現しています。
プログルの開発を始めるにあたり、似たような機能を持つライブラリが無いか調査しましたが、プロダクション投入レベルで安定感のあるライブラリは、Blockly以外に見つかりませんでした。
日本語の情報はほぼなく、ベストプラクティスもなかなか見つからない中、試行錯誤しながら開発を進めています(おそらく日本で一番Google Blocklyに触れていると思います)。
上記の実行フローからお察しの通り、少々クセがあるライブラリで、npmの公式リポジトリがイマドキJSのモジュールインポートに対応していない(モジュール対応をサポートする非公式ライブラリはあります)などレガシーな部分があるため、プログルのフロントエンド技術は、このBlocklyとの相性に焦点が置かれています。
React.js
UIライブラリは、個人的な好みと海外の採用実績から、React.js を採用しています(MITのScratch 3.0や、Code.orgのHour of Codeが React.js と Blockly を組みわせて使っています。他にもBlocklyをReactから扱いやすくする小規模なOSSがあったりします)。
合わせて、ルーティングにReact Router、状態管理に MobX を使っています。MobXは実装がシンプルなところと、Blocklyの実行内容も含めた状態管理がしやすそうだったことから採用しました。
また、Reactアプリケーションの構築に create-react-app、カスタマイズに react-app-rewired を使用しています。
React.jsはViewを構築するライブラリのため、実装する要件に合わせて、様々なライブラリを組み合わせる必要が出てきます。それら組み合わせるライブラリのことをいちいち考えていくのが億劫だな…という思いから、なるべく時間をかけずにReact Wayに合わせられそうな create-react-app を使うことにしました。
create-react-app で賄えない実装要件については、react-app-rewiredで設定を上書きすることで、対応しています(ejectしても良いのですが、それだとせっかくcreate-react-app流に乗せたメリットが無くなってしまうので一旦やめました)。
その他、フロントエンドで使用している技術をまとめると、以下になります。
- モジュール管理・タスクランナー
- yarn
- モジュールバンドラー
- webpack
- トランスパイル
- babel(es2015〜、react)
- フレームワーク
- React.js
- MobX
- Blockly → node-blockly 経由で呼び出し(CommonJSモジュール対応をサポートしてくれる)
- アニメーション
- CreateJS(Blocklyの実行結果を描画するために使用します。もう少し使いやすいライブラリ無いか探し中…)
- その他
- Bootstrap 4
- ESLint
- Jest(ほぼ導入しただけで終わってしまった…)
- FlowTypes(ほぼ導入しただけで終わってしまった…)
プロダクトの規模が大きくなるにつれて、ソフトウェアテストなどの基盤部分を整えていく必要性をひしひしと感じています(このあたりの知見がある方、ヘルプミー😢)。
その他開発を支える技術
その他、プログルの開発で使われている技術要素やサービスもご紹介します。
- GitHub
- Kibela
- 主に開発者間の開発ドキュメント管理に使用しています
- 非営利団体向けの無償化クーポンを使わせていただいてます(ありがとうございます🙏)
- CircleCI
- ソースコードのビルドから本番デプロイまですべておまかせ
- Heroku
- 社内のプレビュー環境に使用しています
- Google Analytics
- Google Tag Manager
- Google Form
- お問い合わせフォームなどで利用しています。便利
- Google Apps Script
- お問い合わせフォームの通知や、SlackにGAの計測情報を送ったり、いろいろなところで使っています
その他、みんなのコードで使っているツールをこちらにまとめたので、よかったらご覧ください。
最後に
使っている技術スタックから選定時の思想まで、一通り書かせていただきました。これからも要件に合わせて積極的に新しい技術を取り入れ、エンジニアの「新しいものを作りたい」という想いと開発のモチベーションを大切にしていきたいと思っています。
とはいえ、ここまで技術選定から、環境構築、実装まで自分ひとりで行ってきたため、未熟な点だらけだと思っています。プログルをより良いプロダクトにするためには、まだまだやりたいことがあり、仲間が必要です。
この記事を読んで興味を持っていただいた方、ぜひお気軽にご応募ください🙂(カジュアルにランチ🍴からでもOKです!)