Backブログに戻る

Next.js 9.4

Next.js 9.4では、React Fast Refresh、インクリメンタル静的再生成 (ISR)、新しい環境変数サポート、組み込みFetchなどが導入されました!

本日、Next.js 9.4のリリースを発表できることを嬉しく思います。主な新機能は以下の通りです:

Fast Refresh

Fast Refreshは、Reactコンポーネントの編集に対して即座にフィードバックを提供する新しいホットリロード体験です。Next.js 9.4以降のすべてのプロジェクトでデフォルトで有効になっています。

ホットリロードは長い間存在してきましたが、歴史的に非常に脆弱だったため、デフォルトで有効にするのは困難でした。このため、Next.jsは以前、アプリケーションの状態全体をリセットする簡易的なホットリロードを実装していました。

従来のホットリロード実装は、コンパイルエラーやランタイムエラーに弱く、CSSやJavaScriptの編集時にタイプミスがあるとアプリケーション全体をリロードしていました。これは最適ではなく、開発の流れを妨げるものでした。

Fast RefreshはReact自体(React Refresh経由)に深く統合されており、Next.jsがReactコンポーネントツリーに対して予測可能な精密な更新を行えるようになります。

つまり、Next.jsは編集したファイルのコードのみを更新し、そのコンポーネントのみを再レンダリングします。コンポーネントの状態は保持されます。これにはスタイル(インライン、CSS-in-JS、CSS/Sass Modules)、マークアップ、イベントハンドラ、エフェクト(useEffect経由)が含まれます。

コンパイルエラーやランタイムエラーが発生しても迅速に回復し、状態を保持しながら編集できるセッション例。

この体験の一環として、エラーオーバーレイを完全に再設計し、より役立つものにすると共に、タイプミスやランタイムエラーに対してアプリケーションが強靭になるようにしました。これには以下が含まれます:

  • 正確なエラー位置(コンパイル前の元の行と列に解決)
  • 文脈に沿ったソースコードスニペットエディタで開く機能
  • 構文エラー修正後の開発セッション再開(アプリケーション状態を保持)
  • 未処理のランタイムエラーが修正されると自動的に解除

この機能の実装に多大な貢献をしてくださったDan Abramov氏に感謝します。

インクリメンタル静的再生成 (ベータ)

