CodeLeaf
@CodeLeaf

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【React × Tailwind】定数ファイルに切り出したTailwindのクラス名が認識されない

解決したいこと

私は現在、就職活動用のポートフォリオサイトを作成している駆け出しのフロントエンドエンジニアです。

Next.jsとTailwindCSSを使用してサイトを実装していますが、定数ファイルにTailwindのクラス名(text-blackやtext-blue-600など)を記載したところ、TailwindCSSの最適化機能によりこれらのクラス名が認識されない問題が発生しました。カスタムフックにしても解決できなかったため、現在はコンポーネントに直接記述する形で対応していますが、コードが長くなってしまうため、より良い解決策を探しています。

発生した問題

コードの移動による問題

当初は以下のようにコンポーネントに直接スキルデータを記述していました。

// components/Skills.tsx(動作する)
export const Skills = () => {
  // コンポーネント内に直接スキルデータを記述
  const skills = [
    {
      title: 'Next.js',
      textColor: 'text-black',
    },
    {
      title: 'React',
      textColor: 'text-blue-600',
    },
    // ... 他のスキルデータ
  ] as const;
  
  return (
    <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'>
      {skills.map((skill) => (
        <div key={skill.title} className={skill.textColor}>
          {skill.title}
        </div>
      ))}
    </div>
  );
};

このコードは動作しましたが、以下の課題がありました。

  • コードが長くなり、可読性が低下
  • スキルデータの再利用が困難
  • データとUIの関心の分離ができていない

定数ファイルへの切り出し

そこで、データを定数ファイルに切り出す実装を試みました。

// constants/skills.ts(動作しない)
// 定数ファイルにTailwindのクラス名を記載
export const skills = [
  {
    title: 'Next.js',
    textColor: 'text-black', // このTailwindのクラス名が認識されない
  },
  {
    title: 'React',
    textColor: 'text-blue-600', // このTailwindのクラス名が認識されない
  },
  // ... 他のスキルデータ
] as const;

// components/Skills.tsx(動作しない)
import { skills } from '@/constants/skills';
export const Skills = () => {
  return (
    <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'>
      {skills.map((skill) => (
        <div key={skill.title} className={skill.textColor}>
          {skill.title}
        </div>
      ))}
    </div>
  );
};

このコードは一見問題なさそうに見えますが、実際にアプリケーションを動かすとtextColorで指定したクラスが適用されませんでした。

カスタムフックでの実装試行

次に、カスタムフックを使用して実装を試みました。

// hooks/useSkills.ts
type UseSkills = { skills: Skill[] };
export const useSkills = (): UseSkills => {
  // カスタムフックにTailwindのクラス名を記載
  const skills: Skill[] = [
    {
      title: 'Next.js',
      textColor: 'text-black', // このTailwindのクラス名が認識されない
    },
    {
      title: 'React',
      textColor: 'text-blue-600', // このTailwindのクラス名が認識されない
     },
    // ... 他のスキルデータ
  ] as const;
  return { skills };
};

// components/Skills.tsx(動作しない)
import { useSkills } from '@/hooks/useSkills';
export const Skills = () => {
  const { skills } = useSkills();
  return (
    <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'>
      {skills.map((skill) => (
        <div key={skill.title} className={skill.textColor}>
          {skill.title}
          {/* 他のスキル情報の表示... */}
        </div>
      ))}
    </div>
  );
};

しかし、この方法でも同様の問題が発生しました。

自分で試したこと

  1. まず定数ファイルにスキルデータを切り出して実装しましたが、TailwindCSSの最適化機能により、クラス名が認識されませんでした

  2. 次に、カスタムフックとして実装しましたが、同様の問題が発生しました

  3. 現在は、コンポーネントに直接スキルデータを記述することで問題を回避していますが、以下の課題があります

    • コードが長くなり、可読性が低下
    • スキルデータの再利用が困難
    • データとUIの関心の分離ができていない

初心者なため、TailwindCSSでこのような動的クラス名を使用する際の、より良い実装方法がわからず困っています。ご存知の方がいらっしゃいましたら、アドバイスをいただけますと幸いです。

0

1Answer

TailwindCSSの最適化機能(パージCSS)

Tailwind はソースコードをスキャンし、実際に使われているクラス名に対応した CSS だけ生成する機能を持っていますが、それと PurgeCSS は別物です。 PurgeCSS は CSS から使われていないクラスを除去する別個のツールです。

Tailwind だけ使っているのであれば、 tailwind.config.jscontent 設定にスキャン対象のファイル名パターンを追加してください。 './constants/**/*.ts''./hooks/**/*.ts' と書けばいいはずです。

本当に PurgeCSS も使っているのであれば、 purgecss.config.jscontent 設定に同様のパターンを追加してください。

1Like

Comments

  1. @CodeLeaf

    Questioner

    ご回答ありがとうございます🙏

    ご指摘の通り、tailwind.config.ts の content 設定に "./src/constants/**/*.ts" を追加することで解決できました✨

    今回の問題は、TailwindCSSが最適化のためにソースコードをスキャンする際、デフォルトでは constants ディレクトリ配下のファイルがスキャン対象外となっていたことが原因でした 🔍

    また、PurgeCSSについてのご指摘も勉強になりました📚
    TailwindCSSの最適化機能とPurgeCSSは別のツールということを理解できました💡
    混同していた部分を整理することができました🌟

    丁寧なご回答をいただき、ありがとうございました 🙇‍♂️

Your answer might help someone💌