クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る

Reactの続きです。前回はReactのいろいろなCSS設定方法を調べました。今回はその中の一つCSS Modulesを体験してみます。Create React AppにCSSとSass(SCSS)を読み込んで、ローカルスコープを作ります。それではいきましょう!

【目次】

※参考:前回記事
ReactのCSS設定方法について調べたこと(className属性、style属性、CSS Modules、CSS in JS、UIフレームワーク) - クモのようにコツコツと

※参考:Reactを習得するためにやったことまとめ
qiita.com

前回のおさらい

ReactのCSS設定方法、下記の違いについて調べた。

  1. className属性:CSSのclass名の設定をJSXのclassName属性に紐付ける
  2. style属性:style属性(インラインスタイル)でCSS設定を直接埋め込む
  3. CSS Modules:webpackのcss-loaderなどを使ってローカルスコープを作る
  4. CSS in JS:styled-componentsなどを使ってCSS構文の形でJS内に設定
  5. UIフレームワーク:Material UIなどを使って用意されたスタイルを当てはめる

このうち1と2は体験済み。今回は3のCSS Modulesを体験する。

※参考:ReactのCSS設定方法について調べたこと(className属性、style属性、CSS Modules、CSS in JS、UIフレームワーク) - クモのようにコツコツと

CSS Modulesとは

CSS ModulesはCSSを読み込んでコンポーネントごとにローカルスコープを作る方法。

※参考:ReactのCSS設定方法について調べたこと(className属性、style属性、CSS Modules、CSS in JS、UIフレームワーク) - クモのようにコツコツと

webpackのcss-loaderなどを使う。

※参考:css-loader | webpack

参考記事

※参考:CSSモジュール ― 明るい未来へようこそ | POSTD
※参考:https://qiita.com/_likr/items/c335dec5221024ad56bc: title
※参考:https://morishitter.hatenablog.com/entry/2015/09/28/103334: title

CSS ModulesはCreate React Appでは標準装備になっているようだ!

※参考:create-react-appで簡単にcss moduleが使えるようになってた。 - かぷかぷ笑う

Create React App環境を作る

Create React Appのインストール

以前こちらの記事で行ったようにCreate React Appをインストールする。

※参考:【React】Create React Appのプロジェクトの作成と実行(エラー対処も) - クモのようにコツコツと

ターミナルのcdコマンドでCreate React Appを入れたいフォルダに移動

cd /(フォルダ)/react_test

今回は「react_test」というフォルダに入れる

create-react-appをインストール。

$ npx create-react-app css-modules-test

最後の「css-modules-test」がプロジェクト名

入った!
f:id:idr_zz:20201211052327j:plain
「css-modules-test」というフォルダにファイル一式が入っている。

「package.json」を見るとcss-loaderとかは見当たらないのだけど、どうなんだべかー

  "dependencies": {
    "@testing-library/jest-dom": "^5.11.6",
    "@testing-library/react": "^11.2.2",
    "@testing-library/user-event": "^12.5.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1",
    "web-vitals": "^0.2.4"
  },

Create React Appを起動(エラーあり)

「css-modules-test」フォルダに移動

cd css-modules-test

プロジェクト起動

$ npm start

おっと、ここでエラーが起きた。。

To fix the dependency tree, try following the steps below in the exact order:

  1. Delete package-lock.json (not package.json!) and/or yarn.lock in your project folder.
  2. Delete node_modules in your project folder.
  3. Remove "babel-jest" from dependencies and/or devDependencies in the package.json file in your project folder.
  4. Run npm install or yarn, depending on the package manager you use.

babel-jestに問題がありそう。

調べたら前回同じ経験してた!ユーザー直下の「node_modules」フォルダにある「babel-jest」とバージョンが合わないのが問題だった。

※参考:【React】Create React Appのプロジェクトの作成と実行(エラー対処も) - クモのようにコツコツと

ユーザー直下の「babel-jest」と「jest」を削除(「jest」も同様のエラーになったため)。

「package.lock.json」と「node_modules」フォルダを削除して、パッケージを再インストール

$ npm install

「package.lock.json」と「node_modules」フォルダが再び作られる。

プロジェクト起動

プロジェクト起動リベンジ

$ npm start

起動した!localhostの3000番
f:id:idr_zz:20201211055203j:plain
クルクル回転ロゴ、また会えたね♪

「control + C」でいったんプロジェクトを終了。

CSS Modules(CSS編)

CSSファイルを作成

とにもかくにもCSSファイルを読み込んでみよう。こちらの記事を参考にしながら。

※参考:create-react-appで簡単にcss moduleが使えるようになってた。 - かぷかぷ笑う

Create React AppではCSSファイルのファイル名に「hoge.module.css」とファイル名と拡張子の間に「.module」を挟めばCSS Modulesと認識されるようだ。


「src」フォルダの中の「App.js」にCSSファイルを読み込みたい。

同一階層に「test.module.css」を作る。
f:id:idr_zz:20201211060326j:plain

「test.module.css」の内容

.text {
    color: red;
}

.testの文字色を赤に。どシンプルw。

CSSファイルを読み込み

「App.js」で「test.module.css」をインポート

import cssTest from './test.module.css';

cssTestという名前で。


App()コンポーネントの中でCSSを読み込む

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <!-- 中略 -->
        <p className={cssTest.text}>これはテストですと。</p>
      </header>
    </div>
  );
}

pタグのclassName属性をcssTestの中の.textセレクターに。

        <p className={cssTest.text}>これはテストですと。</p>