Next.jsは9.3で静的サイト生成(SSG)メソッドを導入し、明確な目標を掲げました:静的サイトの利点(常に高速、常にオンライン、[グローバルに分散](https://rauchg.com/2020/static-hoisting#hoist-to-the-edge))を得つつ、Next.jsが得意とする動的データの優れたサポートを提供することです。

両方の利点を得るために、Next.jsはインクリメンタル静的生成をサポートし、サイト構築後でも静的コンテンツを更新できます。例えば9.3では、getStaticPathsfallback: trueオプションを導入し、実行時に新しいページを追加できるようにしました。

最近、デモを作成し、Next.jsがこの方法で無限のページを静的に事前レンダリングできることを示しました。

本日、インクリメンタル静的再生成(ベータ)も導入します。これはトラフィックが流入する際にバックグラウンドでページを再レンダリングすることで既存ページを更新する仕組みです。stale-while-revalidateに着想を得たこの機能により、トラフィックは中断なく静的に提供され、新しく構築されたページは生成完了後にのみプッシュされます。

pages/blog/[slug].js
export async function getStaticProps() {
  return {
    props: await getDataFromCMS(),
    // ページの再生成を試みる条件:
    // - リクエストが入った時
    // - 最大1秒に1回
    unstable_revalidate: 1,
  };
}

SSRとは異なり、インクリメンタル静的再生成により静的サイトの利点を保持できます:

  • レイテンシの急増なし。ページは一貫して高速に提供されます。
  • ページがオフラインになることはありません。バックグラウンドでのページ再生成が失敗しても、古いページはそのまま残ります。
  • データベースとバックエンドの負荷低減。ページは最大でも同時に1回のみ再計算されます。

インクリメンタル機能(ページの追加と遅延更新)とプレビューモードは、next startVercelエッジプラットフォームの両方でそのまま完全にサポートされています。

今後の予定として、以下の2つの追加的なインクリメンタル静的生成機能に対処するRFCを準備中です:

  • 複数ページの一括再生成と無効化(ブログインデックスと特定のブログ投稿など)
  • イベント(CMSのwebhookなど)を監視してユーザートラフィックに先立って再生成

CMS連携例

新世代静的サイト生成の発表に続き、ヘッドレスCMS APIからコンテンツを取得しNext.js HTMLとしてレンダリングする実践的なシナリオを共有したいと考えました。

世界で最高のCMSシステムの開発者と協力しました:ContentfulDatoCMSPrismicSanityTakeShapeなど、さらに増える予定です。

これらの例はすぐに使用可能で、100%オープンソース(MITライセンス)であり、利用可能なベストプラクティスを組み込んでいます:

DatoCMSは組み込みの画像最適化サポートにより完璧な結果を達成しています。

DatoCMSは組み込みの画像最適化サポートにより完璧な結果を達成しています。

また、TinaCMSと協力し、CMSの新しい方向性であるページ内コンテンツ編集について取り組んでいます。ガイドをチェックして、プロジェクトに実装する方法を学んでください。

新しい環境変数サポート

Next.jsを使用する企業からよく寄せられるフィードバックは、環境変数がいつブラウザバンドルにインライン化され、いつNode.js環境でのみ利用可能になるかが不明確だという点でした。

本日、このプロセスを合理化する2つの完全な後方互換機能を発表します。

まず、環境変数にNEXT_PUBLIC_プレフィックスを付けることで、ブラウザに環境変数を公開できるようになりました。この環境変数が使用されると、ブラウザのJavaScriptバンドルにインライン化されます。

これらの変数を公開するためにnext.config.jsを追加してenvキーを設定する必要はもうありません。

pages/index.js
// 環境変数はブラウザに公開されます
console.log('アプリケーションのバージョン', process.env.NEXT_PUBLIC_VERSION);
 
export default function HomePage() {
  return <h1>Hello World</h1>;
}

2つ目の変更点は、Next.jsがデフォルトで.envファイルの読み込みをサポートするようになったことです。これにより、開発用と本番用の環境変数を簡単に定義できます。

.envファイルの読み込みについて詳しくは、環境変数ドキュメントをご覧ください。

これらの新機能により、環境変数の使用は以下の規則に従って簡素化されます:

  • 環境変数はデフォルトでNode.js環境でのみ利用可能
  • NEXT_PUBLIC_プレフィックスが付いた環境変数のみブラウザに公開

改良された組み込みFetchサポート

Next.js 9.1.7で、ブラウザでのfetch() APIのポリフィルを発表しました。本日、このポリフィルがNode.js環境にも拡張されました。

実際には、サーバーサイド用のfetchポリフィル(isomorphic-unfetchnode-fetchなど)を使用する必要はもうありません。Next.jsがすべての環境で自動的にfetch()を提供します。

例えば、Next.jsのビルド時に実行されるgetStaticPropsを使用する場合:

pages/blog.js
export async function getStaticProps() {
  // isomorphic-unfetchからfetchをインポートする必要はもうありません
  const res = await fetch('https://.../posts');
  const posts = await res.json();
 
  return {
    props: {
      posts,
    },
  };
}
 
function Blog({ posts }) {
  // 投稿をレンダリング...
}
 
export default Blog;

統合Web Vitalsレポート

先週、Google ChromeチームはCore Web Vitalsを発表しました。Core Web Vitalsは、優れたWeb UXを提供するための重要な品質指標であり、有名なLighthouseレポートの基盤となっています。

これらのメトリクスを追跡することは、ウェブサイトやウェブアプリケーションを可能な限り高速に保ちたい場合に非常に有用です。これはNext.jsのコア目標の1つでもあります。

Chromeチームは、開発者がページのパフォーマンスを視覚的に確認できるCore Web Vitals Chrome拡張機能をリリースしました。

本番環境のウェブアプリケーションを構築する際には、訪問者や(潜在的な)顧客にとってサイトがどのように機能しているかを知りたいと思うでしょう。また、これらのメトリクスの改善や退化を時間をかけて追跡し、変更が対象ユーザーに意図した影響を与えているかどうかを確認したい場合もあるでしょう。

Core Web Vitalsを分析サービスに報告するのを支援するため、Googleとの協力のもと、pages/_app.jsからエクスポートできる新しいメソッドreportWebVitalsを導入しました:

pages/_app.js
// 報告が必要なすべてのメトリクスに対して1回呼び出されます
export function reportWebVitals(metric) {
  // これらのメトリクスは任意の分析サービスに送信できます
  console.log(metric);
}
 
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}
 
export default MyApp;

このメソッドを分析サービスと組み合わせて使用するには、ドキュメントの「結果を分析に送信」セクションを参照してください。Core Web Vitalsについて詳しく知りたい場合は、web.dev/vitalsをご覧ください。

絶対インポートとエイリアス

大規模なプロジェクトで作業している場合、import文が../../../スパゲッティになることがあります:

import Button from '../../../../components/button';

このような場合、相対インポートの代わりに絶対インポートを使用したいと思うかもしれません。componentsディレクトリがルートにあると仮定すると、import文は次のようになります:

import Button from 'components/button';

Next.js 9.4では、JavaScriptとTypeScriptプロジェクトの両方で絶対インポートの設定が非常に簡単になりました。必要なのは、jsconfig.json(JSプロジェクト)またはtsconfig.json(TSプロジェクト)baseUrl設定を追加することだけです。

jsconfig.json / tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "."
  }
}

