EAS Hosting を使えば、フルスタックの Expo アプリを簡単にデプロイできます。expo-server、middleware サポート、改善された Cloudflare 統合などの新機能を紹介します。
概要
今年初めに、Expo Router を使った Web と API エンドポイントを簡単に公開するための取り組みとして、EAS Hosting をリリースしました。EAS Hosting は、Expo アプリを API エンドポイントや Web にシームレスに接続し、初日から実用的な機能を備えたアプリをデプロイできる、最も合理化された方法だと考えています。デプロイを気にせずに運用できるように、最初から次のような基本機能を備えることを目指しました:
- Console API と統合された詳細なリクエストログ(プレビューと本番の両方でログメッセージを追跡)
- API ルートで未捕捉のエラーが発生した際のグループ化されたクラッシュレポート
- エンドポイント呼び出しの方法や API ルートのパフォーマンスを把握できるプラットフォーム別の豊富なメトリクス
リリース以降、私たち自身も EAS Hosting でサービスを構築してきました。たとえば Expo Launch は、Expo、EAS Hosting、EAS Workflows だけで構築されています。まだ始まったばかりで、今後の変更や機能拡張により、EAS Hosting があらゆる Expo プロジェクトにとって明白な選択肢になるよう進めています。
expo-server ランタイム API
Expo SDK 54 では、expo-server ライブラリを導入しました。このライブラリは、以前は API ルートで利用できなかった重要な API を提供します。例:
import { StatusError , deferTask , origin , environment } from 'expo-server';
export async function GET(request: Request, { post }: Record<string, string>) {
if (!post) {
throw new StatusError(404, 'No post found');
}
if (post === 'index') {
const target = new URL('/help', origin() ?? request.url);
throw Response.redirect(target, 302);
}
deferTask(async () => {
logAnalyticsDatapoint(...);
});
const env = environment();
return Response.json({ isStaging: env === 'staging' });
}
Fetch や一般的な Web API にはタスクスケジューリングの標準化がないため、ctx.waitUntil(promise) のような API がランタイムにより提供されることがあります。expo-server はサーバー側コードのどこからでも呼べる、タスクスケジューリング用の簡単な関数を 2 つ提供します。また、origin() や environment() といったパターンや、任意のサーバー側コードの箇所で StatusError を投げられる機能は、Expo Launch を EAS Hosting で構築する際に欠けていると感じていたものです。
expo-server は @expo/server パッケージに代わるもので、EAS Hosting に限らない他のサーバーランタイムやプロバイダ向けのアダプタも含んでいます。ランタイムやプロバイダ間の機能を統一し、Expo アプリ内の API ルートやサーバーコードがベンダーロックインを感じないようにすることを目指しています。
expo-server の API の詳細は API Routes のドキュメントページを参照してください。
Expo Router の middleware
これまで Expo Router に middleware サポートがなかったことは大きな制約であり、API ルートの創造的な利用方法を妨げていました。Expo SDK 54 では実験的に middleware のサポートを追加しました。middleware は Expo Router の他のサーバー側コードの前に実行される関数であり、expo-server API と組み合わせて使用できます。例えば、すべての API ルートに対する Response ヘッダをカスタマイズする middleware を書けます。
import { setResponseHeaders } from 'expo-server';
export default function middleware(request: Request) {
setResponseHeaders(headers => {
headers.append('Set-Cookie', 'token=123; Secure');
});
}
EAS Hosting における app.json のヘッダ設定
稀に Expo Router と EAS Hosting 両方に影響する設定があることにも気付きました。例としてデフォルトヘッダの設定があります。
{
"expo": {
"plugins": [
[
"expo-router",
{
"headers": {
"Content-Security-Policy": "frame-ancestors deny",
"Set-Cookie": [
"token=123; Secure"
]
}
}
]
]
}
}
この headers 設定は、Expo Router アプリを export した際に設定ファイルが生成され、それを EAS Hosting がピックアップします。
Cloudflare workerd ランタイムの改善
EAS Hosting は Cloudflare Workers を基盤にしており、デフォルトでグローバル展開されます。Cloudflare が構築した workerd ランタイムは WinterTC と Web API 標準に準拠しています。ただし、そのために Node.js の API やモジュールに制約があり、以前はそれらの差を吸収する必要がありました。時間の経過とともに、これらの制約は次第に解消されています。多くの Node.js 向けライブラリが変更なしで Cloudflare Workers 上で動作するようになっています。特に workerd は以下をサポートするようになりました:
- node:http, node:https, node:http2, node:tls
- node:dns
- node:crypto
- node:fs(インメモリファイルシステムと共に)
workerd のこうした着実な進展により、Node.js の知識を損なうことなく Cloudflare Workers 上に構築することに自信を持てるようになり、Node.js ランタイムで普段使うパッケージを置き換える必要が減りました。
大規模での信頼性
EAS Hosting は現在、毎週数百万件のリクエストを処理しており、企業やチーム、ユーザーからのフィードバックを取り入れてきました。(たとえば 5 月にはワイルドカードのカスタムドメインやダッシュボード内のデプロイメント用ファイルブラウザを導入しました。)
信頼性の向上と収集したデータポイントにより、Free プランユーザー向けのデプロイ数やデプロイあたりのアセット数の制限を緩和できました。現在は毎日数千件のワーカーデプロイを処理しており、ローンチ以来、デプロイとアセットアップロードの速度改善に取り組んできました。平均デプロイ作成時間は一貫して 1 分未満であり、制限緩和はこの速度や障害率に影響を与えていません。
Hosting の将来に向けた基盤づくり
ここまでの変更は一方向を指し示しています。expo-server ランタイム API、Expo Router の middleware.ts サポート、EAS Hosting 用の app.json 設定などを通じて、今後のロードマップに向けた基盤を整えています。
expo-server は、複雑さやベンダーロックインを増やすことなくサーバー側 API を提供するだけでなく、EAS Hosting 固有の機能や API を提供するための手段にもなります。まずは expo-server ランタイム API によって有効になる blob ファイルストレージの追加を行い、EAS Hosting とシームレスに統合する予定です。さらに、データベース類似の機能や名前空間化された KV ストレージの検討も進めています。
expo-server は任意のサーバーサイドコードで動作するよう設計されており、Server Loader Functions、React Server Functions、React Server Components、Expo Router におけるサーバーサイドレンダリングのサポートといった作業を、API の制約に縛られずに進める自信を与えてくれます。これらの機能の開発はまだ流動的ですが、一部はすでに Expo で実験的プレビューとして利用可能です。
現在、私たちは次の 3 つの整合したロードマップを進めています:
- Expo Router の Web およびサーバー側機能(例:React Server Functions)の安定化
- ストア向けのアプリ配布、ユーザーへの更新配信、API コードの EAS Hosting への並列デプロイ
- expo-server による EAS Hosting のステートフル機能とストレージ API の提供
ぜひ Hosting を試してみてください。皆さんのご意見をお待ちしています。