Next.jsのビルドタイムだけtailwindcssのスタイルが消える 2021.07.15
@tailwindディレクティブを@import文に変更する
開発中は気が付かなかったがvercelにデプロイすると、テーマで指定したスタイルの一部が消えていた。手元でビルドして見てみると、同様にスタイルが消えている。
テーマ記述はこんな感じ。
module.exports = {
// ...
theme: {
extend: {
colors: {
danger: colors.red,
warning: colors.amber,
success: colors.teal,
info: colors.blue,
gray: colors.coolGray,
},
},
},
// ...
}
とりあえず見つかった情報で、styles/global.css
の@tailwind
ディレクティブを@import
にしてみたが変化なし
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
safelist
オプションを使用する
tailwindcssは全体を載せるとコードベースが巨大なのでビルド時に不要な部分を落とす機能がある。開発時には問題なくて、ビルド時に壊れるのは最適化に問題があるのかもしれない。
safelist
オプションを使用すると解消できるが、使うスタイルをひとつづつ記述していくのはだいぶつらい。
module.exports = {
purge: {
content: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
safelist: [
'lots',
'of',
'my',
'classes',
// ...
],
},
// ...
}
クラス名が含まれるコードをpurge対象に指定する
問題の箇所は、コンポーネント外のユーティリティに記述したクラス名をclassnamesを使って動的に設定していた。
// ユーティリティのイメージ
export const dict = {
item: {
title: 'title',
bgClass: 'bg-danger-500',
textClass: 'text-white',
},
// ...
}
// コンポーネント側のイメージ
return (
<label
className={classNames(
{
[dict.bgClass]: dict.bgClass,
[dict.textClass]: dict.textClass,
},
)}
>
{dict.title}
</label>
)
ユーティリティに記述したクラス名がpurge対象になっていないのが問題かもしれない。
該当ファイルを含めるようにすると正しくビルドできた。
module.exports = {
purge: {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
'./utils/**/*.{js,ts,jsx,tsx}', // <- 追加
],
},
// ...
}
コンポーネント以外にtailwindcssのクラス名を記述したときはtailwind.config.js
のpurge.content
をアップデートして、正しくpurge対象に含める必要があるということがわかった。
ていうか公式に書いてあった。
This list should include any files in your project that reference any of your styles by name. For example, if you have a JS file in your project that dynamically toggles some classes in your HTML, you should make sure to include that file in this list.