この記事は 『CRESCO Advent Calendar 2017』 20日目の記事です。

 

こんにちは。スマート・ソリューション・センターの benishouga です。

今回はクレスコで行っている 1dayインターンシップの取り組みとそこで利用している JavaScriptを使ったプログラミングゲーム Sourcer の作りについて紹介します。

Sourcer は数年前から個人的にちょこちょこと開発を続けているアプリケーションです。 開発自体はオープンソースで進めており、 Github で公開しています。

リポジトリ https://github.com/benishouga/sourcer
ドキュメント&スタンドアローン版 http://benishouga.github.io/sourcer/standalone-ja.html
Herokuで立てている対戦サーバー https://sourcer.herokuapp.com/

これを社内で共有したところ、ときどき社内イベントや1dayインターンシップで活用されるようになりました。

個人開発のため なかなかにサービス化は難しいのですが、社内イベントなどクローズドなイベントと相性がよく、参加者からは軒並み好評で利用されています。

1dayインターンシップでの活用

Sourcerを活用したクレスコの1dayインターンシップでは、会社紹介はほどほどにとどめ プログラミングの楽しさ とともに 開発の流れ をざっくりと体験できる内容となっており、これまでに4回ほど開催されました。

流れは以下のような形で進めます。参加者にはプログラミング未経験の学生さんもいますので、各チームには先輩社員がメンターとしてつきフォローを行います。

  1. ゲームの説明と、未経験の学生さん向けに簡単なプログラミングの説明
    • 時間が限られているため、詳細は学生さん同士やメンターによるフォローでカバー
  1. チーム(2人~3人)を作る
    • 作り上げるプログラムはチームで1つ
    • 1人がプログラミング/周りは助言やAPIドキュメントを読んだりでサポート という形をローテーションする
    • 開発の醍醐味でもあるチームでの開発を体験してもらう
  1. いきなりプログラミングに入るのではなく、まず作戦を立てる
    • APIドキュメントを眺めたり、メンターのサポートを受けて、実現方法を検討する
    • 実際の開発現場のように、要件の整理/設計を行ってからプログラミングに入る
  1. プログラミングを行い、作戦に沿った動きとなるよう試行錯誤する
  2. 他のチームとエキシビジョンマッチを行い、課題を見つけて3に戻って繰り返す
    • 実際に利用しフィードバックを集めるユーザーテストにあたる作業
    • 開発は作ったら終わりではなく、課題を見つけ改善することを体験してもらいたい
  1. 最後はトーナメント戦
    • 自分たちが作ったものが動く達成感を体験してもらう
    • 対戦は3番勝負
      • 同じプログラムでも状況が変われば結果が変わって良い勝負になることも・・・

実際のワークでは以下のように苦労しながらも開発を楽しむようすが見て取れました。

  • 思い通りに動くようになったら新たな課題が見つかり一喜一憂するチーム
  • メンターの先輩社員を懐柔し実装を進めるチーム
  • 立てた作戦が壮大過ぎで残り5分の呼びかけに悲鳴をあげるチーム
  • 括弧{}の数がそろわず動かなくなって残り5分の呼びかけに悲鳴をあげるチーム
  • エラーの出ているプログラムを保存してしまい残り5分の呼びかけに悲鳴をあげるチーム

ワークの時間としては90分程度と短い時間ですが、学生さんのユニークな発想で様々な作戦が実現されており、いつもトーナメントでは盛り上がり必至な状況です。

Sourcerの作りの話

続いて実装に使っている環境やライブラリの紹介をします。ツール/ライブラリの選択では息長めのものをなるべくシンプルに使いたいという思いがあったりします。

アプリケーションスタック

基本的には MERN スタックで、 SPA として実装しています。俯瞰すると以下の感じです。

ブラウザとサーバーで一部モジュールを共有できる作りとし、特にコアとなる対戦ロジックについて “ブラウザ上の実行(コード作成中)” と “サーバー上の実行(対戦時)” で同一モジュールを使うようにしています。 今のところは機能追加を優先し SSR 対応は見送っています。

クライアントでは前述の通り 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 というサンドボックスライブラリを使用しています。ブラウザ側の実装としては、基本的に自身のプログラムしか動かさないため、セキュリティ考慮甘めでも良いだろうと、簡素な独自実装を行いました。

またプログラムに無限ループを突っ込まれるとサーバー全体が止まるという状況を避けるために、ユーザープログラムの実行では Node.js の Cluster を使ってプロセスを分けるようにしています。

あとは Promise を避け async/await 構文(@TypeScript)をなるべく使うようにしています。記述するコード自体はご機嫌になる半面、コンパイル後のJavaScriptコードが壮大なものになってしまう点だけ、複雑な心境になります。

開発環境

開発環境については俯瞰すると以下のような感じで組んでいます。 ツールを乗り換えてはバランスを整えるというサイクルを避け、少し枯れ目のもの中心に使っています。

モジュール管理/タスクランナーは基本的に npm だけで、並列/直列の実行制御だけ npm-run-all というツールを挟んでいます。 yarn についてはすごくすごく良いというのは理解なのですが、将来的に npm だけで完結してほしいという願いもあり今のところ使っていません。

バンドラについてはなるべく npm-run-script だけ使いたいというところがあり webpack を使わず Browserify を使っています。

コード自体は一貫して TypeScript で記述しています。コンパイルによるチェック/インテリセンス/リファクタリング/参照検索などなどが便利すぎて、本当に本当に今では TypeScript なしだと生きられない体になりつつあります。

あとは css 向けに PostCSS 、テスト向けに Mocha を使っているぐらいです。

まとめ

以上、1dayインターンシップでのプログラミングゲーム Sourcer の活用紹介 でした。

この記事を通してクレスコで行っている1dayインターンシップの特徴や楽しさが少しでも伝わってくれるとうれしいです。

また冒頭で紹介した通り、 Sourcer はオープンソースで開発しており、手軽にサーバー立てることも可能なのでぜひお仲間とのイベントなどで使ってみてください。