LoginSignup
7
5

More than 3 years have passed since last update.

create-react-appでsass導入 + stylelint

Posted at

create-react-appをベースにeslint(airbnb)とprettierを導入 の続編。css周りも改良したくなり、sass(scss)を使えるようにした。(ついでにcss-modulesも試した)
更にstylelintを利用して*.css, *.scssファイルのフォーマットチェックを行い、prettierと連携させて自動整形出来るようにした。

0. 前提条件など

検証環境:

  • Linux(Ubuntu20.04LTS)
  • node 14.16.0
    • npm6.14.11

prettierが予め入っている状態にしたいので、前回の最終形からスタートする。

1. css周り改善

  • sass: https://sass-lang.com/
    • cssの完全上位互換なので、既存の*.cssファイルを*.scssにそのまま置き換えるだけで移行出来る
  • css-modules: https://github.com/css-modules/css-modules
    • あくまで擬似的にだがcssをモジュール化することができ、ファイル分割の際にファイル間でのidやクラス名のバッティングによる意図しない挙動を減らすことが出来そう
    • create-react-appでは標準でサポートされており、別に設定作業は必要無いがついでで試してみる

1-1. sass導入

node-sassをインストールすればOK

npm i node-sass

なお、やや古くから使っている環境で↑をやろうとする(最新版のnode-sassを入れようとする)と、バージョン不整合でエラーが起こることがある。そうした場合、
https://stackoverflow.com/questions/64625050/error-node-sass-version-5-0-0-is-incompatible-with-4-0-0 などを参考に少し古いバージョンのnode-sassを入れることで対処出来る。

create-react-appの場合、node-sassをインストールしておけばそのまますぐにsassを使い始めることができ、例えばsrc/以下にある
index.cssおよびApp.cssをそれぞれindex.scss, App.scssにリネームし、
index.jsおよびApp.jsにおけるimport文を修正(import 'index.css'import 'index.scss'といった感じ)で移行出来る。
(勿論cssも以前通りに使い続けることが出来る)

1-2. css-modules

sassと併用できる。
試しに簡単なファイルを追加して試してみる。

# before
$ tree src
src
├── App.js
├── App.scss
├── App.test.js
├── index.js
├── index.scss
├── logo.svg
├── reportWebVitals.js
└── setupTests.js

# after
$ tree src
src
├── App.js # 編集
├── App.scss
├── App.test.js
├── dummy.module.scss # 追加
├── index.js
├── index.scss
├── logo.svg
├── reportWebVitals.js
└── setupTests.js

App.jsdummy.module.scssをimportしてみる。

dummy.module.scss
$color: #e30;
$dummy-test-color: #d0d;

.test {
  color: $color;
}

.dummy-text {
  color: $dummy-test-color;
}

ごくシンプルな例だが、sassの機能を使うために一応変数を使ってみている。

App.js
import logo from './logo.svg';
import './App.scss';
import styles from './dummy.module.scss'; // 追加

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
        {/* 追加始まり */}
        <div className={`test-class ${styles.test}`}>
          hello css-modules with sass
        </div>
        <div className={styles['dummy-text']}>
          dummy-text
        </div>
        {/* 追加終わり */}
      </header>
    </div>
  );
}

export default App;

create-react-appで自動生成されるお馴染みのコードを少し編集して、dummy.module.scssからインポートしたスタイルをあてがっている。
css-modulesを使う場合の注意点(面倒な点)として、クラス名がハイフン-を含んでいたりすると単純なドット.でクラスを呼び出せないので、上記の例ではstyles['dummy-text']のようにしている。また、一つのclassName内に複数のクラスを割り当てることもあるが、そのような場合は{}とバッククウォートで囲ってあげるなどの必要がある。(上の例でtest-classは別に何の意味もないが、複数クラスを書く場合の例として書いている。)

上記のようにしてnpm run startなどとすると、↓のようにdummy.module.scssから読み込んだスタイルをあてがったテキストを表示出来ていることが分かる:
image.png

2. prettier, stylelintの設定

prettierはcssやscssにも使えるようなので設定してみる。
https://wemo.tech/3307 の後半部分を大幅に参考にさせて頂いているが、自分用の整理として一応書いておく。

npmで必要なパッケージをインストール

npm i -D stylelint-prettier stylelint-config-prettier stylelint-scss 

# 必要に応じて設定をインストール(今回はstandard)
npm i -D stylelint-config-standard

なおstylelint-config-standardに関して、本当はstylelint-config-airbnbを入れようとしていた(eslint設定がairbnbだったため)が、バージョンが0.0.0だったり、最後のアップデートが3年前だったりしたので今回は見送った。

次に、 https://stylelint.io/user-guide/configure を参考にstylelintの設定ファイルを作成する必要がある。
yaml, jsonなどの選択肢もあるが、今回は.stylelintrc.jsを作成する。

.stylelintrc.js
module.exports = {
  plugins: ['stylelint-scss'],
  extends: [
    'stylelint-config-standard',
    'stylelint-prettier/recommended',
  ],
  rules: {
    'at-rule-no-unknown': null,
    'scss/at-rule-no-unknown': true,
  }
};
  • sassを使うので、pluginsstylelint-scssを入れている
  • stylelintとprettierの連携については、 https://github.com/prettier/stylelint-prettier の通りに行う
  • sassを使う際に不要なエラーが出ないようにrules以下を設定している

これでstylelintをlinterとして使えるようになっている。
(他にも必要であればstylelint-orderなど、適宜追加していったりする)

また、前回はnpm run format*.js, *.jsxがprettierで整形されるようにしていた。
package.jsonscript部分を編集して、

package.json(抜粋)
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "format": "prettier --write ./src/**/*.{js,jsx,css,scss}"
  },

のようにすることで、*.css, *.scssファイルも一緒にprettierでフォーマット出来るようになる。

3. まとめ

前回記事と合わせると、プロジェクトのルートディレクトリ直下のファイルなどは

$ tree -a -L 1
.
├── .env.development
├── .env.production
├── .eslintrc.js
├── .git
├── .gitignore
├── .prettierrc.js
├── .stylelintrc.js # 追加
├── README.md
├── node_modules
├── package-lock.json # 変更(但し自動で変更されるので意識しない)
├── package.json # 変更
├── public
└── src # 必要に応じて変更(cssをscssに置き換える、css-modulesに則ったファイルを追加するなど)

といった感じ。

ここで、最終的なpackage.jsonがあるとnpm iなどで一気に必要なライブラリをインストール出来るなど後で便利なので、自分用に置いておく:

package.json
{
  "name": "test-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/user-event": "^12.8.3",
    "node-sass": "^5.0.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.1.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "format": "prettier --write ./src/**/*.{js,jsx,css,scss}"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "eslint": "^7.22.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-react": "^7.22.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "prettier": "^2.2.1",
    "stylelint": "^13.12.0",
    "stylelint-config-prettier": "^8.0.2",
    "stylelint-config-standard": "^21.0.0",
    "stylelint-prettier": "^1.2.0",
    "stylelint-scss": "^3.19.0"
  }
}

参考

7
5
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
7
5