Next.js 12 からの脱却! Next.js 13 へスムーズに移行するためのアップデートガイド
こんにちは、Gaji-Labo フロントエンドエンジニアのたにもとです。
先日 Next.js 12 だった開発環境を Next.js 13 へアップデートする機会がありました。
本記事ではアップデートで対応した内容とハマった時の対処方法を紹介します!
今回対応した変更
Next.js 12 から Next.js 13 へのアップデートで対応したのは以下の3点です。
next/image
に置き換えnext/link
の仕様変更に伴う<Link>
構造の変更- SWC への移行(コンパイラの見直し)
SWC への移行は、必須ではないと考えています。
一方で Next.js 12 以降のバージョンではデフォルトで有効になっています。
可能であれば乗り換えておいた方が良いと判断し、Next.js 13 へのアップデートのこのタイミングで対応しました。
公式ドキュメントにアップデート内容の要約があるので合わせてご確認ください!
具体的な変更内容
next/image
に置き換え
Next.js 13 から import 名が next/image
に変更されるので置き換えます。
今回のプロジェクトでは、next/future/image
が利用されていたので next/image
に置き換えました。
アップデート前に next/image
を利用している場合は以下の2パターンの対応方法があります。
状況に応じて対応方法を検討してください。
- Next.js 12 と同じ仕様で利用し続けたい場合は
next/legacy/image
に置き換える - Next.js 13 の新しい仕様で利用したい場合は変更せず next/image を利用し続ける
codemod が用意されているので一度実行してみるのも良いと思います。
実行箇所のパス ./src
は環境に合わせて変更し、ご利用ください。
npx @next/codemod@latest next-image-to-legacy-image ./src
import 名の置き換え以外にも、alt
が必須になるなどの変更があります。
公式ドキュメントをご確認いただきながら対応されることをオススメします!
next/link
の仕様変更に伴う <Link>
構造の変更
Next.js 13 では <Link>
タグの中に <a>
タグが内包されているとエラーになります。
// Next.js 12 の場合
<Link href="/hoge">
<a target="_blank">リンクテキスト</a>
</Link>
// Next.js 13 の場合
<Link href="/hoge" target="_blank">
リンクテキスト
</Link>
対応は a
タグを削除するだけです。
ただ、構造に依存したスタイルが適用されていたり、 <Link>
でラップした子要素に a
タグが含まれていたり構造を変更するのが困難な場合もあります。
そんな場合の一時的な回避策を2つ紹介します。
<Link>
の子要素として<a>
を使わずに、直接div
やspan
で囲むlegacyBehavior
を設定して対応
legacyBehavior
について補足しておきます。<Link>
タグに legacyBehavior
を付与することで従来の構造でリンクを機能させることができます。
<Link href="/hoge" legacyBehavior>
<a target="_blank">リンクテキスト</a>
</Link>
Next.js 13 の仕様に沿って変更できるのがベストですが、状況に応じて利用を検討してみてください。
こちらも codemod が用意されているのでご利用いただくのも良いと思います。
実行箇所のパス ./src
は環境に合わせて変更し、ご利用ください。
npx @next/codemod@latest new-link ./src
SWC への移行
SWC への移行には next.config
を編集します。
今回の環境では元々 babel
を利用していたのでパッケージも含めて見直しました。
この時 .babelrc
などの babel
に関する設定ファイルを削除しておいてください。
詳しくは後述させていただきます。
以下は削除したパッケージと追加したパッケージです。
// 削除したパッケージ
"@emotion/babel-plugin"
"babel-loader"
"babel-plugin-inline-react-svg"
// 追加したパッケージ
"@svgr/webpack"
次に next.config
を修正していきます。
基本的にはこれまで使っていた記述を使うことができますが、以前は babel
で行っていた Emotion の処理や SVG の処理を next.config に設定を追加しコンパイルされるように修正します。
const nextConfig = {
swcMinify: true,
},
// emotion の処理を追記
compiler: {
emotion: true,
},
webpack: (config) => {
// svg の処理を追記
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
})
return config
},
}
アップデート時にハマったトラップと対処法
解決までに時間がかかったことを2点紹介します。
- SWC で設定した内容がコンパイルに反映されない
- SVG の表示が崩れる
SWC で設定した内容がコンパイルに反映されない
前述で .babelrc
を削除してくださいと書かせていただいた箇所の詳細を説明します。
Next.js は .babelrc
が残っていると babel の設定が優先する仕様があります。
この仕様を知らず解決までの時間がかかりました…。
なので SWC に移行する時は .babelrc
を削除しましょう。
SVG の表示が崩れる
アップデート後に SVG が正しく表示されなくなるケースがあります。
これは、コンパイル時の処理が影響している可能性があります。
今回のアップデート対応のパターンだと @svgr/webpack
の内部で利用されている SVG を最適化しする svgo
が原因であることが考えられます。
SVG が最適化される過程で
の値が削除されてしまうことで発生するようです。viewBox
これを回避するために
の値が消えないように設定を追加する必要があります。viewBox
const nextConfig = {
webpack: (config) => {
config.module.rules.push({
test: /\.svg$/,
// ここを修正
use: [{ loader: '@svgr/webpack', options: { dimensions: false } }],
})
return config
},
}
Next.js 13 へのアップデートをスムーズに進めるために
メジャーバージョンのアップデートには様々なトラップがあります。
ただ、必ず誰かが困って調べた痕跡があり、解決方法が用意されていることが多いので Github の issue を中心に調べてみることをオススメします!
一時的に回避策を実行し、次のアップデートの際に対応する方が効率が良い可能性もあります。
あえて後回しにするのもスムーズにアップデートを進めるためにコツだと考えます。
Gaji-Laboでは、 Next.js 経験が豊富なフロントエンドエンジニアを募集しています
弊社では Next.js の知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違う Gaji-Labo を味わいに来ませんか?
Next.js の設計・実装を得意とするフロントエンドエンジニア募集要項
もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!
この記事がアップデートするために手がかりになると幸いです!