2023.9.9のジャムスタックチョットデキル!!ナカノ!!で登壇した内容です。 実際の案件を例に取り、どのような対応を行ったかお話しました。
ジャムスタックチョットデキル !! ナカノ!!2023.09.09 ジャムスタックチョットデキル!! ナカノ!!Shumpei (chot Inc.)複数人での大規模サイト移植のテクニック
View Slide
ジャムスタックチョットデキル !! ナカノ!!ShumpeiX: @seventhseven- ちょっと株式会社 受託事業部 - フロントエンドエンジニア- 妻と4歳の息子と暮らしています。- 趣味で漫画のファンサイトを運営しています。2
ジャムスタックチョットデキル !! ナカノ!!今日話すこと1. プロジェクトの概要2. 技術面での課題と対応3. プロジェクトを通して4. まとめ3
ジャムスタックチョットデキル !! ナカノ!!1.プロジェクトの概要4
ジャムスタックチョットデキル !! ナカノ!!今回のプロジェクトの目的WordPressで長らく(10年)運用されてきたコーポレートサイトをJamstack化するプロジェクト。- 移行対象ページ700ページ超- 日・英・中の3カ国語のページが存在する- 開発期間は約2ヶ月弱静的サイトへ移行することで、セキュアな構成にする。5
ジャムスタックチョットデキル !! ナカノ!!●Jamstack構成でビルドした成果物をS3へデプロイする今回使用した主な技術スタック6bucket-abucket-b●●●S3AWSNuxt.js
ジャムスタックチョットデキル !! ナカノ!!●Jamstack構成でビルドした成果物をS3へデプロイする今回使用した主な技術スタック7bucket-abucket-b●●●S3AWSNuxt.jsコンテンツによってはNuxt.jsとは別ルートで特定のバケットにデプロイする
ジャムスタックチョットデキル !! ナカノ!!Jamstack移行計画8過去のページを静的化
ジャムスタックチョットデキル !! ナカノ!!Jamstack移行計画9過去のページを静的化CMS連携部分をJamstack化
ジャムスタックチョットデキル !! ナカノ!!Jamstack移行計画10過去のページを静的化CMS連携部分をJamstack化Nuxt.jsへ統合
ジャムスタックチョットデキル !! ナカノ!!Jamstack移行計画11過去のページを静的化CMS連携部分をJamstack化Nuxt.jsへ統合
ジャムスタックチョットデキル !! ナカノ!!静的移行ファイルについて移行対象のファイルは、WordPressで管理されているページの他、大量のHTMLや画像・pdfなどのバイナリファイル群があったため、段階的にスクレイピングを行った。ワードプレス由来になっている箇所を整えたのち、Nuxt.jsのpublicディレクトリへ格納した。12スクレイピング
ジャムスタックチョットデキル !! ナカノ!!Jamstack移行計画13過去のページを静的化CMS連携部分をJamstack化Nuxt.jsへ統合
ジャムスタックチョットデキル !! ナカノ!!フロントエンドのディレクトリ構成14・TOPページNuxt.js・最新のニュース・IR・問い合わせなどsrc/pages ・過去のニュース・IR・会社概要・部署ごとの紹介などsrc/public※PJの都合上src配下に配置
ジャムスタックチョットデキル !! ナカノ!!フロントエンドのディレクトリ構成15・TOPページNuxt.js・最新のニュース・IR・問い合わせなどsrc/pages ・過去のニュース・IR・会社概要・部署ごとの紹介などsrc/publicCMS部分は公開環境とプレビュー環境を用意する※PJの都合上src配下に配置
ジャムスタックチョットデキル !! ナカノ!!CMS連携について公開環境はSG、プレビュー環境はSPAで描画する仕様。nuxt.config.ts内で環境変数をもとにふるまいを分ける。16nuxt.config.ts
ジャムスタックチョットデキル !! ナカノ!!環境ごとの記事データの扱いプレビュー環境(SPA)の場合- アセットファイル含め記事内のデータは、画面アクセス時にcontentfulからAPI経由で表示させる17
ジャムスタックチョットデキル !! ナカノ!!環境ごとの記事データの扱い公開環境(SG)の場合- 記事で使用する画像などのアセットファイルは、ビルド直前にcontentfulからダウンロードしてプロジェクトファイルに含める18
ジャムスタックチョットデキル !! ナカノ!!環境ごとの記事データの扱い公開環境(SG)の場合hooksを使って、ビルド直前に、記事データを ダウンロードする関数を 実行してデプロイする。19nuxt.config.ts
ジャムスタックチョットデキル !! ナカノ!!開発エンジニアの役割分担実装を担当するエンジニアは役割を分担して、それぞれのタスクを担当していった。20
ジャムスタックチョットデキル !! ナカノ!!開発エンジニアの役割分担21下地作り・コア部分以外の実装ビルド周りやNuxt.js自体の調査・対応CMS連携のコア部分の実装(ニュース・IR)
ジャムスタックチョットデキル !! ナカノ!!日々の進め方- タスクはすべてbacklogにてチケット管理- デイリースクラムを組み、朝会を毎日30分程度実施- 開発序盤からQAエンジニアも参加してもらい、各メンバーの進捗状況を確認していた22
ジャムスタックチョットデキル !! ナカノ!!2.技術面での課題と対応23
ジャムスタックチョットデキル !! ナカノ!!技術面での課題このPJ特有なものも含め、いくつかの課題があった。24
ジャムスタックチョットデキル !! ナカノ!!技術面での課題- ビルド時のリンクエラー- 不完全なページがデプロイされる- デプロイの長時間化25
ジャムスタックチョットデキル !! ナカノ!!技術面での課題- ビルド時のリンクエラー- 不完全なページがデプロイされる- デプロイの長時間化26
ジャムスタックチョットデキル !! ナカノ!!ビルド時のリンクエラー- ビルド時、生成したページのURLリスト内に、404エラーを出力するURLがいくつか表示されていた- URLを見る限り、publicディレクトリに格納されている静的HTMLと関連していた27
ジャムスタックチョットデキル !! ナカノ!!ビルド時のリンクエラー- ビルド時、生成したページのURLリスト内に、404エラーを出力するURLがいくつか表示されていた- URLを見る限り、publicディレクトリに格納されている静的HTMLと関連していたNuxt.jsのページデータの取得方法や、ビルド時の挙動を把握することが必要になった。28
ジャムスタックチョットデキル !! ナカノ!!nitroを調べるnitroはNuxt.jsのサーバーエンジンを担うモジュール29https://nitro.unjs.io/
ジャムスタックチョットデキル !! ナカノ!!ビルド時のエラーまでの流れ1. yarn generateする2. nitroのprerenderがページ内のaタグを検知する3. リンクされている全てのページをNuxt.jsでビルドしようとする4. publicにある通常のHTMLファイルや、別バケットにあるページもリンク先であれば対象になり、これらもNuxt.jsでビルドしようとする5. vueファイルではない・もしくはNuxt.jsの管理外ため、ページが存在しない判定となってしまう30
ジャムスタックチョットデキル !! ナカノ!!nitro側で行える、ビルド設定のひとつ。ビルド時に指定されたルートにフェッチし、静的ファイルとして.output/publicディレクトリにコピーする。ignoreにリストされたルートは無視することができる。Default: { crawlLinks: false, ignore: [], routes: [], … }https://nitro.unjs.io/config#prerendernitro/prerender31
ジャムスタックチョットデキル !! ナカノ!!実装方針nuxt.config.tsにnitroプロパティを追加し、prerenderのignoreに弾きたいパスを登録することで回避できた。32nuxt.config.ts
ジャムスタックチョットデキル !! ナカノ!!技術面での課題- ビルド時のリンクエラー- 不完全なページがデプロイされる- デプロイの長時間化33
ジャムスタックチョットデキル !! ナカノ!!不完全なページがデプロイされるビルドは成功し、デプロイ先でページは表示される。ただし動的なコンテンツが取得されていない、または部分的に表示される現象。34
ジャムスタックチョットデキル !! ナカノ!!不完全なページがデプロイされる調査の結果、CMS側に500エラーが発生したもののそのままビルドされ、デプロイまで通っていたことが判明。35
ジャムスタックチョットデキル !! ナカノ!!不完全なページがデプロイされる調査の結果、CMS側に500エラーが発生したもののそのままビルドされ、デプロイまで通っていたことが判明。→ 500エラーの場合は、異常終了させる処理を加えることで対応36
ジャムスタックチョットデキル !! ナカノ!!カスタムエラーハンドラで対応するhttps://nitro.unjs.io/config#errorhandler37
ジャムスタックチョットデキル !! ナカノ!!カスタムエラーハンドラで対応する先述のnuxt.config.tsのnitroプロパティに、errorHandlerを追加し、割り当てたerror.tsの中で対応した38nuxt.config.ts
ジャムスタックチョットデキル !! ナカノ!!技術面での課題- ビルド時のリンクエラー- 不完全なページがデプロイされる- デプロイの長時間化39
ジャムスタックチョットデキル !! ナカノ!!デプロイ完了までの長時間化についてCMS連携において、本番環境を再現したかったものの、クライアント様が環境を用意しており、セキュリティの観点からインフラ設定を把握することが難しかった。40
ジャムスタックチョットデキル !! ナカノ!!デプロイ完了までの長時間化についてCMS連携において、本番環境を再現したかったものの、クライアント様が環境を用意しており、セキュリティの観点からインフラ設定を把握することが難しかった。インフラが関連する事象に関しては、ローカルで完全に再現することができなかったため、どうしてもデプロイして確かめる必要があった。41
ジャムスタックチョットデキル !! ナカノ!!デプロイ完了までの長時間化についてただ、過去のページや大量のバイナリ(画像やPDF)もすべてNuxtで抱えるため、デプロイが完了するまでに45〜50分程度かかってしまう。42
ジャムスタックチョットデキル !! ナカノ!!デプロイ完了までの長時間化についてただ、過去のページや大量のバイナリ(画像やPDF)もすべてNuxtで抱えるため、デプロイが完了するまでに45〜50分程度かかってしまう。→ Nuxt.jsが関連する動作確認をしたい時だけ、シェルスクリプトで動作確認に必要のないファイル(PDFなど)を削ってからデプロイする。43
ジャムスタックチョットデキル !! ナカノ!!デプロイ完了までの長時間化についてただ、過去のページや大量のバイナリ(画像やPDF)もすべてNuxtで抱えるため、デプロイが完了するまでに45〜50分程度かかってしまう。→ Nuxt.jsが関連する動作確認をしたい時だけ、シェルスクリプトで動作確認に必要のないファイル(PDFなど)を削ってからデプロイする。→ 45〜50分から10分に短縮44
ジャムスタックチョットデキル !! ナカノ!!ここまでのまとめ●ビルド時のエラーを回避するビルドに含みたくないパスはignoreに登録する●不完全なデプロイを防ぐ500エラーを検知したら異常終了させる●デプロイの長時間化Nuxt.jsの動作だけを見たい場合は不要なバイナリをデプロイさせない45
ジャムスタックチョットデキル !! ナカノ!!3.プロジェクトを通して46
ジャムスタックチョットデキル !! ナカノ!!プロジェクトを通してのふりかえり- 難しかった点- 良かった点47
ジャムスタックチョットデキル !! ナカノ!!プロジェクトを通してのふりかえり- 難しかった点- 良かった点48
ジャムスタックチョットデキル !! ナカノ!!難しかった点インフラ面で本番環境との差があることで、エラー発生時に調査に時間がかかったり、手戻りがあった。49
ジャムスタックチョットデキル !! ナカノ!!難しかった点QAエンジニアが書いてくれたテストコードで下地はできていたものの、開発期間の兼ね合いもあり、実装者側で書くE2Eテストコードの量が少なかった。50
ジャムスタックチョットデキル !! ナカノ!!難しかった点QAエンジニアが書いてくれたテストコードで下地はできていたものの、開発期間の兼ね合いもあり、実装者側で書くE2Eテストコードの量が少なかった。ただし本番環境を再現しきれなかったので、書けたとしてもテストの妥当性に疑問が残る…。51
ジャムスタックチョットデキル !! ナカノ!!難しかった点commitごとにCIを回してのデプロイフローを取ると、今度はデプロイ完了までの時間と、テスト完了までの時間を合わせると1時間ほどかかることを考えると難しい。。52
ジャムスタックチョットデキル !! ナカノ!!プロジェクトを通してのふりかえり- 難しかった点- 良かった点53
ジャムスタックチョットデキル !! ナカノ!!良かった点エラー対応を通じて、ドキュメントに書かれていないような挙動を把握しながら実装することで、Nuxt.jsの理解を深めることが出来た。54
ジャムスタックチョットデキル !! ナカノ!!良かった点今まで経験したPJではなかったが、QAエンジニアが序盤からアサインされていたのも一つのポイントだった。主に静的移行したページの差分・リンク切れチェックや、CMS連携のテスト、その他細かいサポートをしてもらえたことで開発エンジニアの負担が減った。55
ジャムスタックチョットデキル !! ナカノ!!4.まとめ56
ジャムスタックチョットデキル !! ナカノ!!まとめ- ドキュメントを読むだけではわからない場合、フレームワーク内で使われているモジュールを理解しながら制作を行うことも時には必要- QAエンジニアが序盤から参加することで、PJそのものに対してキャッチアップの時間を取ることができ、開発エンジニアとのコミュニケーションコストを減らすことができた57