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

2019年10月7日(月)

Next.js 9.1

投稿者

本日、`src` および `public` ディレクトリのサポートを含む Next.js 9.1 を発表できることを嬉しく思います。

このリリースの新機能

このリリースのプレビュー

  • 組み込みの CSS サポート: アプリケーションは、グローバル CSS をインポートし、開発ホットリロードと、高度な本番環境での最適化、コンパイル、ポリフィルを活用できるようになります。
  • 静的エラーページ: 可用性(CDN)を向上させるために、予想されるエラーページ(404 など)を静的にエクスポートします。
  • モジュール/ノーモジュール: エバーグリーンブラウザーで実行しているエンドユーザーに、より小さな JavaScript バンドルを送信します。
  • 改善されたバンドル分割: エンドユーザーへの送信バイト数を削減し、TTI とページ遷移速度を向上させます。大きなライブラリチャンクもデプロイ全体で長期的にキャッシュされます。

常にそうであるように、これらの利点がすべて下位互換性があるように努めています。更新に必要なのは、次のコマンドを実行することだけです。

ターミナル
npm i next@latest react@latest react-dom@latest

アプリケーションが Next.js 9 より前のバージョンである場合は、アップグレードガイド を参照して、アップグレードに必要な変更を確認してください。

前回のメジャーリリース以降、TikTokヒルトンElasticRealtor、および JW Player などの企業が Next.js でローンチしているのを見て嬉しく思っています。詳細については、ショーケース をご覧ください!

src ディレクトリのサポート

Next.js には、すべてのファイルが個別のルートになる特別な `pages` ディレクトリがあります。このディレクトリは、設定よりも規約に従うというアプローチに従い、Next.js アプリケーションのルートにある必要があります。

Next.js を使用している企業と話し合い、いくつかのクローズドソースコードベースを調査した結果、開発者が望んでいた一般的なパターンとして、コード用の `src` ディレクトリを用意し、その中に `pages` ディレクトリを含めることがわかりました。

Next.js 9.1 から、アプリケーションのルートに `pages` ディレクトリを作成する代わりに、`src/pages` ディレクトリを作成できるようになりました。

`src` ディレクトリの使用はオプションであり、すでにこの標準が整備されている会社の場合に対応できます。

The pages folder in the src directory directory
src ディレクトリ内の pages フォルダーディレクトリ

public ディレクトリのサポート

`pages` ディレクトリに加えて、Next.js には `static` という別の特別なディレクトリがあります。このディレクトリのファイルは、`/static` ルートにマッピングされます。

たとえば、`static/my-image.png` は `/static/my-image.png` にマッピングされます。

この規約は、Next.js の最初のリリース以来うまく機能しており、特に問題はありません。

しかし、時間の経過とともに、`/static` では Web アプリケーションに必要なすべてをカバーできないことがわかりました。たとえば、`robots.txt` はドメインのルートから提供する必要があります。

Next.js 9.1 から、`public` という新しいディレクトリを導入します。

`public` ディレクトリ内のファイルはすべて、ドメインのルートにマッピングされます。

たとえば、`public/robots.txt` は `/robots.txt` にマッピングされます。

`public` は `static` ディレクトリのユースケースもカバーするため、同じ機能を持つ `public/static` フォルダーを作成することを優先して、`static` ディレクトリを非推奨にすることにしました。

これまでと同様に、後方互換性を維持するように努めています。そのため、staticディレクトリは引き続き動作しますが、非推奨のメッセージが表示されます。

近日公開

以下の機能は現在、実験的なフラグの下にあり、最終的な実装が完了次第リリースされます。

組み込みCSSサポート

現在、Next.jsにはstyled-jsxと呼ばれるCSS-in-JSソリューションが組み込まれています。このソリューションは、個々のReactコンポーネントのスタイリングには適しています。

しかし、企業と話をしていると、既存のCSSをベースとしたスタイリングやデザインシステムを再利用する必要性が共通してあることがわかりました。

一般的に、これはCSSインポートのサポートを追加するためにnext-cssプラグインを追加することを意味します。

Next.jsユーザーの約50%がこのプラグインをアプリケーションに追加していることがわかりました。

この広範な使用状況のため、CSSインポートの組み込みサポートを追加し、開発中のスタイルの自動リロードや、これまでnext-cssプラグインでは不可能だった本番環境での最適化を行います。

初期の実装は現在、本番環境のNext.jsアプリケーションでテストされています。

グローバルCSSインポートが最初に導入されます。

pages/_app.js
// Global styles can be imported from _app.js
import '../styles/global.css';
import App from 'next/app';
 
export default App;

グローバルCSSインポートの後、.module.css拡張子を通してCSSモジュールのサポートを導入します。

pages/index.js
// Scoped styles are imported through .module.css
import styles from '../styles/index.module.css';
 
export default function HomePage() {
  return <h1 className={styles.heading}>Hello World</h1>;
}

これにより、CSSインポートを使用する際に、開発者エクスペリエンスを大幅に向上させることができます。

現在進行中の作業の詳細については、GitHubのRFCで確認できます。

静的エラーページ

Next.jsには、エラーが発生したときにレンダリングされる特別なページがあり、このページは内部的に/_errorと呼ばれています。このページは、Reactコンポーネントをエクスポートするpages/_error.jsファイルを作成することで、ユーザーがカスタマイズできます。

