📚

マナリンクの開発環境カイゼンの歴史(Laravel、Nuxt.js)

2021/12/10に公開

今回はゆるめのテーマとして、これまでマナリンクが歩んできた開発環境カイゼンの歴史を振り返っていこうと思います。

現時点の開発環境だけ見ると、良いところも悪いところも目に付きます。しかし、過去から振り返ってどういうふうにカイゼンしてきたかが分かれば、今見えている問題点も一つひとつ解消していけば前進していける、ということがわかると思い、この観点でまとめてみることにしました。

前提

前提として、マナリンクは前身となるサービスとして「NoSchool」という勉強質問サイトを運営している時代がありました。この頃から会社としては自社開発を続けており、サービスをクローズして新しくマナリンクを始めたときも、大枠の技術選定は変えませんでした。なので本記事ではNoSchoolの時代を含め振り返っていきます。

Wordpress + Bitbucket時代

一番最初は、Wordpress + Bitbucket時代です。時期としては2018年5月〜2019年5月頃までを含みます。

このときはNoSchoolの立ち上げ初期で、フルタイムのエンジニアもおらず、現在CTOを務める私も副業で入っている段階でした。なのでほとんど実装がいらない構成で進めていました。
記憶が確かではないですが、当時はまだGitHubもプライベートリポジトリ作り放題ではなかったはずです。なのでBitbucketで済ませていた気がします。

Laravel + 部分的にNuxt + AWS(EC2ベース) + GitHub時代

以下の記事でも書いていますが、NoSchoolというサービスを運営し最初の資金調達後、晴れてそれなりの開発環境へのリプレイスを行いました。

https://qiita.com/mejileben/items/f68a50ec9164b261b9cd

2019年3月〜5月くらいの2ヶ月強で移行しています。

ここで一気に開発者が開発しやすい環境にある程度は変化しました。
しかし今から振り返ると、当時はまだまだ目立った課題が多く、

  • Wordpressから機械的にコピーしたPHPコードが散見
  • これを機にフロントエンドを一気にNuxt化したかったが、余裕がなく半分ほどのページだけNuxtという半端な状態
  • バックエンド含め、テストコードがまったく書かれていない
  • AWS運用の知見もないので、EC2をAMIベースでひたすら秘伝のタレとして継ぎ足して管理

といった状況でした。他方、GitHub管理やAWSの利用開始そのものは非常に意義深かったです。また、DBもWordpress特有の縦持ち地獄から横持ちに書き換えることができました。

徐々にNuxtの利用箇所を拡大 & 初めてのテストコードに挑戦の時代

2019年5月〜12月頃に掛けては、新機能を原則Nuxtで開発することで、徐々にNuxtの利用箇所を拡大していきました。
さほどリッチな機能のアプリケーションではなかったものの、VueのSFCの恩恵でCSSを管理しやすい点や、モーダル等の状態を持つページを容易に構築できる点は、SSRなどの複雑性をある程度補えるメリットだったと思います。

2019年10月頃には待望のTypeScript移行を果たしています。当時はNuxt2.9あたりでようやくTSサポートが整ってきていました。

https://qiita.com/mejileben/items/fd1dffd1428513503be3

2019年10月〜12月に掛けて、収益化に乗り出すために決済機能の実装を行いました。
初めての決済機能を実装するにあたって、これまでのシンプルな勉強質問サイトとは違って絶対にバグらせることはできないというプレッシャーがありました。
この時期はとにかく設計周りの情報収集から、テストコードの書き方まで学びまくり、なんとか12月にテストコードがある状態で決済機能をリリースできた記憶があります。

https://qiita.com/mejileben/items/302a9f502ca0801b1efb

当時はiOSアプリも開発していたので、Sign in with Appleなどの実装も要求されてしまい(ソーシャルログインがあったので)、そのへんの闇の実装もテストコードを書きつつおそるおそる進めていました。

https://qiita.com/mejileben/items/df79024ae93971643271

今から振り返ると、当時詰め込んだ設計の知識はまだまだ甘いなとは思いますが、モデルに依存しないように実装するのは大切な原理なので、そこは早期に抑えることができてよかったなとは思います。
決済サービスとの連携を伴う実装では、容易に実装がそれら外部サービスの仕様に引っ張られて汚くなるため、理論と実践の差分も痛感することができました。

ピボットに伴うバックエンド混在の時代

2020年1月頃、NoSchoolの課金機能が鳴かず飛ばずだったことを決め手として、「オンライン家庭教師サービス」へのピボットを会社として決断しました。

これに伴い、先月まで実装していた決済機能は削除、心機一転でオンライン家庭教師のための課金プラン作成の実装へ進むことになります。

もちろん開発者としては、先月まで社運を掛けて実装していた機能の削除は心理的なダメージもあることでしたが、結果としては模索した痕跡の残る実装を速攻で消しされたのは良かったことかもしれません。
まだまだ荒削りではあったものの、オンライン家庭教師に特化した課金仕様を3月までの2ヶ月間で(もちろんフロントエンドも含め)一気に実装することができました。

この頃から取り組んできた実装上の工夫として 「機能ごとにnamespaceを切り分ける」 があります。

NoSchool時代になんとなくDDDを導入しようとしたものの実際は「UserService」といったクソデカServiceクラスがいくつもあり、それらを今後も利用すると意図しないバグが発生することが予想されます。
その対策として、機能ごとにnamespaceを分けてそのなかでアプリケーション層やドメイン層、インフラ層を置くことにして、この方針は今でも続けています。

なお、この時代は多忙のあまり開発工数削減への意識も芽生えてきており、aspidaを使ったAPI管理だったり、microCMSを使った管理画面開発工数の削減に積極的に取り組み始めました。

