サイトリニューアルでしたこと

概要

現在、サイトリニューアルを行なっている。 忘れないうちに、思ったこととかやったことをメモ。

はじめ

WEBサイトリニューアルをするということで、入社した。
入社時点で、PHPのCodeIgniterから、Railsに移行するということは決まっていた。
また、ReactとかVueを入れたいという要望も出ていた。

技術選定

フロントエンドをどうするかで結構悩んだ。
最初に挙げられた選択肢は 3つ。

  1. Rails に、webpackerで、Client Server Rendering。
  2. Rails に、hypernovaとか、react on rails とかで、Server Side Rendering。
  3. Rails & Slim を基本は使い、jQueryみたいに、一部分だけVueとか使う。

ただ、1は、SEO的にリスクとれなくて、SSRしたいということでNG。
2は、Nodeサーバの運用が誰も経験なくて、複雑そうだったので勇気でなくてNG。
3は、コンポーネント志向で開発したかったのでNG。
となった。

そこで、勉強会とか参加して、調査進めていくうちに、Next.js、Nuxt.js というものを知った。
簡単にいうと、SSRが簡単にできて、なおかつモダンな開発環境が簡単に作れるといったもの。
SEOのためにSSRしたい + Vueの方が日本語ドキュメント豊富 ということから、Nuxtを採択した。
Nodeサーバもリクルートさんとかで、運用事例が出てたので、これはいける!と思って、自身持って提案したらOKが出た。
選んでみて、フロントのモダンな開発環境が作成でき、簡単かつフォルダルールが明確で、選んで良かったと思う。

デザインリニューアル

入社時点で既にWEBサイトのデザインリニューアルの会議が行われてて、サイトリニューアル時についでにやっちゃおうって感じだった。
同時のタイミングでやってるので、いらなそうなコンテンツ削除とか、速度に影響を与えるコンテンツの仕様変更とか、提案しやすくてよかった。
一方で、リリースがデザイナー律速になる可能性があるので、サイトリニューアル急ぎの時は辞めた方がいいと思った。
今回は、急ぎなわけではないし、空き時間で別案件を行なってたので問題なかった。
悲しいこととして、リニューアルしていらない機能が減ると思ってたら、増えてる部分もあって、速度大丈夫か不安な部分もある。
SEO的にSSRしてるけど、一部コンテンツは、非同期でとってこないといけないかも...

それに合わせてアトミックデザインも考えたが、最初からうまく作れる気がしなかったので断念した。
その代わりといってはなんだけど、Storybookを入れた!
最近は追加できてないけど、先輩が手伝えそうということなので、どういうコンポーネントがあるかを整理して、Storybookにまとめておきたい。

構成

フロントエンドとバックエンドのサーバを分けて実装した。
Nuxtは、Expressのミドルウェアとして利用している。
1ページ毎にリニューアルし、完成したらALBにパスルーティングで、Express側に付け替えるって感じで進めている。

今までのURL

