Closed12

Next.js 12 をざっくり理解

JJJJ

Next.js 12 https://nextjs.org/blog/next-12
以下が大きな変更点

  • Rust Compiler: ~3x faster Fast Refresh and ~5x faster builds
  • Middleware (beta): Enabling full flexibility in Next.js with code over configuration
  • React 18 Support: Native Next.js APIs are now supported, as well as Suspense
  • <Image /> AVIF Support: Opt-in for 20% smaller images
  • Bot-aware ISR Fallback: Optimized SEO for web crawlers
  • Native ES Modules Support: Aligning with the standardized module system
  • URL Imports (alpha): Import packages from any URL, no installs required
  • React Server Components (alpha): Try it today, including SSR streaming
JJJJ

Rust Compiler

Rust 製の SWC を使ったビルド方法に変更された。
これによりビルドが高速化された
https://github.com/swc-project/swc

これは少し前から入っていたが完全にデフォルトで使えるようになったと言う解釈でいいのかな

また fast refresh(yarn devで立ち上げた時の差分ビルド)での最適化をする際にコンソールに出す情報を増やしたっぽい

styled-jsx の変換のための CSS パーサーも SWC のものを使っているっぽい

また babel の設定がある場合は、 自動的に optout されると書いている。例えば styled-components などの人気ライブラリは後々に置き換えていく

また Rust コンパイラーを使った minify も optin することができる。これは Terser よりも 7倍早い。

// next.config.js

module.exports = {
  swcMinify: true
}
JJJJ

Introducing Middleware

Next.js には API Route があり、そこでは Middleware の実装例などがあったがそれが web でも使えるようになったっぽい。
自由に Response を書き換えることができることで以下のようなことができるようになったと書いている

  • Authentication
  • Bot protection
  • Redirects and rewrites
  • Handling unsupported browsers
  • Feature flags and A/B tests
  • Server-side analytics
  • Advanced i18n routing requirements
  • Logging

見た感じ Next.js の Request / Response に対するものなので Landing してきた時の HTML に対して変更を行なったり、 Header を書き換えたりすることが可能になるっぽい。
また Map を持っていれば req.url などを参照することで 特定の path に対しては 401 を返して Basic Auth を促すみたいな実装は比較的簡単に行える気がする。

middleware の実装は pages_middleware.js を配置することで行える

// pages/_middleware.js

export function middleware(req, ev) {
  return new Response('Hello, world!')
}
JJJJ

React 18 Support

React 18 で使える SuspensestartTransition のような API、 React.lazy をサポートしたサーバーサイドレンダリング用の新しいストリーミング API が追加されると書いている

まず alpha を使わないといけないので react と react-dom の alpha を download する

$ npm install react@alpha react-dom@alpha

Server-Side Streaming

React 18 の concurrent には server side suspense と SSR streaming がサポートされているためそれらを使うことができる

実験的な機能なので有効にするには next.config.js で以下のフラグを有効にする必要がある

// next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true
  }
}

React Server Components

React Server Components ではコンポーネントを含むすべてのものをサーバー上でレンダリングすることができる。Server Components ではクライアントサイドの JavaScript が一切不要になるためページのレンダリングが高速化される

使うには以下のフラグを有効にする必要がある

// next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
    serverComponents: true
  }
}

React Server Components を使うことで getServerSidePropsgetStaticProps のような Next.js の特別な関数を使う必要がなくなった。データ取得をコンポーネントに co-location することは React Hooks のモデルに沿ったものである

Next.js のページを .server.js にリネームして、サーバーコンポーネントを作成し、クライアントコンポーネントをサーバーコンポーネントの中に import することが可能である

現在 Next.js は server-side suspense, 選択的な hydration, streaming rendering に取り組んでいて今後ブログで紹介していくつもりである

JJJJ

Bot-Aware ISR Fallback

現在 fallback: true を用いた、 Incremental Static Regeneration はまだ生成してないページへの最初のリクエストでページのコンテンツをレンダリングする前に、 fallback 状態をレンダリングする。ページの読み込み自体をブロックするには fallback: blocking を指定する。

Next.js 12 では、 web クローラーは fallback: true を使用した ISR ページを自動的にサーバーレンダリングするが、クローラーではない User-Agent に対しては以前と同じ挙動をするようになる。
これによって、 クローラーに対してローディング状態をインデックス化させることを防ぐ。

JJJJ

Smaller images using AVIF

Next.js の Image Optimization が AVIF 画像をサポートするようになった。 WebP と比較して 20% 小さい画像になる。
AVIF 画像は WebP と比較して最適化に時間がかかるため、 next.config.js の新しい images.format プロパティを使って optin することができる

module.exports = {
  images: {
    formats: ['image/avif', 'image/webp']
  }
}

この format のリストは、リクエストの Accept header を使用してオンデマンドで最適な画像フォーマットを決定するために使用される。 AVIF が最初に来るのでブラウザが AVIF をサポートしていれば AVIF を提供し、されてない場合は WebP をサポートしていれば WebP を提供、それもサポートされてない場合はオリジナル画像を提供するといった流れになる

JJJJ

ES Modules Support and URL Imports

Next.js 11.1 から ESM support を実験的にサポートしていたが、 Next.js 12 ではこれらがデフォルトになった。また CommonJS のみを提供している npm modules の import は引き続きサポートもする

JJJJ

URL Imports

Next.js 12 では ES modules を URL 経由で import する機能が実験的にサポートされていて install や別の build step は必要ない

URL import では任意のパッケージを URL 経由で直接使用することができる。これにより Next.js は remote の http(s) リソースをローカルの依存環境と同じように処理することができるようになった。

URL import が検出されると Next.js は remote resource を追跡するための next.lock を生成する。 URL import はローカルにキャッシュされるため、オフラインでも作業は可能。また Next.js はクライアント / サーバーサイドの両方で URL import をサポートしている。

next.config.js の中に、許可する URL prefix を追加することで optin することができる

module.exports = {
  experimental: {
    urlImports: ['https://cdn.skypack.dev']
  }
}

こう記述すると cdn.skypack.dev のものであれば URL import することができる

import confetti from 'https://cdn.skypack.dev/canvas-confetti'

ES modules を提供する CDN やノーコード、 Framer のようなデザインツールもまとめて動作させることが可能。

  • Skypack
  • esm.sh
  • jsDelivr
  • JSPM
  • unpkg
JJJJ

Breaking Changes

  • webpack 4 を正式に削除し、 webpack 5 をデフォルトとする
  • next.config.js の target が不要になった
  • next/images で wrap するのが div から span に変更された
  • Node.js の最小バージョンが 12.0.0 から 12.22.0 に上がった。これは Native ES Modules をサポートするバージョンのうち最小
JJJJ

next/images で wrap するのが div から span に変更された

これ styled-components とかで無理やり親からスタイル書き換えてたりしてる人壊れそう

JJJJ

今回この Next.js 12 の中の Middleware というのも Next.js を Vercel に deploy してれば middleware の部分を Edge で実行してくれるという神みたいなプレーかましてくれるのね。なるほど。

このスクラップは2021/12/21にクローズされました