Closed9

@fastly/next-compute-js を試す

tkc310tkc310

fastlyでnext.jsのホスティング用の機能がリリースされていたので試してみる。
https://www.fastly.com/jp/blog/run-your-next-js-app-on-fastly#@fastly/next-compute-js-のご紹介

知りたいこと

いまのところ Static HTML Exportを利用して pages/xxx/[id].jsx のような動的ルーティングを動かすためには下記の手段が必要になると思っている↓
(getStaticPropsでビルド時にデータは参照せず、マウント後に非同期で取得するケース)

  • vercelを利用する
    static利用が中心だが帯域だけでエンプラ料金になる可能性がある
  • serverless next pluginを利用する or これ相当のデプロイ機構を準備する
    ライブラリの中身を理解する必要がありそう (コードで管理されるためnext.jsの変更によっては、対応することが出てきそう)
  • lambda, cloud functionsなどでルーティングのみ動的に解決する
    ルーティング層のメンテが必要になりそう
  • 自前でサーバを立てて $ next build && next start で動かす (next exportを利用しない)
    サーバのメンテナンスを行う必要があり graceful shutdownなどにも配慮する必要が出てくる
    (custom serverでシグナルのハンドリングを行う)

上記のようにvercelを利用するか自前でサーバーを立ててメンテナンスをする必要が出てくるため大変な印象がある。
(これが理由でnuxt.jsを選んでいるプロジェクトも多いのかな..?と想像している)

前述のリリース記事には オリジンサーバーも必要ありません という記載があり、vercel以外の選択肢でサーバのメンテナンスが不要になるのか確認したい。

tkc310tkc310

@fastly/next-compute-js のご紹介

next build コマンドで生成されるのとまったく同じビルド成果物上で動作し、Next.js ランタイムのあらゆる機能を利用できるようにすることを目指して作成されています

この機能はserverless next pluginでAWS上に next start で動くサーバーを立てたときと同じ動作を提供してくれるものらしい。
(恐らくapiやpages単位でedgeサーバ(serverless function)を作ってくれる)

tkc310tkc310

下記リポジトリにサンプルコードを乗せていく↓
https://github.com/tkc310/fastly_next

セットアップ

next-compute-jsの初期化

$ npx @fastly/next-compute-js

./compute-js/ が作成される。
https://github.com/tkc310/fastly_next/commit/8baf4afaead67f7a17ac9920f30b7a29f5464332#diff-98ee2db2c5f09377b9830c208b1bd5a42fd4b07c073fcd823c57ba5f56a2d835

fastly CLIでデバッグ

fastly CLIをhomebrewでインストールする。

$ brew install fastly/tap/fastly
$ cd compute-js
$ fastly compute serve
$ open http://localhost:7676

./compute-js/statics.js が作成される。
https://github.com/tkc310/fastly_next/commit/1c4ddcacf5bebf5176e54da18facebb457f4e8e4#diff-00792f784b8e1f26b346383d674b5e0e69f2a2705a3d176e6b18538f10b8b979

Compute@Edge上で動いた時の挙動をローカルで確認できるコマンドらしい (fastly初心者)

fastly CLIでデプロイ

事前設定

$ fastly profile create test
# ここでtokenの入力が求められる
# => created ~/Library/Application\ Support/fastly/config.toml
$ fastly compute publish
# => created ./fastly.toml

fastly.tomlに個人情報が追記されるがリポジトリではignoreしている。
https://developer.fastly.com/reference/compute/fastly-toml/

CLIで色々聞かれるがすべてenterでデフォルトにした。
なぜか1回目は失敗した..

1回目
Create new service: [y/N] y
Service name: [fastly_next-next-compute-js-app] 
✓ Initializing...
✓ Creating service...
Domain: [xxx.edgecompute.app] 
Backend (hostname or IP address, or leave blank to stop adding backends):

✓ Creating domain 'xxx.edgecompute.app'...
✓ Uploading package...
✗ Activating version...

ERROR: the Fastly API returned 503 Service Unavailable: .
2回目
✓ Initializing...
✓ Verifying package manifest...
✓ Verifying local javascript toolchain...
✓ Running [scripts.build]...
✓ Creating package archive...
SUCCESS: Built package (pkg/package.tar.gz)
✓ Uploading package...
✓ Activating version...
Manage this service at:
        https://manage.fastly.com/configure/services/xxx
