東大の学園祭のウェブサイト部門の技術がPHPからNuxtになるまで

# 前書き

この記事は、純粋に技術を紹介するというよりは、「いかに技術を浸透させたか」「つらみにどう対処したか」という「メタ技術」的な話になります。そのため、要素要素の技術の詳細には立ち入りません。ご了承ください。

また、長々と書いていますが、まとめだけ見たい人は一番したの「まとめ」までスクロールしてください。


# 対象読者

- これから情報システム部門を立ち上げようとしている人
- 情報システム部門にいて、新しく技術を導入したいけれど、技術的な「負の遺産」に悩んでいる人
- 人の入れ替わりが激しく、継続的な技術の蓄積が難しいと感じている人
- 情報システム部門にいるけど、他の部署からの圧力による要件追加などに悩んでいる人

# なぜ「学園祭」なのか

大学の学園祭の運営をしている、と聞くと、皆さんはどんなことを思い浮かべますか？
学園祭の楽しい記憶などがあっても、運営、と聞くと「？」となってしまう人が多いと思います。

今回のアドベントカレンダーは、そんな、普段目につかないようなところで頑張っている大学の学園祭の中でも、さらに一段と見えないところで頑張っている情報部門のアドベントカレンダーです。

ほとんどの企業が自分のウェブサイトを持ち、旅行するときは乗換検索、料理は食べログやGoogle Mapsに当たり前に頼るようになった2019年末の現在でも、情報部門をもつ学園祭運営団体はあまり多くないのが現状です。

経験からすると、それは「**学園祭の運営団体でITをやるのはつらい**」に起因するように思います。しかし、その**学園祭という特殊な環境にありながら、その「つらみ」はIT企業であれば当たり前に遭遇するような普遍的なものばかり**です。

- 人がすぐ辞める
- スキルの高い人が少ない
- 他の部署からの圧力がある
- 謎の秘伝のコードがある

etc...

今回は、そんな**「つらみ」といかに折り合いをつけながらITをやっていくのかという問題に対して、「技術選択」でどのように対処したのか。**
僕が在籍し、技術選択を行った2017-18年にかけての東京大学の駒場祭/五月祭実行委員会の事例を紹介します。

# 時系列

## 〜2016年 PHPの時代

2016年まで、駒場祭ではウェブサイトは基本的にはPHPで作られていました。いつからPHPで作られているのか、そしていつからそのようになっているのか厳密なことは分かりませんが、委員会内部の断片的な記録を辿ると、2000年代の後半には既にそのような形態になっていたことが伺えます。

さて、「PHPで開発」と言ってもいろいろな状況があり得ます。僕が駒場祭委員会に入った大学1年生の時の状況は、基本的には以下のような状況でした。

### 開発者のスキル・人数

**1,2年生合わせて5人程度、ほとんどは大学でプログラミングをはじめた人です。**もちろん、委員会でも何もしないわけではなく、入会してしばらくは「講習会」と称して2-3ヶ月ほど研修のようなものがあります。しかし、IT企業でのような集中的なものではなく、1週間に1-2時間程度のもので、さらにはJavaScriptしか基本的には教えないという極めて不十分なものでした。つまり、PHPに関してはほぼ全員が教育もなく先輩のコードを見様見真似したりする程度でした。

### 技術スタックと技術蓄積の状況

PHP-FPMで書かれていました。ざっくりいうとCGIです。「Perlで掲示板を作ろう！」みたいな本で一通り実装したことのある世代には非常に馴染みの深いものだと思います。

これだけでもかなりレガシーな匂いがしますが、それに加えて、**パッケージマネージャーもない**という状況でした。つまり、ライブラリを入れたりするのが非常に大変だったわけです。（流石にGitはありました。）

それでも腐っても東大生なので、頑張れば無理やり求める実装が出来上がってしまいます。結果として**秘伝のタレのようなコード**が多くあり、しかも初心者には読み解けない。メンテナンスができない。という状況でした。

しかも、駒場祭委員会には**大学1,2年生しか在籍できないため**、それらをリファクタできるレベルの技術に達する人もなかなか現れませんでした。東大は（2年はともかく）1年生の、特に理系のカリキュラムはかなり重いため、必然的にリファクタできるレベルの技術を手にする人はかなり限られていました。

## 2017年 Node.js(Express & Pug)への移行

### PHP→JS

先ほどの状況の問題を整理すると以下のようになります。

- PHPを書ける人材を育てられていない
- パッケージマネージャーがない
- 秘伝のタレコードが多い

一つ目は、そもそも委員会ではPHPを書いているのに、研修ではJavaScriptしか教えていないことに由来する問題です。しかし、実質教えることのリソースを増やしてPHPを教えるというのもとても厳しいものでした。これは、2-3ヶ月以上教えると、今度はウェブサイトを作る時間が取れなくなってしまうからです。
そのため、推定10年弱続いた伝統を断ち切って、**フロントエンドをJSだけで実装できるように**改めて技術選定を行いました。

具体的にはExpressとPugを採用しています。ビルドはGulpで行っています。
当時もReact,Angular(Vueはまだ日本では比較的普及している途中だったようです)などのフロントエンドフレームワークはかなり有名でしたが、「教えきれない」という理由でウェブサイトでの導入を断念しています。（とはいえ、他のより小規模なシステムには採用しています。）
ExpressもPugも**学習コストの少ないフレームワークだったので、移行そのものは比較的楽**でした。