レンダリングされるエラーは、一般的に、予期されるエラーと予期しないエラーの2つのケースに分けられます。

予期されるエラーは、たとえば、404ページです。

予期しないエラーは、たとえば、getInitialPropsまたはReactツリーのレンダリング中にエラーがスローされた場合で、500をレンダリングします。

一般的に動的にレンダリングする必要がないため、予期されるエラーに対して自動静的最適化を追加する予定です。

ユーザーがこれらのページを動的にレンダリングしたい場合はオプトアウトできますが、デフォルトでは404が静的ページになります。これにより、serverターゲットを使用する場合はサーバーの負荷が軽減され、serverlessターゲットを使用する場合はコストが削減されます。

ページを静的にするもう1つの利点は、CDNを使用する際に自動的にキャッシュできることです。

Google Chromeとの連携

Next.js 9の発表で共有したように、Google ChromeチームはNext.jsの改善にリソースを投資しており、すべてのNext.jsアプリケーションの大規模なパフォーマンス向上を実現するために、複数の取り組みを行っています。

このコラボレーションの詳細については、Next.js 9の発表を参照し、React RallyでのNicole Sullivanによる講演をご覧ください。

Module / Nomodule

Next.jsでコードを書くときは、一般的に「モダン」なJavaScriptを書きます。最新の安定した機能をすべて使用でき、Next.jsはBabelを使用してコードをコンパイルすることで、これらの機能が自動的に変換またはポリフィルされるようにします。

現時点では、これらのJavaScript機能の多くがほとんどのブラウザでサポートされています。ただし、一般的には(Next.jsを含む)、コードはアプリケーションがサポートするすべてのブラウザで実行される単一のJavaScriptバンドルとして出荷されます。

Next.jsの場合、これはモダンなJavaScriptをInternet Explorer 11と互換性のある形式にコンパイルすることを意味します。

たとえば、現在、Next.jsはasync/await構文のポリフィルを提供する必要があります。これは、async/awaitをサポートしていないブラウザでコードが実行されると、コードが壊れる可能性があるためです。

古いブラウザを壊さないようにしながら、新しい構文をサポートするブラウザにモダンなJavaScriptを送信するために、Next.jsはmodule/nomoduleパターンを利用します。module/nomoduleパターンは、最新のブラウザに最新のJavaScriptを提供しながら、古いブラウザがポリフィルされたES5コードにフォールバックできるようにする信頼性の高いメカニズムを提供します。

この新機能は現在、複数の大規模なNext.jsアプリケーションで本番環境でテストされており、実際のデータを収集しています。これらのテストの結果は有望であり、この変更によるパフォーマンスの向上に関する詳細については、近日中に共有されます。

初期結果の例として、Next.jsで組み込みのmodule/nomoduleサポートを有効にする前後のバンドルサイズに関するNatalie Marlenyによる比較があります。

バンドル分割の改善

Next.jsには現在、ページをインタラクティブにするためにロードする複数のJavaScriptバンドルがあります。最も注目すべきは次のとおりです。

  • ページJavaScriptバンドル。
  • 共通のJavaScriptを含むファイル。
  • Next.jsクライアントサイドランタイムバンドル。
  • 動的インポート(一般的にnext/dynamicを通して追加されます)。

ページをインタラクティブにするには、これらのすべてのバンドルをロードする必要があり、すべてがブラウザでReactを起動できるように相互に依存しているためです。

これらのバンドルはReactを起動するためにロードする必要があるため、できるだけ最適化され、アプリケーションの残りの部分から過度に多くのコードをダウンロードしないことが重要です。

このため、ページ間で共通のJavaScriptを保持するcommonsバンドルがあります。commonsを生成するための現在のバンドル分割戦略の計算は、比率ベースのヒューリスティックに基づいています。モジュールがすべてのページの50%で使用されている場合、それは共通モジュールとしてマークされます。

ただし、アプリケーションはさまざまな部分で構成される可能性があります。たとえば、マーケティングページ、ブログ、ダッシュボードなどです。ダッシュボードと比較してマーケティングページが多数ある場合、commonsの計算では、マーケティングページに対してより最適化された結果が得られます。

私たちの目標は、1つのアプリケーションでこれら両方を同時に最適化することです。

Alex Castleは、複数のファイル、特に多くのページが関与する場合に、より最適化されたcommonsチャンキングを可能にする、新しいレイヤーのチャンキング(別のJavaScriptファイルの作成)を定義しました。

module/nomoduleサポートと同様に、改善されたバンドル分割は、本番環境で複数の大規模なNext.jsアプリケーションでテストされており、実際のデータを収集しています。これらのテストの結果と、この変更によるパフォーマンスの向上に関する詳細については、別のブログ記事で近日中に共有されます。

コミュニティ

すべてのNext.jsアプリケーションのパフォーマンスを向上させる今後の変更に興奮しています。

さらに、Next.jsコミュニティはまだ拡大しています。

  • 少なくとも1回のコミットを完了したコントリビューターが800人以上います。
  • GitHubでは、プロジェクトが41,350回以上スターされています。
  • examplesディレクトリには、210以上のサンプルがあります。

Next.jsコミュニティには、現在11,250人以上のメンバーがいます。ぜひご参加ください!

このリリースを形作るのに貢献してくださったコミュニティの皆様、そして外部からのフィードバックや貢献に感謝いたします。