View this service at:
        https://xxx.edgecompute.app

CLIの出力にデプロイ先のURL https://xxx.edgecompute.app に無事アクセスができ、
next build && next start と同じ内容が表示された。

npm scriptsにfastly CLIのコマンドを追加しておく
https://github.com/tkc310/fastly_next/commit/2183075ac8412c8aa913fc8ea98da24676dd3b97

tkc310tkc310

ダイナミックルーティングの挙動を確認する

serverless next pluginと同様にedgeサーバを作成していそうなため、
できると思うが一応試してみる。

動的ルーティングを行うpagesとダミーデータを返すapiを追加

  • api/
    • posts/
      • index.ts
      • [id].ts
  • pages/
    • posts/
      • index.tsx
      • [id].tsx

これでデプロイ結果を見る (よく考えたらドメインは公開しても問題ないため貼っておく)

途中で気づいていたけど当たり前に動いた😇

結論

  • @fastly/next-compute-js を利用すればvercelを利用しなくても自前でサーバーを用意せずに next.js が利用できる。
  • デフォルトでedgeサーバが利用されるためパフォーマンスも良い
  • 価格は調査する必要がある (vercelよりは優位性がある価格だと信じている)
  • 静的ホスティングができればもっと安くなるはずなので続報を待つ
tkc310tkc310

@fastly/compute-js-static-publish

api routes は $ next export 時に怒られるため削除
https://github.com/tkc310/fastly_next/commit/3e466a3e4225e56c7740d47032070038ea000534

$ npm run build
# => .next/ の生成
$ npm run export
# => out/ に静的ホスティング用のファイルが出力される

下記に沿って進める↓
https://github.com/fastly/compute-js-static-publish#how-it-works

上のセクションで作成した compute-js/ を削除してから下記を実行

$ npx @fastly/compute-js-static-publish --preset=next
# => created compute-js/
$ cd compute-js
$ npm i
$ fastly compute serve
$ open http://localhost:7676

ローカルでは詳細ページが404になる。

新しく compute service をfastlyの管理画面から追加しておく。
./compute-js/fastly.tomlservice_id を作成したものに書き換える。

$ fastly compute publish

やはり詳細ページは404になる..
[id].html のルーティングが解決できていない。
(next/routerでのspa遷移はできているが直接URLを叩いてアクセスはできない)

tkc310tkc310

compute-js/index.js でルーティング処理が記載されていたため、
下記のように変更したら詳細ページのURLも解決できた↓
https://github.com/tkc310/fastly_next/commit/f2894a17e014ce29656e86d1456ed54c22930eaa

ただ、ルーティングのメンテが必要になるため最初の問題に帰結する 😇
https://reasonably-shining-rhino.edgecompute.app/posts/uuid-1

issueを作ったが2つ目なので次の記事を待った方が良さそうな気がしてきた。
https://github.com/fastly/compute-js-static-publish/issues/2

tkc310tkc310

上記のissueに回答をいただいた。
https://github.com/fastly/compute-js-static-publish/issues/2#issuecomment-1285093535

やはりnext exportで出力されたコンテンツを静的ホスティングする場合に、プレビルド時に解決されないダイナミックルーティングはサポート外らしい。
エッジと合わせて新しく出たサービスだったので、ルーティングが自動解決される仕組みも期待していた。
(vercelも自サービスを使ってほしいはずなので、今後next.js自体でのサポートもされないと予想される)

とはいえ @fastly/next-compute-js に関しては next start で動かす際のホスティング候補にfastlyのcompute@edgeが加わったため、インフラコスト・敷居を下げてくれてくれそうだと思う。

fastlyはCDNとしてのキャッシュパージの仕組みも充実しているため、メンテナンスやチューニングフェーズでの移行も踏まえると少し高くてもawsやgcpに自前でサーバー(+ストレージ, サーバレス関数)を用意するよりは中長期的にコストも回収できると思っている。
(値段は比較していない)

このスクラップは2022/11/18にクローズされました