この記事は Cresco Advent Calendar 2017 20日目の記事です。
こんにちは。スマート・ソリューション・センターの benishouga です。
今回はクレスコで行っている1dayインターンシップの取り組みとそこで利用している JavaScript を使ったプログラミングゲーム Sourcer を紹介します。
(アニメーションGIF)
Sourcer は数年前から個人的にちょこちょこと開発を続けているアプリケーションです。 開発自体はオープンソースで進めており、 Github で公開しています。
リポジトリ: https://github.com/benishouga/sourcer
ドキュメント: http://benishouga.github.io/sourcer/standalone-jp.html
Herokuで立てている対戦サーバー: https://sourcer.herokuapp.com/
これを社内で共有したところ、ときどき社内イベントや1dayインターンシップで活用されるようになりました。
個人の開発のため なかなかにサービス化は難しいのですが、社内イベントなどクローズドなイベントと相性がよく、参加者からは軒並み好評で利用されています。
Sourcerを活用したクレスコの1dayインターンシップでは、会社紹介はほどほどにとどめ プログラミングの楽しさ とともに 開発の流れ をざっくりと体験できる内容となっており、これまでに4回ほど開催されました。
参加者にはプログラミング未経験の学生さんもいますので、各チームには先輩社員がメンターとしてつきフォローを行います。
- ゲームの説明と、未経験の学生さん向けに簡単なプログラミングの説明
- 時間が限られているため、詳細は学生さん同士やメンターによるフォローでカバー
- チーム(2人~3人)を作る
- 作り上げるプログラムはチームで1つ
- 1人がプログラミング/周りは助言やAPIドキュメントを読んだりでサポート という形をローテーションする
- 開発の醍醐味でもあるチームでの開発を体験してもらう
- いきなりプログラミングに入るのではなく、まず作戦を立てる
- APIドキュメントを眺めたり、メンターのサポートを受けて、実現方法を検討する
- 実際の開発現場のように、要件の整理/設計を行ってからプログラミングに入る
- プログラミングを行い、作戦に沿った動きとなるよう試行錯誤する
- 他のチームとエキシビジョンマッチを行い、課題を見つけて3に戻って繰り返す
- 実際に利用しフィードバックを集めるユーザーテストにあたる作業
- 開発は作ったら終わりではなく、課題を見つけ改善することを体験してもらいたい
- 最後はトーナメント戦
- 自分たちが作ったものが動く達成感を体験してもらう
- 対戦は3番勝負
- 同じプログラムでも状況が変われば結果が変わって良い勝負になることも・・・
実際のワークでは以下のように苦労しながらも開発を楽しむようすが見て取れました。
- 思い通りに動くようになったら新たな課題が見つかり一喜一憂するチーム
- メンターの先輩社員を懐柔し実装を進めるチーム
- 立てた作戦が壮大過ぎで残り5分の呼びかけに悲鳴をあげるチーム
- 括弧{}の数がそろわず動かなくなって残り5分の呼びかけに悲鳴をあげるチーム
- エラーの出ているプログラムを保存してしまい残り5分の呼びかけに悲鳴をあげるチーム
ワークの時間としては90分程度と短い時間ですが、学生さんのユニークな発想で様々な作戦が実現されており、いつもトーナメントでは盛り上がり必至な状況です。
続いて実装に使っている環境やライブラリの紹介をします。ツール/ライブラリの選択では息長めのものをなるべくシンプルに使いたいという思いがあったりします。
基本的には MERN スタックで、 SPA として実装しています。俯瞰すると以下の感じです。
(アプリケーションスタック画像)
ブラウザとサーバーで一部モジュールを共有できる作りとし、特にコアとなる対戦ロジックについて "コード作成中のブラウザ上の実行" と "実戦時のサーバー上の実行" で同一モジュールを使うようにしています。 今のところは機能追加を優先し Universal 対応は見送っています。
クライアントでは前述の通り React を使い、デザイン周りは Material Design Lite (React-MDL) で整えています。
React-MDL は最近あまりコードに動きがなく React がv16
以上だとpeerDependencies
起因で警告が出るのが辛い状況。
通信には少し旬が過ぎた感の SuperAgent を使用しています。Fetch API を使いたいが Abort できずで見送っています。 Abort 周りの処理は AbortController に期待して少し意識した実装をしています。
ルーティングは React-Router を使用。状態の保持は Redux 等は特に使わず、単純なシングルトンで行っています。
ストレージは "Heroku などのサービスでカジュアルに使えるように" を目的に MongoDB だけに依存させ、モデルの定義には定番の Mongoose を使用しています。 TypeORM のような Decorators を活用したライブラリに期待しつつ枯れるの待ちな状態です。
対戦ロジックの実装では、信頼できないプログラムを実行するため、サーバーでは vm2 というSandboxライブラリを使用しています。なお、ブラウザ上での実行は自身のプログラムしか動かさないため、セキュリティ考慮甘めでも良いだろうで、簡素な実装を行いました。
またプログラムに無限ループを突っ込まれるとサーバー全体が止まるという状況を避けるために、ユーザープログラムの実行では Node.js の Cluster を使ってプロセスを分けるようにしています。
開発環境については俯瞰すると以下のような感じで組んでいます。 ツールを変えてはバランスを整えるというサイクルに疲れて、少し枯れ目のもの中心に使っているのが特徴になってしまっています。
(開発環境/ツール画像)
モジュール管理/タスクランナーは基本的に npm だけで、並列/直列の実行制御だけ npm-run-all というツールを挟んでいます。 yarn についてはすごくすごく良いというのは理解なのですが、将来的に npm だけで完結してほしいという願いがあり使っていません。
似たような話で npm-run-script だけ素直に使いたいというのがあり WebPack も今のところは使わずで Browserify で通しています。
コード自体は一貫して TypeScript で記述しています。コンパイルによるチェック/インテリセンス/リファクタリング/参照検索などなどが便利すぎて、本当に本当に今では TypeScript なしだと生きられない体になりつつあります。
あとは css 向けに PostCSS 、テスト向けに Mocha を使っているぐらいです。
以上、1dayインターンシップでのプログラミングゲーム Sourcer の活用紹介 でした。
この記事を通してクレスコで行っている1dayインターンシップの特徴や楽しさが少しでも伝わってくれるとうれしいです。
また冒頭で紹介した通り、 Sourcer はオープンソースで開発しており、手軽にサーバー立てることも可能なので、ぜひお仲間とのイベントなどで使ってみてください。