Fastly で Next.js アプリケーションを実行
Fastly の新しい next-compute-js ライブラリを使用することで、Compute@Edge プラットフォーム上で Next.js アプリケーションをホストできるようになりました。これにより、Next.js 開発者のエクスペリエンスが向上し、圧倒的なスピードを誇る Fastly のグローバルエッジネットワークのメリットが得られます。オリジンサーバーも必要ありません。
Next.js は広く普及している JavaScript ベースのサーバーフレームワークで、開発者に優れたエクスペリエンスを提供します。具体的には、フロントエンドのコードを React で作成できるほか、ごくわずかな設定で本番環境に必要な優れた機能 (ハイブリッドの静的レンダリングとサーバーレンダリング、スマートバンドル、ルートプリフェッチなど) を直感的にセットアップできる便利さを備えています。
Next.js を使用する理由
Next.js などのフレームワークは、最先端のWebサイトを構築するのに非常に便利です。早速ですが、React で「Hello, World!」のコンポーネントを作成し、Webサイトのルートから配信してみましょう。まずは Node.js が必要です。ディレクトリを作成し、npm を使用していくつかの依存関係をインストールします。
mkdir my-app
cd my-app
npm -y init
npm install react react-dom next
コンテンツを保持するためのディレクトリを2つ作成します。
mkdir pages
mkdir public
ここで、このコンポーネントを使用して pages/index.js
にファイルを作成します。
export default function Index() {
return (
<div>Hello, World!</div>
);
};
ファイルを作成したら、開発サーバーを実行します。
npx next dev
そして、Web ブラウザが http://localhost:3000/ にアクセスするようにします。
素晴らしいでしょう?大したことないように見えるかもしれませんが、これは本当によくできています。React を使用して完全な開発環境をセットアップできました。ただ単に pages/index.js
にファイルを作成するだけで、Next.js サーバーによって React コンポーネントがレンダリングされ、その出力がブラウザに表示されたのです。
これで、React の機能をフルに活用できるようになりました。カスタムコンポーネントを作成することも、以前に作成したコンポーネントを使用することも、サードパーティのコンポーネントを読み込むこともできます。さらに、この pages/index.js
ファイルを編集すると、変更内容がホットリロードされるため、開発中にブラウザ内で即時にフィードバックを得ることができます。
Next.js では、規則に従ってパスをルーティングできます。つまり、ファイルシステム内にファイルを配置することで、対応する場所にあるファイルが Next.js によって配信されます。このため、同様のファイルを pages/about.js
に追加すると、http://localhost:3000/about で利用可能になります。パスに動的セグメントが必要な場合も、簡単に追加できます。pages/users/[id].js
(ファイル名に角括弧を含みます) を作成すると、そのファイル内のコンポーネントが、このコンポーネントに渡された props を介して ID を受け取ります。画像、フォント、または robots.txt ファイルなどの静的ファイルを配信したい場合は、それらのファイルを public
という名前のディレクトリ内に配置するだけでそのまま配信されます。
Next.js には、多くの機能が用意されています。CSS のビルトインサポート、レイアウト、サーバーサイドレンダリング、MDX のサポートなどはほんの一例です。こうした機能の多くは、ほとんど設定が不要です。Next.js では、JavaScript ファイルを pages/api/ に配置することで、API Routesundefined を使って、JavaScript で書かれたお客様の API にルーティングすることも可能です。
本番環境に移行する準備が整ったら、一連の中間ファイルを使ってサイトをビルドします。
npx next build
これにより、サイトの各ページを実行するために必要なファイルがすべてコンパイルされてビルドされ、.next
という名前のディレクトリに配置されます。この場合、コード分割などの適切な最適化が適用されるため、特定のページを読み込む際に、最低限必要な JavaScript のみがブラウザに送信されます。そして、Next.js のサーバーサイドレンダリングによって、利用可能なすべての React コンポーネントのプリレンダリングが行われます。この実装を試みた経験がある方なら、この機能によってどれほど多くの時間を節約できるかご存知だと思います。ここでは .next
で利用できるすべての機能について詳しく説明することはしませんが、.next は非凡な能力を備えています。undefined
サイトの成果物を作成できたら、以下のようにサイトの配信を開始できます。
npx next start
おめでとうございます。最適化されたサイトがローカルの Node.js サーバーで稼働するようになりました。
これは素晴らしいのですが、ご覧のとおり、Next.js は Node.js サーバー上で動作するよう設計されています。動的ランタイム機能を使用しなくても構わない場合は、静的出力ファイルのセットを (<u>next export</u>
を使用して) エクスポートすることもできます。バンドルされたファイルとしてこれらのファイルをアップロードすることで、従来の Web サーバーから配信できます。
しかし、お客様が Fastly を使用している場合はどうでしょう。Fastly は従来の Web サーバーとは異なります。Fastly を介して静的サイトを配信することはもちろんできますが (これに関する耳寄りなニュースを近日中にお届けします!)、Fastly は JavaScript からコンパイルできる Wasm バイナリを実行できます。ということは、Fastly は Next.js のビルド出力を配信できるだけでなく、Compute@Edge を使用してエッジでサーバー側のコンポーネントも実行できるのではないかと思う方もいらっしゃるでしょう。もちろん可能です!
@fastly/next-compute-js のご紹介
ここで、拡大し続ける Fastly の開発ツールライブラリに新たに追加された、最新のツールをご紹介します。next-compute-js は、Compute@Edge プラットフォーム向けの Next.js ランタイムとプロジェクトの基盤を組み合わせて提供します。これは、next build コマンドで生成されるのとまったく同じビルド成果物上で動作し、Next.js ランタイムのあらゆる機能を利用できるようにすることを目指して作成されています (現時点で完全な Node.js ランタイムを必要とする Vercel Edge ランタイムに依存する機能は除きます)。
使い方は非常にシンプルです。ここでは引き続き、上記の例を使います。next build コマンドを実行したら、.next
ディレクトリが作成されるはずです。では、以下のように next-compute-js を実行してみましょう。
npx @fastly/next-compute-js
出力は Compute@Edge アプリケーションが compute-js
の新しいディレクトリで初期化されていることを示します。依存関係がインストールされ、しばらくすると、コマンドプロンプトに戻ります。
これを Fastly の開発サーバーで実行してみましょう。ここでは、Fastly CLI がインストールされていると想定し、単純に fastly compute serve コマンドを実行します。
cd compute-js
fastly compute serve
これだけで、Next.js アプリケーションが Compute@Edge アプリケーションとして動作しています (ただし、お客様のマシン上での話ですが)。では、本番環境に移行したい場合はどうすれば良いでしょうか。答えは「fastly compute publish の使用」です。
# This is equivalent to 'vercel deploy --prebuilt'
# if you were deploying to Vercel.
cd compute-js
fastly compute publish
実際に試してみましょう。以下の2行を Next.js プロジェクトの package.json
ファイルの scripts セクションに追加します。これにより、Next.js プロジェクトをビルドして、テストまたはデプロイするコマンドを、いつでもすぐに利用できるようになります。
{
"scripts": {
"fastly-serve": "next build && cd compute-js && fastly compute serve",
"fastly-publish": "next build && cd compute-js && fastly compute publish"
}
}
本当にこれだけで、このシンプルなツールを使用できます。
next dev
を使用していつも通りに開発します。次に、npm run fastly-serve
でテストし、準備が整ったら npm run fastly-publish
でクラウドにデプロイできます。
オリジンサーバーは必要ないのですか?
必要ありません。next-compute-js によって .next
ディレクトリ全体が Wasm バイナリの一部としてパッケージ化され、お客様のすべてのコンテンツはビジターに最も地理的に近い位置にある Fastly のエッジノードから世界中に配信されるため、Next.js アプリケーション用のオリジンサーバーは不要になります。その結果、最高の開発エクスペリエンスと本番環境パフォーマンスを実現できます。
この仕組みに関心のある方は、Next.js によって提供されている NextServer クラスのカスタム実装をご覧ください。これは、Wasm バイナリから適切なファイルを読み込むことで機能します。
サポートされている Next.js の機能
Fastly では、ほぼすべての機能をサポートしています。
静的ファイルのルーティング
静的および動的にルーティングされる React ページ
ルーター/命令型ルーティング/浅いルーティング/リンク
データなしでの静的生成
静的 props /静的パスを使用したサーバーサイド生成
サーバーサイド props を使用したサーバーサイドレンダリング
クライアントサイドのフェッチと SWR
ビルトイン CSS / CSS モジュール
圧縮 (gzip)
ETag の生成
ヘッダー/書き換え/リダイレクト/国際化ルーティング
レイアウト
フォントの最適化
MDX
カスタムアプリケーション/ドキュメント/エラーページ
API ルート/ミドルウェア
以下の機能はまだサポート対象ではありませんが、今後サポートを開始する予定です。
画像最適化
プレビューモード
プラットフォームの違いにより、現時点では、以下の機能をサポートする予定はありません (しかし、可能性がゼロなわけではありません!)。
エッジ API ルート/ミドルウェア
段階的な静的サイト生成
動的インポート
API ルートでさえも?
はい、API ルートでさえもです。Next.js では、API を JavaScript で作成し、ページの場合と同様にパスディレクトリを使ってこれらの API を利用可能にできます。
実際に試してみましょう。pages/api/hello/[name].js
(ファイル名に角括弧を含みます) にあるプロジェクトにファイルを追加します。
export default function handler(req, res) {
const { name } = req.query;
res.statusCode = 200;
res.end(JSON.stringify({message: `Hello, ${name}!`}));
}
ファイルを追加したら、プログラムを実行します。
npm run fastly-serve
ここで http://127.0.0.1:7676/api/hello/World にアクセスしてみると、以下が表示されます。
{"message": "Hello, World!"}
API をコールするための URL がファイルのパスに直接マッピングされること、および req.query
オブジェクトを介して動的セグメント [name]
の値にアクセスできることが分かります。とてもシンプルです。
API ルートハンドラーに渡されるリクエストオブジェクトとレスポンスオブジェクトについてご説明すると、Fastly では、@fastly/http-compute-js を使用してお客様に Node.js スタイルの req
オブジェクトと res
オブジェクトを提供してから、API ルートリクエストヘルパーを使用してこれらを拡張し、next dev と互換性のあるハンドラーを作成できるようにします。req オブジェクトのストリームインターフェイスは、Compute@Edgeの Request
のボディストリームにつながれます。そして、ハンドラーが res
オブジェクトへの出力の送信を終了すると、送信されたデータがヘッダーやステータスコードと一緒に Response
オブジェクトにパッケージ化され、Compute@Edge による配信が可能になります。
この機能に加え、Fastly がサポートできる Next.js のその他すべての機能を利用できる Compute@Edge は、お客様の Next.js アプリケーションにとってメリットの大きい魅力的なプラットフォームです。
Next.js アプリケーションの新しい拠点
Next.js と Compute@Edge がシームレスに統合され、オリジンサーバーなしで Next.js アプリケーションを Compute@Edge 上でホストできるようになりました。開発プロセスで Next.js の素晴らしい機能のメリットを活用し、世界最速を誇る Fastly のエッジ・コンピューティング・プラットフォーム Compute@Edge で本番環境にデプロイし、グローバルなオンラインプレゼンスを実現できます。
次回のブログ記事では、この記事でも簡単に触れた、@fastly/compute-js-static-publish
を取り上げます。これは、エッジから静的サイト全体を配信することを可能にするツールです。
Fastly は今後も、お客様がエッジでさらに多くのコードを実行し、より迅速に開発することを可能にするツールを構築し続けると同時に、より幅広いツールを利用できる環境作りに取り組みます。皆さまはこれらのツールをお使いでしょうか。また、どのような用途にお使いでしょうか。ぜひ Twitter でお聞かせください。