Route53 -> ALB -> CodeIgniter(PHP

リニューアルしたURL

Route53 -> ALB -> Express(Nuxt)-> Rails

フロントエンドとバックエンドを分離していて、今はサーバサイドエンジニアしかいないけど、フロントエンドエンジニアが入った時もばりばり作業ができるようになってる。
一人で開発してるからだと思うが、サーバとかリポジトリを分けたことによるメリットを感じないけど、デメリットも感じないので、これで良かったのか未だによく分からない...。
あと、 先輩のアドバイスから、Railsは外に繋げてない(ExpressからAPIを叩く必要がある)ので、Railsサーバに外からアクセスできないようにした。
Express側ではAPIアクセス時、http-proxy-middleware を利用してて、とても便利だった。

APIの仕様に関しては、GraphQLとか、Swaggerとか使おうかと思ったが、会社独自のAPIのURLルールがあったので、それに準拠した。

開発

Nuxt

TypeScriptを試してみたが、サンプルコードがほとんどJSで書かれてたり、Vueの実務経験もなかったので、時間がかかりすぎて2日で断念した。
今から始めるなら、NuxtがTypeScriptをサポートしたし、VueもTypeScript使ってる人多いから問題ないかも。

テストに関しては、レガシーからの脱却を掲げているにもかかわらず、未だに書けてない。書かないと...

あと、ページ特有のデータを、Globalにもつのが好きじゃなかったので、Vuexはそんなに使わずに、props渡しをメインにした。
一方で、UA情報とか動的な設定値とかもVuexに入れて、VuexはGlobal変数みたいな感じで使ってる。

APIのアクセスに関しては、最初 api.js ファイルみたいなのを作ってたが、基本Pagesから呼ぶようにしたので廃止した。
一方で、「いいね」ボタンが押された時に、APIアクセスするコードを、Component に置いているので分離させたいが、いい感じのやり方が思いつかない...

Nuxtや、Vueを使ってて特に良かったと思う時は、動きの部分を実装してる時で、vue の transition とか、スタイルバインディングとかで、デザイナーからの動きの要望を簡単に実現できた。
TOP画面にスライドショーを作ったが、今まではjQueryを使ってたけど、今回は自作してて、細かい要望に簡単に対応出来た。

あと、SSR時、Nuxt標準のサーバを利用する選択肢もあったが、今回はExpressを使った。
ライブラリが豊富だし、シンプルで使いやすいし、フロント側のサーバでできることが広がった。BFFの役割を将来的にはもたせたい。

あと、Adsenceの広告周りを、Vueで組み込めるかが不安だったけど、今のところ安定して動いていて、問題なさそう。

Rails

Rails Wayに準拠することを目標にしている。
テストコードを真面目に書くのは初めてだったが、今のところControllerと、BusinessLogic周りは全部書けている。
リファクタリングが怖くなくなったし、開発時もブラウザ確認回数が減るし、やっとテストの良さがわかった。
名前空間だけ未だに慣れない。ライブラリで同じ名前使われたりした時困って諦めた。

ActiveRecordは何が起こってるかわかんないときがあって、慣れるまで大変だったけど、慣れるとすごく便利。 パフォーマンス向上のため、生SQLをかかざるを得ない時もありますが...

Viewに関しては、jbuilderを使ってて、使いやすくて便利。
作り方覚えて、Scopeとかいい感じに設定できてくると、開発速度が凄く上がってるなって感じがする。
WEBサイトのAPIで、Railsがよく使われてる理由がわかった!

ただ、次はGoとかTypeScriptとかも試してみたい!

インフラ

EC2

インフラ側を一から構築するのは初めてだったので、先輩に教えてもらいながら行なった。

最初はEC2にサーバを最低2台ずつ立ち上げてた。
Nodeサーバは、Expressはデーモン起動のために、pm2を利用した。 Railsサーバはpuma。 どちらのサーバも、nginxをproxyと静的ファイルの配信と、ログ収集のために利用した。

access_log とかは、kinesisでlogをS3に送ってるらしい。 監視については、zabbix -> grafana で行なった。 デプロイは、CodePiplineで、ブランチへのpushを検知し、CodeDeployを利用して、Deployした。

AMIとか、セキュリティグループとかは、既に先輩が作ってたものを利用した。

問題として、CodeDeployでデプロイするときに、新旧サーバが起動してる瞬間があって、そのときに静的ファイルをnginxから配信すると、not foundエラーが起きる時があった。
詳しくは後述するが、なのでS3にあとで移動した。

ECS Fargate

社内のDocker推奨の機運が高まったので、ECSに移行することにした。
DockerFileはもともと勉強してたので、あんま問題なかった。 Nodeサーバは、Dockerだと、デーモン起動必要ないし、ログも標準出力で良かったので、node index.js みたいに起動した。 Railsサーバは引き続きpumaだけど、ログを標準出力に変えた。

デプロイは、CodePiplineを利用。
Githubのソースを元に、CodeBuildを走らせ、Docker buildして、ECRにImageをpushする。
次に、Nuxtの場合だけ、ECRのImageにbuildしたファイルが入ってるので、それを取得し、S3へアップロード(ブラウザからはCDNを介してアクセス)。
最後に、ECSでデプロイするって流れ。

先輩が、これらの設定を一発で行うshellファイルを作ってくれたので余裕でできた。(後から手でもやったが覚えれば簡単だった)

監視は、引き続き、nginxのログをkinesis agentでS3に送った。
あと、2xxとか3xxとかResponseTimeとかを見るために、ALBを監視してる。 また、CPUとかは、CloudWatchでもみてるが、DataDogをタスクに追加して、監視に利用してる。
DataDogは、APMを利用して、パフォーマンス測定も簡単にできそうなので、すごい!

Fargateは、SSHログインできないので、調査しにくいところが困ってる...
だいたいLocalで、Docker立ち上げれば原因は分かるけど、プロセスの状況を知れる方法が知りたい。
パフォーマンスチューニングをしたいけど、linuxのコマンド叩けなくて挙動が今のところ不明...
インフラ周りの勉強をもっとしなきゃいけない。

その他

自分がNuxtを導入した後、弊社のCTOが気に入って、それ以後の新規C向けサイトをNuxtで作成するようになった。 自分はほとんど説明してないのに、サイト毎にそれぞれ別の先輩が、ささーっと作ってたからNuxt(+ Vue)のドキュメントや分かりやすさが、すごいなと改めて思った。

感想

入社時は、PHPできます!コーディングできます!リスティングとかABテストとか施策考えられます!って感じだった。
それが、入社して9ヶ月で、

  • Railsで開発できます!
  • Vue & Nuxtで開発できます!
  • Express使ったことあります!
  • Dockerで環境構築できます!
  • ECSで本番環境構築できます!
  • 既存サイトのリニューアル経験あります!

って言えるようになったのは、先輩たちや与えられたポジションのおかげで、感謝しかない。

今までの会社では、個人とかチームで、企画考えて、CVRあげていこうってのがメインで楽しかったけど、企画から一歩離れて、技術に正面から向き合うのも楽しいなって思った。

今後

まずは、リニューアルを最後までやりきりたい。 あと、現在インフラ、バックエンド、フロントエンドを全部一人でやってるので、ドキュメント整備しないといけない。 一応、複数人で開発してるときと同じように、意識して作ったり、一部ドキュメント書いたりしてるけど、新しく入った人が困らないようにしないといけない。

また、会社として、マイクロサービス化を進めるので、先輩たちの仕事をキャッチアップしながら、勉強していきたい。
具体的な技術的には、

  • TypeScript
  • Go
  • Envoy
  • Kubenetes

を学んでいきたい。

あと、Ethereum を使うサービスを手伝ってるので、ブロックチェーン周りの技術も勉強進めていく。