kqito's 技術ブログ

技術やプログラミングについて思ったことを呟くブログ

SSRするときはdockerを使おう...

はじめに

こんにちは。Webフロントエンドを専攻しているkqitoです。

今回はアルバイトでSSRしているサービスのデバッグをして苦労した + docker使った方がやっぱりいいよねと思った経験をまとめます。

環境

利用しているフレームワークはNuxt.jsで、プロセスマネージャーはpm2を利用しています。 またNuxt.jsということもあって、SSR + SPAという実装になっています。

ja.nuxtjs.org

pm2.keymetrics.io

遭遇したバグについて

とあるページに遷移するとクライアント側ではエラーログも出ずにNuxt errorのページが表示されるだけでした...

次にstaging環境でpm2 logを叩くと以下のログが出力されました。

ReferenceError: URLSearchParams is not defined

ReferenceErrorか... なるほど。そのまえにURLSearchParamsについておさらい。

URLSearchParamsって何?

URL関連をJSで扱いやすくするクラスです
簡単なデモを作ってみました。

const paramObject = {
  test1: 100,
  test2: 'テキスト'
}

const URLSearchParamsObject = new URLSearchParams(paramObject)

// URLで使用するのに適したクエリー文字列を返す
console.log(URLSearchParamsObject.toString())
// 結果: test1=100&test2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88

// 指定した検索パラメータが含まれているのか
console.log(URLSearchParamsObject.has('test1'))
// 結果: true

console.log(URLSearchParamsObject.has('test3'))
// 結果: false

このようにとても便利なAPIになっています。

また、各ブラウザの実装状況としてはIE以外がほぼ全て対応しているという状況です。

developer.mozilla.org

従って特にReferenceErrorなんて起こることはないはず...

さらにそのバグについて調査を進めた結果

ステージング環境でのみ発生

ということが判明しました。

🤔🤔🤔🤔🤔

解消方法

色々思考した結果、Node.jsのバージョンが古いんじゃね?という発想に至りました。

というのも、ブラウザではなくSSR時にステージング環境のNode.jsを参照していることに気づき、

URLSearchParamsが見つからない
↓
そもそもglobalとして定義されていない
↓
Node.jsに組みこまれたタイミングっていつ?

という発想に至りました。

ということでURLSearchParamsがグローバルオブジェクトとして定義されたタイミングを調べると v10以降ということでした。

僕のNode.jsはv10.16.3(Nodebrewを使用してLTSを導入)でしたが、ステージング環境のNode.jsはv8でした。

ということで、

ステージングEC2のyumのreposやcacheを削除後にNode.jsのLTSのrepoを導入
↓
yum install nodejs
↓
node -v 
 => v10.16.3

ということで、URLSearchParamsがグローバルオブジェクトとして定義されているバージョンでサービスをデプロイすると

エラー解消

となりました!!!!

思った事

クライアントとサーバー側でNode.jsのバージョン不一致問題

これ、かなり深刻だと感じました。その携わった開発環境はそもそもdocker、docker-compose等を利用していなかったので結果として Node.js バージョン不一致による進捗遅れ が発生してしまいました。

ローカルとステージング環境によるバージョンの違いが発生してしまったのでこの様な事が内容にミドルウェアをDocker等で管理する様な仕組みを導入する必要があると感じました。

もしくは、AWSのCode Deploy後のスクリプトに工夫をするなども選択肢としてあるのかなと感じました。

まとめ

実際にアルバイトとしてSSR環境のプロダクトの開発・デバックを行う事で、知識だけではなく実践的な経験を得ることができたと思います。

またSSRを利用する1番の目的はSEOの評価を向上させる事にあると思っているのですが、SEOの評価はそれだけではないので、基本的な部分から意識してコーディングしたいと感じます。