Next.js@9.2 がリリースされたのでこの blog へ適応して要点などまとめておきました。
表題の通り、Next.js 9.2 がリリースされました。
変更点は主に下記のようです。
Global Stylesheet のサポート
これまでは CSS の import をする場合は @zeit/next-css
を利用する必要がありましたが、標準でサポートしてくるようになりました。
共通の CSS は pages/_app.js
にて下記のように import すれば build 時に共通 asset として吐き出してくれます。
// pages/_app.js
import '../styles.css'
コンポーネントレベルでの CSS Module のサポート
[name].module.css
という名前で生成した CSS ファイルを import することで、CSS Modules を実現できる。
// src/components/Links/index.module.css
.ul {
display: flex;
justify-content: center;
}
.li {
display: inline-block;
margin-right: 15px;
}
// src/components/Links/index.js
import Link from "next/link";
import styles from "./index.module.css";
export default () => {
return (
<div>
<ul className={styles.ul}>
<li className={styles.li}>
<Link href="/">
<a>top</a>
</Link>
</li>
<li className={styles.li}>
<Link href="/about">
<a>about me</a>
</Link>
</li>
<li className={styles.li}>
<Link href="/blog">
<a>posts</a>
</Link>
</li>
</ul>
</div>
);
};
module scope の CSS はスプリットされ、<link preload as="style"
として別々にロードされる。
FP を速くするためにページごとに最小限の CSS がロードされるようにしてくれている。
Network
Element
もちろん、unique な class 名が付与されるので、styled-component と同じ理屈で普遍的な名前をつけてしまっても名前空間のコンフリクトの心配はない。
Code-Spliting 戦略の改善
9.2 以前では TTI までに必要な bundle がいくつか存在していたが、この読み込みがあまり賢いものではなかった。
その module が各 page で 50% 以上使用されていれば common.js
へブチ込むし、未満なら page 固有へ割り当てたりみたいな感じだったらしい。
この辺りが Chrome チームのサポートとかを受けながらかなり改善したらしい。
開発者として知っておかないといけないかというとそうでもない知識に分類されるので、「code-spliting がマシになったのね」くらいの認識でいいと思う。
気になった人は blog を詳しく読もう。
一応 build の差分を載っけておく。
9.17 の build
> next build
Creating an optimized production build
Compiled successfully.
Automatically optimizing pages
Page Size
┌ ○ / 402 B
├ ○ /about 446 B
├ ● /blog 488 B
└ ● /blog/2020/write-notes-until-develop-with-Next.js-and-depploy-with-now 604 B
+ shared by all 71.6 kB
├ chunks/commons.js 66 kB
├ runtime/main.js 4.88 kB
└ runtime/webpack.js 746 B
λ (Lambda) server-side renders at runtime (uses getInitialProps or getServerProps)
○ (Static) automatically rendered as static HTML (uses no initial props)
● (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
9.2 の build
> next build
Creating an optimized production build
Compiled successfully.
Automatically optimizing pages
Page Size First Load
┌ ○ / 412 B 73.6 kB
├ /_app 269 B 54.9 kB
├ ○ /about 453 B 73.7 kB
├ ● /blog 495 B 73.7 kB
└ ● /blog/2020/write-notes-until-develop-with-Next.js-and-depploy-with-now 611 B 73.8 kB
+ shared by all 54.9 kB
├ static/_buildManifest.js 294 B
├ static/pages/_app.js 269 B
├ chunks/commons.888ebf.js 8.59 kB
├ chunks/framework.94bc9f.js 40.5 kB
├ runtime/main.6d7d62.js 4.59 kB
└ runtime/webpack.b65cab.js 746 B
λ (Lambda) server-side renders at runtime (uses getInitialProps or getServerProps)
○ (Static) automatically rendered as static HTML (uses no initial props)
● (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
First Load というカラムが増えているよう。
これはおそらく TTI までに必要な load size の目安ということだと思う。
ワイルドカード的なダイナミックルート
/pages/[slug].js
という形で、Next.js でもダイナミックルートを扱えるようになったのだが、ワイルドカード的な使い方は用意されていなかった。
それが 9.2 からは [...name]
という構文を使用して、ワイルドカード的なダイナミックルート(公式はキャッチオールダイナミックルートと呼んでいる)を利用できるようになった。
例えば、pages/post/[...slug].js
は /post/a、/post/a/b、/post/a/b/c をキャッチできるようになる、というような感じ。
軽く検証してみると、query とかはこんな感じになるらしい。
// src/pages/post/[...slug].js
function App() {}
App.getInitialProps = function({ query }) {
console.log(query);
return {};
};
export default App;
この状態で /post/dep1/dep2/dep3
へアクセスすると log には下記のように出ていた。ヒエラルキーの降順で配列で渡されるよう。
{ slug: [ 'dep1', 'dep2', 'dep3' ] }