Next.js 9
70回のcanaryリリースを経て、Next.js 9をリリースできることを嬉しく思います。以下の機能を搭載しています:
- ビルトイン・ゼロコンフィグTypeScriptサポート: 自動TypeScriptサポートと統合型チェックにより、より確信を持ってアプリケーションを構築できます。
- ファイルシステムベースの動的ルーティング: カスタムサーバーを必要とせず、ファイルシステムを通じて複雑なアプリケーションルーティング要件を表現できます。
- 自動静的最適化: 機能を犠牲にすることなく、デフォルトでServer-Side RenderingとStatic Prerenderingを活用した超高速ウェブサイトを作成できます。
- API Routes: ホットリロードと統一されたビルドパイプラインを活用して、バックエンドアプリケーションエンドポイントを素早く構築できます。
- より多くのプロダクション最適化: ビューポート内プリフェッチングやその他の最適化により、アプリケーションがこれまで以上にレスポンシブになりました。
- 改善されたDX: 最高の開発体験を提供するための、控えめで使いやすい改善。
いつものように、これらすべての利点が後方互換性を保つよう努めています。ほとんどのNext.jsアプリケーションでは、以下を実行するだけです:
npm i next@latest react@latest react-dom@latest
コードベースの変更が必要なケースは非常に少数です。詳細については、アップグレードガイドをご覧ください。
前回のリリース以降、IGN、Bang & Olufsen、Intercom、Buffer、Ferrariなどの企業がNext.jsでローンチしているのを見ることができて嬉しく思います。詳細はショーケースをご覧ください!
ビルトイン・ゼロコンフィグTypeScriptサポート
1年前、Next.js 6は@zeit/next-typescriptというプラグインを通じて基本的なTypeScriptサポートを導入しました。ユーザーは.babelrcをカスタマイズし、next.config.jsで有効にする必要もありました。設定されると、プラグインは.tsと.tsxファイルをNext.jsでビルドできるようになりました。しかし、型チェックは統合されておらず、Next.jsコアから型も提供されていませんでした。これは、リリースと同期が取れない可能性があるコミュニティパッケージをDefinitelyTypedで別途メンテナンスする必要があることを意味していました。
多くのユーザー(既存および新規)と話をする中で、ほとんどの人がTypeScriptの使用に非常に興味を持っていることが明らかになりました。彼らは、既存または新しいコードベースにTypeScriptを簡単に統合するための、より信頼性が高く標準的なソリューションを求めていました。そのため、私たちはTypeScriptサポートをNext.jsコアに統合し、開発者体験を改善し、プロセスをより高速化することに着手しました。
自動セットアップ
Next.jsでTypeScriptを始めるのは簡単です:任意のファイル、ページ、またはコンポーネントを.jsから.tsxにリネームします。そして、next devを実行してください!
これにより、Next.jsがプロジェクトでTypeScriptが使用されていることを検出します。Next.js CLIがReactとNode.jsに必要な型のインストールをガイドします。Next.jsは、まだ存在しない場合、適切なデフォルト設定でtsconfig.jsonも作成します。このファイルにより、Visual Studio Codeなどのエディターで統合型チェックが可能になります。
統合型チェック
Next.jsは開発時とプロダクション用ビルド時の両方で型チェックを処理します。開発中、Next.jsはファイル保存後に型エラーを表示します。型チェックはバックグラウンドで実行され、更新されたアプリケーションとブラウザーで即座にやり取りできます。型エラーは利用可能になると、ブラウザーに伝播されます。
Next.jsは、型エラーが存在する場合、プロダクションビルド(next build)も自動的に失敗させます。これにより、壊れたコードをプロダクションに出荷することを防げます。
TypeScriptで書かれたNext.jsコア
過去数ヶ月間で、コードベースの大部分をTypeScriptに移行しました。これはコード品質を強化しただけでなく、すべてのコアモジュールに型を提供することも可能にしました。例えば、next/linkをインポートすると、TypeScriptをサポートするエディターは許可されたプロパティとそれらが受け入れる値を表示します。
動的ルートセグメント
動的ルーティング(URLスラッグやPretty/Clean URLsとしても知られる)は、Next.jsがリリースされた2.5年前にGitHubで最初に要求された機能の1つでした!この問題は、Next.jsをプログラム的に使用するためのカスタムサーバーAPIを導入することで、Next.js 2.0で「解決」されました。これにより、Next.jsをレンダリングエンジンとして使用し、抽象化と受信URLの特定ページへのマッピングが可能になりました。
ユーザーと話し、多くのアプリケーションを調査した結果、多くがカスタムサーバーを持っていることがわかりました。パターンが浮かび上がりました:カスタムサーバーの最も顕著な理由は動的ルーティングでした。
しかし、カスタムサーバーには独自の落とし穴があります:ルーティングがプロキシではなくサーバーレベルで処理される、モノリスとしてデプロイ・スケールされる、パフォーマンス問題が発生しやすいなどです。カスタムサーバーはアプリケーション全体を1つのインスタンスで利用可能にする必要があるため、これらの問題を解決するServerless環境へのデプロイは通常困難です。Serverlessリクエストはプロキシ層でルーティングされ、パフォーマンスボトルネックを避けるために独立してスケール・実行されます。
さらに、私たちはより良い開発者体験を提供できると信じています!Next.jsの魔法の多くは、pages/blog.jsという名前のファイルを作成すると、突然/blogでアクセス可能なページができることから始まります。なぜユーザーが/blog/my-first-post(/blog/:id)のようなルートをサポートするために、独自のサーバーを作成してNext.jsのプログラム的APIについて学ぶ必要があるのでしょうか?
このフィードバックとビジョンに基づいて、ユーザーがすでに知っていること(pages/ディレクトリ)によって駆動されるルートマッピングソリューションの調査を開始しました。
動的にルーティングされたページの作成
Next.jsは、path-to-regexp(Expressを動かすライブラリ)によって普及したパターンである、基本的な名前付きパラメータを持つルートの作成をサポートしています。ルート/post/:pidにマッチするページの作成は、pagesディレクトリにpages/post/[pid].jsという名前のファイルを作成することで実現できます!
Next.jsは/post/1、/post/hello-nextjsなどのリクエストを自動的にマッチし、pages/post/[pid].jsで定義されたページをレンダリングします。マッチしたURLセグメントは、[角括弧]間で指定された名前でクエリパラメータとしてページに渡されます。
例:以下のページとリクエスト/post/hello-nextjsが与えられた場合、クエリオブジェクトは{ pid: 'hello-nextjs' }になります:
static async getInitialProps({ query }) {
const { pid } = query
const postContent = await fetch(`https://api.example.com/post/${encodeURIComponent(pid)}`)
.then(r => r.text())
return { postContent }
}
複数の動的URLセグメントもサポートされています![param]構文はディレクトリ名とファイル名の両方でサポートされており、以下の例が動作します:
./pages/blog/[blogId]/comments/[commentId].js
./pages/posts/[pid]/index.js
この機能の詳細については、Next.jsドキュメントまたはNext.js Learnセクションをお読みください。
自動静的最適化
Next.jsは約2年前にリリースされたv3で静的ウェブサイト生成のサポートを追加しました。当時、これはNext.jsに追加される最も要求された機能でした。そして正当な理由があります:静的ウェブサイトが高速であることは否定できません!サーバーサイド計算を必要とせず、CDNロケーションからエンドユーザーに即座にストリーミングできます。
しかし、サーバーサイドレンダリングまたは静的生成アプリケーションの選択は二進的で、サーバーサイドレンダリングまたは静的生成のいずれかを選択する必要がありました。中間地点はありませんでした。
実際には、アプリケーションは異なる要件を持つことができます。これらの要件には異なるレンダリング戦略とトレードオフが必要です。例えば、ホームページとマーケティングページは通常静的コンテンツを含み、静的最適化の優れた候補です。一方、プロダクトダッシュボードは、データが頻繁に更新されるサーバーサイドレンダリングの恩恵を受ける可能性があります。
私たちは、ユーザーに両方の世界の最良の部分を提供し、デフォルトで高速にする方法を探求し始めました。どうすれば静的マーケティングページと動的サーバーレンダリングページをユーザーに提供できるでしょうか?
Next.js 9以降、ユーザーは完全にサーバーレンダリングするか、アプリケーションを静的にエクスポートするかの選択をする必要がなくなりました。ページごとに両方の世界の最良の部分を提供します。
自動部分静的エクスポート
ページが静的HTMLに事前レンダリングできるかどうかを自動的に決定するヒューリスティックが導入されました。この決定は、ページがgetInitialPropsを使用してブロッキングデータ要件を持つかどうかによって行われます。
このヒューリスティックにより、Next.jsはサーバーレンダリングページと静的生成ページの両方を含むハイブリッドアプリケーションを出力できます。
ビルトインNext.jsサーバー(next start)とプログラム的API(app.getRequestHandler())の両方が、このビルド出力を透過的にサポートします。設定や特別な処理は必要ありません。
静的生成されたページは依然としてリアクティブです:Next.jsはアプリケーションをクライアントサイドでハイドレートし、完全なインタラクティビティを提供します。さらに、ページがURLのクエリパラメータに依存している場合、Next.jsはハイドレーション後にアプリケーションを更新します。
Next.jsは開発中にページが静的生成されるかどうかを視覚的に通知します。この視覚的アーティファクトはクリックすることで非表示にできます。
静的生成されたページは、Next.jsのビルド出力にも表示されます。
API Routes
Reactアプリケーションを構築する多くの場合、何らかのバックエンドが必要になります。データベースからデータを取得するか、ユーザーが提供するデータを処理する(例:お問い合わせフォーム)ためです。バックエンドが必要な多くのユーザーが、カスタムサーバーを使用してAPIを構築していることがわかりました。そうすることで、彼らはかなり多くの問題に遭遇しました。例えば、Next.jsはカスタムサーバーコードをコンパイルしないため、import/exportやTypeScriptを使用できませんでした。
この理由で、多くのユーザーがカスタムサーバーの上に独自のカスタムコンパイルパイプラインを実装することになりました。これは目標を解決しましたが、多くの落とし穴があります:例えば、不適切に設定された場合、アプリケーション全体でtree shakingが無効になります。
これは疑問を提起しました:Next.jsが提供する開発者体験をAPIバックエンドの構築に持ち込むことができたらどうでしょうか?
本日、APIバックエンドを構築するためのNext.jsからのベストインクラス開発者体験であるAPI routesを導入できることを嬉しく思います。
API routesの使用を開始するには、pages/ディレクトリ内にapi/というディレクトリを作成します。このディレクトリ内の任意のファイルは、他のページファイルがルートにマップされるのと同じ方法で、自動的に/api/<your route>にマップされます。
例えば、pages/api/contact.jsは/api/contactにマップされます。
注意:API RoutesもDynamic Routesをサポートしています!
pages/api/ディレクトリ内のすべてのファイルは、Reactコンポーネントではなく、リクエストハンドラー関数をエクスポートします:
export default function handle(req, res) {
res.end('Hello World');
}
reqはhttp.IncomingMessageを拡張するNextApiRequestを参照します
resはhttp.ServerResponseを拡張するNextApiResponseを参照します
一般的にAPIエンドポイントは、例えばクエリストリング、リクエストボディ、またはクッキーなどの受信データを受け取り、他のデータで応答します。Next.jsにAPI routesサポートを追加することを調査する際、多くの場合ユーザーがNode.jsのリクエストとレスポンスオブジェクトを直接使用していないことに気づきました。代わりに、Expressのようなサーバーライブラリによって提供される抽象化を使用していました。
これを行う理由は、多くの場合、受信データが有用になるために最初に解析する必要があるテキストの形式だからです。そのため、これらの特定のサーバーライブラリは、最も一般的にはミドルウェアを通じて、データを手動で解析する負担を取り除くのに役立ちます。最も一般的に使用されるものは、クエリストリング、ボディ、クッキーの解析を提供しますが、開始するためにはまだいくつかのセットアップが必要です。
Next.jsのAPI routesは、APIエンドポイントの作成ですぐに生産的になれるよう、これらのミドルウェアをデフォルトで提供します:
export default function handle(req, res) {
console.log(req.body);
console.log(req.query);
console.log(req.c