Help us understand the problem. What is going on with this article?

Next.js 9.4 リリースノート全訳! 段階的な静的再生成、新しい環境変数のサポートなど、見逃せない新機能が目白押し!

本日(5/12)、Next.js 9.4 がリリースされました!
本記事は Next.js 9.4 リリースノート(Next.js 公式ブログ) の和訳です。

私はふだん Next.js で個人開発を行ったりしている者です。
Twitter もやっているのでよかったらフォローおねがいします! :wink: @_thesugar_

よかったら Next.js チュートリアル(公式)の翻訳記事 もどうぞ。

:exclamation: 注意
この翻訳は非公式です。
訳が不正確な部分やその他不備があればお知らせください。
本文中の画像もすべて公式ブログが出典です。

Next.js 9.4

本日は Next.js 9.4 を紹介します。その特徴は次のとおりです。

Fast Refresh

Fast Refresh とは、React コンポーネントに編集を加えたときにすぐにフィードバックを得られる、新しいホットリロード機能です。Next.js 9.4 以降では、あらゆるプロジェクトにおいて デフォルトで利用可能 です。

ホットリローディングは 昔からありました が、デフォルトで有効にしてワークフローに組み込むには、今までの経緯などを見るにあまりにも脆弱 でありました。このため、今までNext.jsでは、アプリケーション全体の状態をリセットするホットリロードの粗い形式を実装していました。

この古いホットリロードの実装はコンパイルエラーやランタイムエラーに耐性がなく、CSS や JavaScript の編集中に一文字でも typo してしまうとアプリケーションの完全なリロードを行ってしまいます。これは最適なものではなく、思考の流れを妨げるものでした。

Fast Refresh は React 自体と深く結びついたもの(React Refresh を介して)であり、そのため Next.js は 予測可能な精度で React のコンポーネントツリーを更新できるのです。

つまり Next.js は編集が行われたファイルのコードのみを更新し、コンポーネントの状態を失うことなく そのコンポーネントだけを再レンダリングするということです。このことはスタイル(インライン、CSS-in-JS、CSS/Sass モジュール)、マークアップ、イベントハンドラ、ならびに副作用(useEffect によるもの)にも当てはまります。

コンパイラーやランタイムエラー(クイックリカバリー付き)および状態を保持する編集機能が特徴の編集セッション(公式ブログ内の動画)

この機能の一部として、エラーのオーバーレイを、より有用かつアプリが typo やランタイムエラーにより耐性のあるものとなるように抜本的に設計しなおしました。これにはたとえば以下のことが含まれますが、これだけに限りません:

  • コンパイル前に、自分が書いたコードの 元々の行と列 を解決した 正確なエラー箇所を表示 します
  • 文脈に関連のある ソースコードスニペットクリックしてエディタで開く ことができます
  • シンタックスエラーが修正されたら、アプリケーションの状態を失うことなく 開発の セッションを再開 します
  • エラーを修正したとき、処理されていないランタイムエラーを 自動的に破棄 します

Incremental Static Regeneration (beta)

Next.js は 9.3 で Static Site Generation(静的サイト生成)の手法を導入しましたが、そのとき明確に定めていたゴールがあります。それは、静的であることの利益(つねに速く、いつもオンラインで、グローバルに分散されている)を享受しながらも、動的なデータについてもしっかりとサポートするということで、それは Next.js が得意とすることでもあります。

両方のいいとこ取りをするために、Next.js は Incremental Static Generation をサポートします。Incremental Static Generation では、サイトを構築した後に静的コンテンツを更新します。たとえば、 9.3 では getStaticPaths において fallback: false オプションを導入し、それによって、実行時に 新しいページ を追加することができるようになりました。

つい最近、Next.js がどのようにして限りない数のページを静的にプリレンダリングするかを紹介する例をまとめました:

Next.js 9.3 以降では、ビルド時に静的生成できる。でも実行時にも静的生成できるんだ。
このデモを見れば @vercel 上で Jamstack がスケールしているのがわかると思う。一日に 5 億もの新しいページを生成しているんだ! static-tweet.now.sh