CSSのローカルスコープ作成

プロジェクト起動

npm start

f:id:idr_zz:20201211061426j:plain
おお!「これはテストですと。」が赤くなってますと!

レンダリングされたタグはこんな感じ

<p class="test_text__2Ykfa">これはテストですと。</p>

なるほど、この__2Ykfaという部分がランダムに作り出される文字列か。これで重複のないローカルスコープになるんだなー。

「control + C」でいったんプロジェクトを終了。

CSS Modules(Sass(SCSS)編)

node-sassをインストール

CSS ModulesはSass(SCSS)ファイルも読み込めるようなのでやってみる。

Sass(SCSS)についてはこちらを参照。

※参考:【LESS, SCSS, Sass, Stylus, PostCSS】 AltCSS 事始め - クモのようにコツコツと

Create React AppでSass(SCSS)のCSS Modules、こちらの記事を参考に。

※参考:create-react-appでSassやCSS-moduleを使う方法 - Qiita


Create React AppでSass(SCSS)を使うために「node-sass」パッケージをインストール

npm install node-sass

package.jsonを確認入った!

  "dependencies": {
    "@testing-library/jest-dom": "^5.11.6",
    "@testing-library/react": "^11.2.2",
    "@testing-library/user-event": "^12.5.0",
    "node-sass": "^5.0.0", // 追加
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1",
    "web-vitals": "^0.2.4"
  },

ちなみに以前、gulp環境ではgulp-sassをインストールしていた。

※参考:【CSS】Sass(SCSS)をGulpでコンパイルしてみる - クモのようにコツコツと

Sass(SCSS)ファイルの作成

次にSass(SCSS)ファイルを作成。「test.module.scss」というファイル名で。
f:id:idr_zz:20201211063014j:plain

「test.module.scss」の内容。

.text {
    color: yellow;
    &:hover {
        background: rgba(255,255,255,0.3);
    }
}

文字色は黄色にして、Sass(SCSS)の書式で:hoverを設定。

セレクターのclass名が先ほどのCSSファイルと同じ.textなので、普通に読み込むとcolor設定が重複するはず(後から読み込む方が優先される)

Sass(SCSS)の書式についてはこちらを参照。

※参考:【LESS, SCSS, Sass, Stylus, PostCSS】 AltCSS 事始め - クモのようにコツコツと

Sass(SCSS)ファイルを読み込み

「App.js」でtest.module.scssをインポート

import sassTest from './test.module.scss';

sassTestという名前で

App()コンポーネントの中でSass(SCSS)を読み込む。

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <!-- 中略 -->
        <p className={cssTest.text}>これはテストですと。</p>
        <p className={sassTest.text}>これはSassのテストですと。</p>

      </header>
    </div>
  );
}

最初のpタグの下に「これはSassのテストですと。」というpタグを追加

className属性をsassTestの中の.textセレクターに。

        <p className={sassTest.text}>これはSassのテストですと。</p>

さてどうなるか。

Node Sassをダウングレード(エラー対策)

プロジェクト起動

npm start

ありゃ、エラーになった。

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0.

こちらはGatsbyの例だが、Node Sassのバージョンに問題があるようだ。

※参考:Gatsby.js 【Node Sass version 5.0.0 is incompatible with ^4.0.0.】 エラーの対処法 - Qiita

package.jsonのnode-sassのバージョンを5から4に変更する。

    "node-sass": "^4.0.0", // ver 5 -> 4

ちなみにバージョン番号の前のキャレット^の意味

"一番左側にある、ゼロでないバージョニングは変えない (それ以下があがることは許容)"

チルダ~の場合は下記の意味

"明記したところ以下のバージョンがあがることのみ許容"

※参考:package.json のチルダ(~) とキャレット(^) - Qiita

「node_modules」フォルダを削除して、パッケージインストールを再実行

npm install

Sass(SCSS)のローカルスコープ作成

プロジェクト起動リベンジ!

npm start

おお、pタグが黄色になった!そして1行目のpタグが赤のまま。
f:id:idr_zz:20201211064358j:plain

カーソルを乗せるとhoverの背景色が適用されている。
f:id:idr_zz:20201211064543j:plain

レンダリングされたタグはこんな感じ

<p class="test_text__2Ykfa">これはテストですと。</p>
<p class="test_text__2aOg-">これはSassのテストですと。</p>

2番目のpタグには__2aOg-という文字列がついているため、1番目のpタグと重複しない。

デベロッパーツールでCSS設定を見るとscssファイルのままレンダリングされている模様。
f:id:idr_zz:20201211065029j:plain


今回作ったソースコード全体(GitHub)

※参考:GitHub - ryo-i/css-modules-test: CSS Modulesテスト

最後に

ということでCSS ModulesでCSSとSass(SCSS)のローカルスコープを作りました。

別ファイルで管理しつつ、コンポーネントの中で固有の文字列がふられてローカルスコープが作れるので、セレクタの命名はゆるくできそうです。Sass(SCSS)が使えるので共通するスタイル設定は変数や@mixinなどにするといいかなと思いました。

※参考:【Sass(SCSS)】変数($)、@mixinを使ってモジュールを超えた共通スタイルを設定する - クモのようにコツコツと

次回は、CSS in JSを体験してみたく思います。こちらはHTMLでいうJSXのようにJSファイル内に直接CSSスタイルを書く方法です。

それではまた!


続き書きました!

※参考:【React】styled-componentsでCSS in JSを事始める - クモのようにコツコツと


※参考:Reactを習得するためにやったことまとめ
qiita.com