https://qiita.com/mejileben/items/6b15d91995927a8df262

「マナリンク」誕生の時代

2020年6月頃、NoSchoolの新機能として始まったオンライン家庭教師サービスが順調な滑り出しを見せたことを受け、いよいよオンライン家庭教師機能を切り出して、「マナリンク」というサービス名とドメイン(manalink.jp)で新サービスとしてリリースしました。

2020年8月にマナリンクが正式公開された頃には、

  • AWSはEC2秘伝のタレではなくFargateによるコンテナ管理に
  • フロントエンドは全部Nuxtで、Laravelは完全にAPIサーバーに
  • aspidaでAPIに型安全にアクセスすることがデフォルトに
  • NoSchool時代のコードを切り離したことで、ほとんどのAPIにテストコードが備わった状態に

なりました。また、厳密な時期はうろ覚えですが、このあたりでPHP7.3から7.4に上げて、よりクラスの開発が捗るようになった記憶があります。

「マナリンク」検証の時代

2020年8月以降は、オンライン家庭教師サービスとして先生・ご家庭双方のニーズに応えられるように、オンライン指導専用アプリの開発であったり、オンライン家庭教師の働き方について発信するメディアの開発にも取り組んできました。

そのため既存環境のカイゼンというよりは、新しいプロダクトのリリースに取り組んでいることが多かったです。
しかしその中でも開発メンバーが実践してきたカイゼンポイントをいくつか上げてみます。
ここまで解説してきたカイゼン内容は、さながら「縄文時代から弥生時代」のようなものでしたが、このあたりまで来ると「明治時代から大正時代」くらいの感覚です(?)

開発環境を独自ドメインでSSL化

https://zenn.dev/manalink/articles/manalink-ssl-original-domain

ローカル環境で独自ドメインが当たると、ポート番号を覚えなくてよかったり、localhost独自の罠(ブラウザの警告など)にハマらないので便利です。

Nuxtのtsconfigから"noImplicitAny": trueを削除

最初にJSからTSに移行したアプリケーションだったので、これは結構骨の折れる作業でしたが、古い実装を徐々に消すなどの積み重ねで完了することができました。

Vueでpugの利用を中止。一括置換

昔はPugで書くのがDX良いと感じていましたが、Pugで書いているせいで適用できないESLintルールなども存在しますし、そもそもEmmetを使えばPugのタイプ数でHTMLが書けるといっても過言ではないので、一気に置換してPugをやめました。

GitHub Actionsのいろいろな活用

https://zenn.dev/manalink/articles/manalink-github-actions

GitHub Actionsに限った話ではないですが、運用フローや品質面については、ドキュメントにまとめて開発者に周知するようなやり方はできるだけ避けたくて、GitHub Actionsによってプルリクと同時に何らかのチェックを走らせたり、日頃の開発でコードジェネレーター(scaffdogとか)を使って生成するようにしたり、ESLintの設定でimport先を縛ったり、さまざまな工夫でコードベースでルールを守って開発できるようにしたいなと思っています。

カイゼンするなかで思ったこと

最後に、簡単にこれまでカイゼンしてきて思ったことをまとめてみます。

事業的に優先度が高いところは、いずれ機能改善が入るので、リファクタリングも追ってできる

難しい実装をしているとき、初期リリース段階でどの程度設計を頑張ろうか?みたいな疑問って誰でも思ったことがあるかと思いますが、個人的にはテストコードさえあれば、あとからリファクタリングはできるし、事業的に優先度が高ければすぐにユーザー検証が入って治したいところが出てくるのでリファクタリングのチャンスが巡ってくると思います。

つまり、優先度が高くドメイン知識が刷新されるところほど、「事業戦略と実装の一致度」が高まるし、そうでないなら乖離したまま放置されるだけの話だと思うのです。なので、初期実装段階での設計云々については細かく言ってもキリが無いのかもなーと個人的には思っています。まあこればかりは会社によりますが・・・

自分たちが頑張っても競争優位性にならないものはXaaSでカバーする

SEO集客のために自社メディアを持つとして、そのメディアの入稿画面を自分たちで内製しても、それが自社サービスの競合優位性に繋がっているでしょうか
少なくともマナリンクに関してはオンライン指導体験の向上やマッチングの最適化に工数を突っ込むほうが良いだろうと思います。

そういうときこそ、XaaSに頼るべきです。弊社がmicroCMSを使っているのはそういう理由です。

他で言うと、テスト工数を浮かせるAutify、Magic Podとか、Feature Flagの実装工数を浮かせるLaunchDarkly、Flagsmith、Statsigなどが挙げられます。

いずれ必要になりそうな技術を先に追っておく

少なくともスタートアップでは、今後こういうものを作りたいね、という話は社内で日常茶飯事ですし、ある程度大きな企画であれば十中八九自分自身が開発に関わることになると思います。

そのため、あらかじめ予習しておくことでいざというときに気になる技術を導入することができるはずです。
エンジニアは100勉強しても実務で10活きたら良い方ではある生き物ですが、スタートアップではそれを30とか50くらいに持っていくこともタイミング次第ではできるかなーという肌感覚です(僕は活きる活きないに関わらずMLとかWebRTCとかにも食いついてしまう人間なのでアレですが、人によってはもっと高い割合にできると思います)。

実例として2020年5月ごろからNext.jsのISRを素振りしておいて、10月にメディア開発が決まったときに躊躇なくNext.jsを選んでmicroCMSと組み合わせることで2週間でリリースにこぎつけることができました。

まとめ

ここまで読んでいただいてありがとうございます!

書き始めたら止まらなくなってけっこう書いてしまいましたw

マナリンク Tech Blog

Discussion