Next.js で next build した時、出力先フォルダがクリーンされない件
2021/06/26 追記: Next.js 11 からビルド時 distDir
がクリーンされるようになりました。以下のビルド前にデータを消すが必要なのは Next.js 10 以下の場合です。
Next.js では設定をしない状態だとビルドの度に新しいビルド ID が割り当てられ、データフォルダにビルド ID 名のフォルダが作成されます。ところが、ビルド時に出力先がクリーンされません。そのため過去のビルド結果が積み重なり、出力先フォルダが肥大化してしまいます。
Next.js の GitHub の Discuttions に「ビルド時に .next
フォルダをクリーンしてほしい」というリクエストが上がっていますが、Next.js 10 (記事日付現在) ではクリーンはされないようです。
[RFC] cleaning distDir on next build · Discussion #6009 · vercel/next.js
フォルダ構成
next export したフォルダは以下のような構成になっていました。
out/
├ _next/
│ ├ ビルド_ID_1/
│ ├ ビルド_ID_2/
│ ├ ビルド_ID_3/
│ ├ ...
│ ├ data/
│ │ ├ ビルド_ID_1/
│ │ ├ ビルド_ID_2/
│ │ ├ ビルド_ID_3/
│ │ ├ ...
│ └ static/
│ ├ ビルド_ID_1/
│ ├ ビルド_ID_2/
│ ├ ビルド_ID_3/
│ ├ ...
│ ├ chunks
│ ├ css
│ └...
├ index.html
├ 各ページの html
├ ...(/public のファイル)
ビルドした回数だけビルド ID (ランダムな文字列) のフォルダができてしまいます。
対処法
以下 2 つの組み合わせでなんとかなりました。
ビルド前にデータを消す
- ルートフォルダにある
.next
フォルダ next export
で作成されるエクスポート先のフォルダ
これらはビルド時に作られるので完全に削除しても問題はありませんでした。
エクスポート先のフォルダが /out
の場合は以下のようなコマンドで消せます。
rm -rf .next out
などして削除してから再度 next build && next export
すればビルド時点のデータだけになりました。
かといって毎回コマンドを打つのも大変なので、 rimraf
(OS に依らず rm -rf
を実行してくれるパッケージ) をインストールして npm script に書いてしまうのがいいかもしれません。
私の package.json
には以下のような scripts
を書いています。
...
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"export": "next build && next export",
"clean": "rimraf .next out",
...
},
...
過去のデータをビルド結果に含ませたくないときは npm run clean
を実行してから npm run export
します。
毎回必ず削除してからビルドするなら export
などにまとめしまってもいいかもしれません。
"scripts": {
...
"export": "rimraf .next out && next build && next export"
...
}
任意の Build ID を指定する
next.config.js
に generateBuildId
を用意することで任意の Build ID を割り当てることができます。
私のケースでは GitHub のリリースに応じて Build ID を変えていきたかったので、以下のような感じで package.json の version を参照して設定するようにしてみました。
module.exports = {
...
generateBuildId: async () => {
// package.json の version を取得する
const version = process.env.npm_package_version;
console.log('Use package version as Build ID: ', version);
// ピリオドをハイフンに置換したものを Build ID にする
return version.replace(/\./g, '-');
},
...
}
これでバージョン 1.0.0 なら 1-0-0 フォルダにビルド結果が入るようになりました。
バージョンアップが続いて過去のデータが溜まってきたら ビルド前にデータを消す 方法で消す感じの運用にしています。
あとがき
クリーンしないことで何かメリットがあるのかもしれませんが、私の使用状況では見当たりませんでした。 逆にクリーンすることで生じるデメリットがあるのかもと悩みましたがそちらも特に思い当たるところはなし。 転送量の制限が厳しいサーバーや記憶域が小さいサーバーでホスティングする時に困りそうな気がするので手動でも削除したほうがよいかなと思いました。