今日、Incremental Static Regeneration (beta) というものも紹介します。これは、既存のページを更新する メカニズムであり、既存のページへトラフィックが入ってきたときにバックグラウンドでそのページを再レンダーするというものです。stale-while-revalidate にインスパイアを受けていますが、この stale-while-revalidate とは、トラフィックが途切れなく、かつ、いつも静的に提供(サーブ)され、新しくビルドされたページはその生成が完了した後にのみプッシュされるというものです。

export async function getStaticProps() {
  return {
    props: await getDataFromCMS(),
    // ページの再生成を以下のように試みます
    // - リクエストが来たとき
    // - 最大で 1 秒に一度
    unstable_revalidate: 1
  }
}

SSR とは違い、Incremental Static Regeneration を使えば、静的(Static)であることの利点を確実に保持できます。

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

インクリメンタル機能(ページの追加と遅延(lazy)更新)と プレビューモード はどちらもすでに next startVercel edge platform の両方で完全にサポートされていて、追加の設定無くすぐに使い始められます。

次は、Incremental static generation にさらに 2 つ機能を追加するために補足的な RFC を作成しようとしています。

  • 一度に複数ページを再生成して無効にすること(ブログのインデックスとブログの個別の記事のように)
  • ユーザーからのアクセスより前に、イベントを待ち受けて再生成すること(CMS のウェブフックのように)

CMS の例

次世代の静的サイト生成 について発表したすぐ後から、ヘッドレス CMS の API からコンテンツを取得したりそれを Next.js の HTML としてレンダリングするといった、実際の(リアルワールドの)シナリオを共有したいと思っていました。

我々は、世界で最も優れた CMS システムの製作者たちと提携しました。ContentfulDatoCMSPrismicSanityTakeShape などです。

blog.png

上記で例として挙げたものたちは、すぐに使用できて 100 % オープンソースであり MIT ライセンスであるというだけでなく、利用可能なベストプラクティスを取り入れています。

lighthouse.png

DatoCMS は、画像の最適化をビルトインでサポートしているため、申し分のない結果を達成しています。

また、TinaCMS とは CMS のわくわくするような新しい方向性である、コンテンツのページ内編集 についてコラボレーションしています。自分のプロジェクトでページ内編集を実装する方法について知るにはTinaCMS のガイド をチェックしてください。

新しい環境変数のサポート

Next.js を使用している企業から得たフィードバックに共通していたものは、環境変数がいつブラウザバンドルにインライン化されるのか、Node.js 環境でしか利用できないのはいつなのか、がわかりづらいというものでした。

今日は、このプロセスを合理的にする、完全に後方互換性のある 2 つの機能を発表します。

そのうちの一つ目ですが、環境変数をブラウザでも参照できるようにするには、環境変数名を NEXT_PUBLIC_ で始めてください。その環境変数が使われると、ブラウザの JavaScript バンドルにインライン化されます。

もはや、next.config.js を追加してそこに env キーを追加することでこれらの変数をブラウザに公開する…という手順は不要になります。

// pages/index.js

// 以下の環境変数はブラウザに公開される
console.log('My Application Version', process.env.NEXT_PUBLIC_VERSION)

export default function HomePage() {
  return <h1>Hello World</h1>
}

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

.env の読み込みについては 環境変数のドキュメンテーション をご一読ください。

以上の新しい機能は、以下の規約に従うことで環境変数の使用を簡素化します。

  • 環境変数は、デフォルトでは Node.js 環境でのみ利用可能である
  • NEXT_PUBLIC_ で始まる環境変数はブラウザに公開される

ビルトインfetchのサポートの改善

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

実用上は、Next.js がどんな環境においても自動で fetch() を提供してくれるので、もはやサーバサイドフェッチ用のポリフィル(たとえば isomorphic-unfetchnode-fetch)はまったく使う必要がないのです。

たとえば、getStaticProps を使って、ビルド時に Next.js を使って実行される例は以下のようになります。

export async function getStaticProps() {
  // fetch 関数はもはや isomorphic-unfetch からインポートする必要はありません
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts
    }
  }
}

function Blog({ posts }) {
  // posts のレンダー処理・・・
}

export default Blog

統合された Web Vitals レポーティング

先週、Google Chrome チームが Core Web Vitals を導入しました。Core Web Vitals とはウェブにおいて優れた UX を届けるための鍵となるクオリティのシグナルであり、よく知られている Lighthouse レポート もそれに基づいて構築されています。

