Next.js 12 をざっくり理解
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
Rust Compiler
Rust 製の 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
}
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!')
}
React 18 Support
React 18 で使える Suspense
や startTransition
のような 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 を使うことで getServerSideProps
や getStaticProps
のような Next.js の特別な関数を使う必要がなくなった。データ取得をコンポーネントに co-location することは React Hooks のモデルに沿ったものである
Next.js のページを .server.js
にリネームして、サーバーコンポーネントを作成し、クライアントコンポーネントをサーバーコンポーネントの中に import することが可能である
現在 Next.js は server-side suspense, 選択的な hydration, streaming rendering に取り組んでいて今後ブログで紹介していくつもりである
Bot-Aware ISR Fallback
現在 fallback: true
を用いた、 Incremental Static Regeneration
はまだ生成してないページへの最初のリクエストでページのコンテンツをレンダリングする前に、 fallback 状態をレンダリングする。ページの読み込み自体をブロックするには fallback: blocking
を指定する。
Next.js 12 では、 web クローラーは fallback: true
を使用した ISR ページを自動的にサーバーレンダリングするが、クローラーではない User-Agent に対しては以前と同じ挙動をするようになる。
これによって、 クローラーに対してローディング状態をインデックス化させることを防ぐ。
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 を提供、それもサポートされてない場合はオリジナル画像を提供するといった流れになる
ES Modules Support and URL Imports
Next.js 11.1 から ESM support を実験的にサポートしていたが、 Next.js 12 ではこれらがデフォルトになった。また CommonJS のみを提供している npm modules の import は引き続きサポートもする
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
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 をサポートするバージョンのうち最小
next/images で wrap するのが div から span に変更された
これ styled-components とかで無理やり親からスタイル書き換えてたりしてる人壊れそう
今回この Next.js 12 の中の Middleware
というのも Next.js を Vercel に deploy してれば middleware の部分を Edge で実行してくれるという神みたいなプレーかましてくれるのね。なるほど。
本気和訳してる人いたので詳しく知りたい人はこちら💁♂️