これにより、.(ルートディレクトリ)からの絶対インポートが可能になります。また、VSCodeや他のエディタとの統合もサポートしており、コードナビゲーションや他のエディタ機能が利用できます。

注: 以前に絶対インポートを有効にするためにWebpackのモジュールエイリアス設定を変更していた場合、その設定は削除できます。

さらに、Next.js 9.4はpathsオプションもサポートしており、カスタムモジュールエイリアスを作成できます。例えば、以下の設定によりcomponents/design-systemの代わりに@/design-systemを使用できます:

jsconfig.json / tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/design-system/*": ["components/design-system/*"]
    }
  }
}

そして、エイリアスを次のように使用できます:

// 'components/design-system/button'をインポート
import Button from '@/design-system/button';

pathsを指定する場合はbaseUrlも指定する必要があります。pathsオプションについて詳しくは、TypeScriptドキュメントをご覧ください。

設定可能なSassサポート

Next.js 9.3で組み込みSassサポートが導入された際、一部のユーザーからSassコンパイラを設定したい(例えばincludePathsを設定したい)というフィードバックがありました。

これはnext.config.jssassOptionsキーを使用することで可能になりました:

next.config.js
const path = require('path');
 
module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')],
  },
};

改良されたログ出力

コマンドライン出力をより一貫性のあるものに再設計し、デプロイURLや開発サーバーの起動待機などの重複データを減らしました。また、メッセージタイプの間隔を統一し、行ごとにジャンプしなくなりました。

9.4以前のバージョンでnext devを実行した場合

9.4でnext devを実行した場合

コミュニティ

Next.jsの採用が継続的に成長していることを嬉しく思います:

  • 1066人以上の独立したコントリビューターが参加しています。
  • GitHubでプロジェクトは48,000回以上スターを獲得しています。

GitHub DiscussionsでNext.jsコミュニティに参加してください。Discussionsは他のNext.jsユーザーとつながり、質問できるコミュニティスペースです。

Next.jsを使用している場合は、ぜひプロジェクトURLを共有してください。

このリリースを形作るのに役立ったコミュニティとすべての外部フィードバックと貢献に感謝します。