ウェブサイトやウェブアプリを可能な限り高速化したいのであればこれらの指標を追求することはきわめて有用ですし、それは Next.js の核となる目標の一つです。

core-web-vitals.jpg

Chrome のチームは Core Web Vitals Chrome 拡張 をリリースしました。それを使えば、自分のページのパフォーマンスがどうであるか、開発者用の視覚的なフィードバックを得ることができます。

本番用のウェブアプリを構築するとき、自分のサイトが訪問者や(潜在)顧客に対してどのようなパフォーマンスを発揮しているか知りたいということもあると思います。自分が施した変更が、顧客に対して意図した影響を与えているか確認するために、上記の指標の改善や悪化を、変更前後の時間の変化と合わせて追跡したいと思うかもしれません。

分析サービスへの Core Web Vitals のレポートを支援すべく、Google とのコラボレーション により、reportWebVitals という新しい手法を導入しました。これは pages/_app.js から export できます。

// レポートされる各指標につき一度呼び出されます
export function reportWebVitals(metric) {
  // この指標はどんな分析サービスに送信することもできます
  console.log(metric)
}

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

この手法をあなたが使っている分析サービスと組み合わせて使うにはドキュメントの Sending result to Analytics(分析サービスに結果を送る) というセクションを参照してください。Core WEb Vitals についてもっと知りたい場合は web.dev/vitals を参照してください。

Absolute Imports とエイリアス

大きなプロジェクトで作業をしているとき、import 文が ../../../ というようなスパゲッティ状態になって苦しんだ経験をお持ちの方もいらっしゃるのではないでしょうか。

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

そのようなケースでは、相対パスでインポートを行う代わりに、絶対パスでのインポート が使いたいということもあるでしょう。components ディレクトリがプロジェクトのルートにあると想定して、import 文を次のように書きたいと思うかもしれません。

import Button from 'components/button'

Next.js 9.4 では、JavaScript のプロジェクトにおいても TypeScript のプロジェクトにおいても、絶対パスのインポートはきわめてシンプルに設定することができます。必要なことは jsconfig.json(JavaScript のプロジェクトの場合) あるいは tsconfig.json(TypeScript のプロジェクトの場合)baseUrl の設定を追加することだけです。

// jsconfig.json あるいは tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "."
  }
}

こうすることで .(ディレクトリのルート)から絶対パスでインポートすることができます。また、これは VSCode や他のエディタとも統合されており、コードナビゲーションやその他エディタ機能もサポートしています。

補足: 今まで、絶対パスでのインポートを可能にするために Webpack のモジュールエイリアス の設定を修正していたという方は、その設定はもはや削除してしまって構いません。

さらに、Next.js 9.4 では paths オプションもサポートしており、それにより独自のモジュールエイリアスを作ることができます。例えば、以下のように設定することで components/design-system の代わりに @/design-system と書くことができます。

// tsconfig.json あるいは jsconfig.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 キーを使用することで可能になりました。

const path = require('path')

module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')]
  }
}

ログ出力の改善

コマンドラインの出力をより一貫性のあるものとし、また、デプロイ URL や開発用サーバーが待ち状態にあることなどを重複して出力することを減らすように再設計しました。また、メッセージタイプの間隔を変更し、メッセージ間で一貫性を持たせるようにしました。つまり、行から行にジャンプするということはなくなったということです。

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

log-output-previous.png

9.4 以後のバージョンで next dev を実行したとき

log-output-new.png

コミュニティ

Next.js を採用する人や企業が増え続けていることにワクワクしています。

  • これまでに実人数で 1066 人 以上のコントリビューターがいました。
  • GitHub では、このプロジェクトは 48,000 回 以上スターを付けられています。

GitHub Discussions で Next.js のコミュニティに参加しましょう。Discussions は、他の Next.js ユーザーとつながり、質問をすることができるコミュニティ空間です。

Next.js を使っているのなら、気兼ねなくコミュニティであなたのプロジェクトの URL を共有してください。

このリリースを形成するのに手伝ってくれたコミュニティならびにすべての外部からのフィードバック、貢献に感謝します。

thesugar
東大工学部卒→とある金融機関のR&DチームでAIを開発してたりしてなかったりします。機械学習、フロントエンド開発、純粋関数型言語に興味があります。
https://twitter.com/_thesugar_
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした