Next.js 9.4の変更点
遅れながらNext.js 9.4の変更点に触れていきます。基本的に公式に沿っていますが、割合した部分および多少コードの補足を加えています。
Fast Refresh
Next.jsはホットリロードが搭載されていましたが、9.4では新たにreact-refreshが搭載されました。react-refreshはホットリロード同様に自動リロード機能を持っていますが、加えてコードの変更前後でアプリケーションの状態を維持することができます。
スタイル、マークアップ、イベントハンドラ、エフェクトで状態維持がサポートされているようです。エラー位置を正確に出力してくれるなど利便性も上がっています。
環境変数
9.3以前の環境変数はnext.config.js
を用いてましたが、9.4からは以下も可能になりました。
NEXT_PUBLIC_
で始まるインライン変数.env
ファイルでカスタム環境変数を追加する
インライン変数
Next.jsはアプリケーション内でNEXT_PUBLIC_
で始まる環境変数をインライン化(数値を値に置き換える)するようになりました。例えばページ内に以下が記述されているとします。
<p>hello, {process.env.NEXT_PUBLIC_NAME}</p>
NEXT_PUBLIC_NAME=mda yarn dev
と実行すると、<p>hello, mda</p>
となります。
インライン変数はJavaScriptのバンドルに含まれるため、機密情報の埋め込みに適していません。
.envファイルによる環境変数
プロジェクトのルートに.env
ファイルを置くと、環境変数として公開することができます。ただし、環境変数はNode.js環境でのみ動作し、クライアント(ブラウザ)のJavaScriptバンドルには含まれません。変数を含めたい場合は、前述したようにインライン変数にする必要があります。
NEXT_PUBLIC_NAME='mda'
API_VALUE=10
上記の.env
ファイルの場合、クライアントコードではAPI_VALUE
にアクセスできませんが、NEXT_PUBLIC_NAME
はクライアントのコードでアクセスできます。
// pages/index.js
function Home() {
return (
<>
{/* ブラウザでアクセス可能 */}
<p>{process.env.NEXT_PUBLIC_NAME}</p>
{/* ブラウザでアクセス不可 */}
<p>{process.env.API_VALUE}</p>
</>
)
}
export default Home
以下では、Node.js環境のためAPI_VALUE
変数が動作します。
export default function Home({ post }) {
return (
<>
<section id={post.id}>
<h1>{post.title}</h1>
<p>{post.body}</p>
</section>
</>
)
}
export async function getServerSideProps(context) {
const id = process.env.ID;
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
const post = await res.json();
return { props: { post } }
}
.env
ファイルは実行時の環境に応じて、複数のファイルを用意できます。以下の[enviroment]
には、develop
, production
, test
が明記できます。実行時においてnext dev
はdevelopment、next build
とnext start
はproductionと見なされます。
- .env
- .env.local
- .env.[enviroment]
- .env.[enviroment].local
local
がつくものは変数の上書きに使います。local
なし版はリポジトリの管理対象に入れ、local
版は.gitignore
に記述するようです。このため、後者が機密情報を保管するのに適しています。また、適用される優先順位もあり、上記では下にいくほど優先順位が高くなります。
例えば先程のサンプルにおいて、以下の3つのファイルを用意したとします。
// 便宜上、3つのファイルを1箇所に記述しています
// .env
ID=1
// .env.development
ID=5
// .env.development.local
ID=10
これをnext dev
するとID=10
が使用されます。next build
後にnext start
とするとproductionになりますが、production用の環境ファイルはないため、.env
のID=1
が使用されます。
絶対インポート
jsconfig.json
にbaseUrl
を設けると、絶対インポートが可能になりました。.
はルートディレクトリを指しています。
// jsonconfig.json(TypeScriptの場合はtsconfig.json)
{
"compilerOptions": {
"baseUrl": "."
}
}
例えば長々しい../../../components/button
も以下で解決されます。
import Button from 'components/button';
エイリアス
baseUrl
に加えてpaths
オプションを使うと、エイリアスも設定できるようになります。
以下のようなディレクトリ構造を想定します。
(root)/
├── components/
│ └── nest/
│ ├── partsA.js
│ └── partsB.js
└── pages/
└── index.js
通常、index.js
からpartsAとpartsBをインポートするには、以下のようになります。
import PartsA from '../components/nest/partsA';
import PartsB from '../components/nest/partsB';
jsconfig.json
にpaths
を追加してみます。
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/parts/*": [
"components/nest/*"
]
}
}
}
@/parts/*
にcomponents/nest/*
というパスをマップしたため、以下が可能になります。
import PartsA from '@/parts/partsA';
import PartsB from '@/parts/partsB';
VSCodeなどを使用していると、パス部分で補完が適用されるようにもなっています。
Web Vitals Reporting
Google Chromeが提供し出したWeb VitalsがNext.jsに組み込まれました。公式にあるようにpages/_app.js
にreportWebVitals
というメソッドを配置し、メトリックを計測できます。
// pages/_app.js
export function reportWebVitals(metric) {
console.log(metric);
}
function MyApp({ Component, pageProps }) {
return <Comopnent {...pageProps} />
}
export default MyApp;
例えば、トップページにアクセスすると、以下が出力されました。
{
"id":"1590175632294-1421296618188",
"name":"Next.js-hydration",
"startTime":537.2850000003382,
"value":15.414999999848078,
"label":"custom"
}
{
"id":"1590175868092-9818419920942",
"label":"web-vital",
"name":"FCP",
"startTime":452.3850000005041,
"value":452.3850000005041
}
{
"id":"1590175868092-9037373988752",
"label":"web-vital",
"name":"TTFB",
"startTime":0,
"value":19.775000000663567
}
name
に記載されているのがネットワークリソースの応答性の指標として使用される測定値名です。
FCPはFirst Contentful Paintの略で、ブラウザがDOMのコンテンツの最初のビット(テキストや画像など)がレンダリングされるポイントを示します。TTFBはTime To First Byteの略で、サーバへの接続が要求された後、最初のバイトが利用者のブラウザに到達するまでの時間を示します。Next.js-hydrationは、Next.jsが実際のドメインデータを埋め込んでいく段階のことだと思われます。そして、実際の参考値には、startTime
やvalue
を利用します。
このようにNext.jsの固有値も含め、各種メトリックをキャプチャすることが容易になりました。
その他の変更点
- Incremental Static Regeneration - 静的コンテンツを再レンダリングさせるメソッド。現在betaバージョンのため割合しますが、今後よく利用されそうな機能になると思われます
- 組み込みfetchメソッドの改善 - ブラウザおよびNode.js環境で同じfetchメソッドが利用できるようになりました。node-fetchなどのモジュールを導入する必要がなくなります
- Sassの設定オプション -
next.config.js
でSassのオプション設定ができるようになりました - ログ出力 - ログの出力が再設計されました
Next.js 9.4は後方互換が保たれているため、特に問題なく移行できるはずです。