二つ目についても、PHPの場合はComposerなどのツールがありますが、Node.jsの場合は**npmでかなり簡単にライブラリをいれることができる**ようになりました。

三つ目もかなり状況が改善されます。PHP時代のコードのほとんどに対し、対応するライブラリを見つけられたため、**そもそも実装が減ったので、秘伝のタレコードなるものも自然と減ります。**

### 秘伝のタレ、再び

一見良いことづくめで、実際最初の1-2ヶ月は良い感じに回っていましたが、結論からいうとExpress & Pugも狼人間に対する銀の弾丸ではありませんでした。

ライブラリの大量投入により実装そのものは大幅に減り、僕らはより難しい、抽象的な問題に集中できるようになりました。しかし、今まではみんながしなければいけなかった「難しい実装」が特定の人に集中する、ということが起こります。集中するだけならこれはこれで良いのですが、問題は、**難しい実装をする人が多忙により後世に知見を引き継げない**ということでした。

具体的には、Expressのgulpのスクリプトがそうなりました。当時の駒場祭委員会では、gulpで「ファイルが保存されたら再ビルド & リロード」などのタスクを定義していました。しかし、かなり複雑な実装だったため、それらを理解できる人がいないという問題が発生しました。

### 政治的圧力による要件追加

これはコミュニケーションの不足なのですが、Twitterカードなどを表示するためのOGPコードの導入が後付けで決まります。ウェブサイトを実装するのは駒場祭委員会のシステム局の管轄ですが、局長である僕はその要求を断ることができませんでした。これは、ウェブサイトの内容などを決める他の局の方が基本的に発言力が強かったことに由来します。

要件に入ってなかったのを半強制的に入れることになったため、当然、かなりの実装コストを強いられました。これにより、他の実装に回せたはずのリソースを吸われてしまい、スケジュールの遅延などが悪化しました。

## 2018年 VueとNuxtの導入

先ほども言ったように、駒場祭委員会に在籍できるのは大学の1,2年生だけなので、これからの話は五月祭実行委員会での出来事になります。

### 秘伝のタレの解消、その2（Nuxt.jsへの移行）

五月祭実行委員会では、今度は1-3年が12-6月にかけて祭りの運営をしています。
その中で2年生として入った僕は今度は、中間学年として改めてウェブサイトの技術選定を行うことになります。

しかし、五月祭でExpress & PugでまたGulpを書き、秘伝のタレを生み出すのも気が引けます。何より、そのGulpスクリプトによる構成はOGPコードの実装が非常に面倒な構成を前提としていたので悩みました。

そんな時に出会ったのがNuxt.jsでした。

2018年の1月当時、Nuxt.jsはv1になったばかりという非常に新しいフレームワークでしたが、ビルドやページ追加などの指針が明確に整理され、**ウェブサイトの基本的な構造を非常に簡単に作れる**という点で非常に優れていました。これにより、さらに秘伝のタレコードを減らすことができるようになりました。

### Vue.jsの導入

Nuxt.jsはVue.jsを前提にしたフレームワークですので、当然チームで使う際にはVue.jsの概念、コンポーネントやディレクティブ、プロパティー渡しなどを普及させる必要があります。

VueはReactなどに比べるとHTML & CSSからの移行は楽なのですが、JS部分の移行に関してはそうは行きません。しかし、これについても**Vue.jsの公式ドキュメントが非常に充実していたため、教える側としてはかなり楽でした。**

### 政治的圧力への対処

政治的圧力がしんどい場合の解決策はいろいろありますが、当時の僕が最初にとった手段は「**そもそも政治的圧力が発生しないようにどうにかする**」というものでした。

つまり、事前に要件は決めつつ、「後からの要件追加は、実装コストによっては却下します。なぜなら他の、より優先度の高い実装の障害になるからです。」という方針でまずは他の担当の合意を取り付けました。
これにより、要件の決定権がなく、勝手に仕事のゴールポストをずらされるという状況がかなり改善します。

その上でもごねてきた連中に対しては**合意を盾に容赦無く提案を却下**しました。
面白いのは、普通なら信頼されなくなると思うところが、これにより**優先度の高い実装に優先的にリソースを回すことができるようになり、結果として信頼関係が強化された**ことです。

冷静に考えてみるとこれは当たり前で、能力を超えた仕事を請負っても失敗するのだから、わかっている場合は最初から請けない方が「請負った仕事は終わる」確率は上がります。（いささか力技でしたが）

# まとめ

## つらいところ

- 初心者が大量に入ってくる
- 2年程度しかいないのでスキルの高い人が少ない
- 秘伝のタレコードがある
- 政治的圧力をかけられて要件が追加されたりする

## どうしたか

- 初心者でもできる方法を模索する
    - 駒場祭/五月祭委員会の場合は、それがNuxt.jsだった
- 秘伝のタレコードは思い切って捨てる
    - 学習コストの少ないものを採用すると移りやすい
- 要件追加の方法を合意し、ごねる人には毅然とした態度で
    - 長期的な信頼関係を築くにはむしろその方がよい