2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

型ファイルが邪魔じゃない。React開発者のための型安全CSS Modules環境構築

Last updated at Posted at 2023-11-29

はじめに

Reactを用いた開発の際、CSSをどうするかは意見が分かれるところだと思います。
今回はそのなかでもCSS Modulesを用いて型安全な開発環境を構築する方法を紹介したいと思います。

前提環境

この記事を書いた人の環境は以下です。
React : 18.2.0
Typescript : 4.9.5
node : 18.17.1

Dockerで動かしていますが、使っていなくても大丈夫です。

この記事で作れる環境

  • 型ファイルを普段目につかない場所に置ける(自分の中では最重要)
  • cssファイルを編集した瞬間型ファイルに反映
  • 存在しないクラス名の時はエラーを出してくれる
    スクリーンショット 2023-11-27 22.21.15.png
  • インポートしてあるCSSファイルのクラス名を早い段階でサジェストに出すことができる
    スクリーンショット 2023-11-27 22.22.12.png

などです。
また、CSSModulesそのもののメリットとして以下のものがあります、

  • 学習コストが低い
  • 過去の.cssファイルをほぼそのままで使える
  • クラス名を一意に生成することにより、クラス名の衝突が防げる(importしていないCSSファイルのクラスは適用されない)

しかし一概にcss-modulesがCSSを扱う上での最適解というわけではなく、特にReactにおいてはCSSの選択は意見が分かれるところだと思うのでこのぐらいにしておきます。では本題の環境構築の方法に進みます。

環境構築

Typescript入りのReactは動いている前提で話を進めます。

この作業をする時はブランチを切って進めていくことを強く勧めます。(環境を大きくいじる場合があるので)

最終的なディレクトリ構造はこちらです
.
├── dist // 型ファイルがここに生成されます
│   ├── index.css.d.ts
│   └── components
│       ├── card
│       │   └── card.css.d.ts
│       └── list
│           └── list.css.d.ts
├── src
│   ├── index.tsx
│   ├── index.module.css
│   └── components
│       ├── card
│       │   ├── card.tsx
│       │   └── card.module.css
│       └── list
│           ├── list.tsx
│           └── list.module.css
└── tsconfig.json

1. typed-css-modulesをプロジェクトに追加

クラス名を型ファイルに書き出してくれる神パッケージです。
こちらの手順に従ってインストールします。

npm install typed-css-modules
npm install -g typed-css-modules

順に実行します。

2.tsconfig.jsonを編集

必要ない行は省略してます。

tsconfig.json
{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "src/*": ["./dist/src/*", "./src/*"],
        }
    },
    "include": ["src","dist/**/*"],
}
全文
{
    "compilerOptions": {
        "target": "es5",
        "baseUrl": ".",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noFallthroughCasesInSwitch": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react-jsx",
        "typeRoots": ["types"],
        "downlevelIteration": true,
        "paths": {
            "src/*": ["./dist/src/*", "./src/*"]
        }
    },
    "include": ["src", "types", "dist/**/*"],
    "exclude": ["node_modules"]
}

tsconfig未だによくわかってないので、意味不明な部分あれば教えてください🙇🏻‍♂️

肝は以下の部分で、

"paths": {
    "src/*": ["./dist/src/*", "./src/*"],
}

import styles from "src/myComponent.module.css";とした時に、まず"./dist/src/*"を見に行ってくれます。型情報を参照しつつ、importエラーも出なくなります。このおかげで型ファイルを普段見えない場所に置いておくことができます。

3. package.jsonを編集

package.jsonscriptsの部分に追記します。

package.json
"scripts": {
    "tcm": "npx tcm -p src/**/*.module.css -o dist -w"
}

説明します。これは先ほどインストールしたtyped-css-modulesを実行するコマンドです。
-p src/**/*.module.cssで監視するファイルをsrc以下の.module.cssに限定します。
-o distで型ファイルをアウトプットする先を指定しています。dist部分は好きに変えて問題ないですが、合わせてtsconfig.jsonも変更する必要があることに注意してください。
-wでcssファイルの変更を監視して、自動で型ファイルを変更に合わせて書き換えてくれます。

4.コマンドを実行

上の作業を終えた後、npm run tcmで実行すると、プロジェクトのルートディレクトリにdistフォルダが作成され、src以下に対応したディレクトリに型ファイルが生成されます。

ローカルで開発している方は新規ターミナルを立ち上げて上記のコマンドを打ってください。
Dockerを使用している方はコンテナの立ち上げに合わせてnpm run tcmを実行させるか、
startの部分を"start": "npx tcm -p src/**/*.module.css -o dist -w & react-scripts start",のように記述しても大丈夫です。

5.実際につかってみる

任意のファイルでmodule.cssファイルを作って、インポートしてみます。

src/MyComponent.tsx
import styles from "src/myComponent.module.css";

function MyComponent() {
    return <div className={styles.text_highlight_test}>UItest</div>;
}

export default MyComponent;
src/myComponent.module.css
.text_h1_bold_test {
    font-weight: bold;
    font-size: 30px;
}

.text_h2_test {
    font-size: 25px;
}

.text_highlight_test {
    color: #0048ff;
    font-weight: bold;
}

この記事で作れる環境で列記した通りになっていれば環境構築は終了です!
お疲れ様でした。

うまく動かない場合、chatGPTに聞くと解決できるかもしれません。(無責任)
コメントにエラー文などを書いていただけると手助けができるかもしれません。
特にtsconfigbaseUrlを変更した場合、既存のインポート文が使えなくなっている事があり、エラーになっているimport文を書き直す必要があります。

おわりに

最後まで読んでいただきありがとうございました!
css modulesを型安全に扱う上で型ファイルが邪魔すぎたので、それを解消できたのは大きいなと思っています。

もっと簡単にこの記事で作れる環境で列記した要素を満たせる方法がある場合教えていただけると嬉しいです!
また、本文中で不適切な部分がある場合、もっといいやり方がある場合も教えていただけると助かります🙇🏻‍♂️

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?