コンテンツへスキップ
ブログに戻る

2020年5月11日月曜日

Next.js 9.4

投稿者

本日、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モジュール)、マークアップ、イベントハンドラ、およびエフェクト(useEffectを介して)が含まれます。

コンパイラおよびランタイムエラー(迅速な回復を含む)と、状態を保持する編集を特徴とする編集セッション。

この体験の一環として、エラーオーバーレイを完全に再設計し、より役立つものにし、アプリケーションがタイプミスやランタイムエラーに強くできるようにしました。これには、以下のものが含まれますが、これらに限定されません。

  • コンパイル前のコードの元の行と列に解決された、正確なエラー位置
  • コンテキストに関連するソースコードスニペットエディタでクリックして開く機能付き
  • 構文エラーが修正された後の開発セッション再開アプリケーションの状態を失うことなく
  • エラーを修正した際に、未処理のランタイムエラーの自動解除

この機能の実装にご尽力いただいたDan Abramov氏に感謝いたします。

Incremental Static Regeneration (ベータ版)

Next.jsは9.3で静的サイト生成方法を導入しましたが、その明確な目標は、Next.jsが知られている動的データの優れたサポートを維持しつつ、静的サイトの利点(常に高速、常にオンライン、グローバル分散)を得ることでした。

両方の利点を最大限に引き出すため、Next.jsはIncremental Static Generationをサポートしており、サイトを構築した後でも静的コンテンツを更新できます。たとえば、9.3ではgetStaticPathsfallback: trueオプションを導入し、ランタイム時に新しいページを追加できるようになりました。

Next.jsがこのようにして無限のページを静的にプリレンダリングできる方法を示す例を最近作成しました

本日、Incremental Static Regeneration (ベータ版)も導入します。これは、トラフィックが来たときにバックグラウンドで既存のページを再レンダリングすることで、既存のページを更新するメカニズムです。stale-while-revalidateにインスパイアされており、これによりトラフィックが中断されることなく常に静的に提供され、新しく構築されたページは生成が完了した後にのみプッシュされます。

pages/blog/[slug].js
export async function getStaticProps() {
  return {
    props: await getDataFromCMS(),
    // we will attempt to re-generate the page:
    // - when a request comes in
    // - at most once every second
    unstable_revalidate: 1,
  };
}

SSRとは異なり、Incremental Static Regenerationは静的サイトの利点を確実に維持します

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

増分機能(ページの追加と遅延更新)、およびプレビューモードは、next startVercelエッジプラットフォームの両方で最初から完全にサポートされています。

次に、追加の増分静的生成機能2つに対処するための補足的なRFCに取り組む予定です。

  • 複数のページを一度に再生成および無効化する(ブログのインデックスと特定のブログ記事など)
  • ユーザーのトラフィックに先行して、イベント(CMSウェブフックなど)をリッスンして再生成する

CMS事例

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

私たちは、世界最高のCMSシステムの一部であるContentfulDatoCMSPrismicSanity、およびTakeShapeのクリエイターと提携しました。今後も増える予定です。

これらの事例は、すぐに使用できるだけでなく、100%オープンソースでMITライセンスであり、利用可能な最良のプラクティスを取り入れています。

DatoCMS achieves impeccable results due to their built-in image optimization support.
DatoCMSは、組み込みの画像最適化サポートにより、申し分のない結果を達成しています。

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

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

新しい環境変数サポート

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

本日、このプロセスを効率化するのに役立つ、完全に後方互換性のある2つの機能を発表します。

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

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

pages/index.js
// The environment variable will be exposed to the browser
console.log('My Application Version', 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環境にも拡張されました。

実際には、Next.jsがすべての環境で自動的にfetch()を提供するため、いかなる種類のサーバーサイドfetchポリフィル(例えばisomorphic-unfetchnode-fetch)も使用する必要がなくなりました。

たとえば、ビルド時にNext.jsを使用して実行されるgetStaticPropsを使用する場合

pages/blog.js
export async function getStaticProps() {
  // fetch no longer needs to be imported from isomorphic-unfetch
  const res = await fetch('https://.../posts');
  const posts = await res.json();
 
  return {
    props: {
      posts,
    },
  };
}
 
function Blog({ posts }) {
  // Render posts...
}
 
export default Blog;

統合されたWeb Vitalsレポート

先週、Google ChromeチームはCore Web Vitalsを発表しました。Core Web Vitalsは、ウェブ上で優れたUXを提供するための重要な品質シグナルであり、その上に有名なLighthouseレポートが構築されています。

これらの指標を追跡することは、あなたのウェブサイトやウェブアプリケーションを可能な限り高速にしたい場合に非常に役立ちます。これはNext.jsの主要な目標の一つです。

Chromeチームは、開発者としてページのパフォーマンスに関する視覚的なフィードバックを得ることができるCore Web Vitals Chrome拡張機能をリリースしました。

本番のウェブアプリケーションを構築する際には、サイトが訪問者や(潜在的な)顧客にとってどのように機能しているかを知ることも重要です。変更がオーディエンスに意図した影響を与えているかを確認するために、これらの指標の改善や後退を時間とともに追跡したい場合もあるでしょう。

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

pages/_app.js
// Will be called once for every metric that has to be reported.
export function reportWebVitals(metric) {
  // These metrics can be sent to any analytics service
  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/*"]
    }
  }
}

エイリアスは次のように使用できます。

// Imports '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をコミュニティと共有してください

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