0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EmotionのCSSオブジェクトで未知のプロパティを検出する方法を試してみた

Posted at

はじめに

CSS-in-JS(Emotion、styled-components 等)を使用する際、以下のようなタイポに気付けないことがあります。

const style = {
  color: "red",
  colr: "blue", // タイポだがエラーにならない
};

通常のCSSであれば Stylelint によって未知のプロパティを検出できますが、StylelintではCSS-in-JSを解析するパッケージが非推奨になっています。

本記事では、Emotionを使用している環境で未知のCSSプロパティをエディタ上でインライン検出する方法について試した結果を共有したいと思います。

本記事で検出できるようにしたいこと

eslint-plugin-csscss/no-unknown-property ルールを使用して、オブジェクト形式の CSS の「未知のプロパティ」をエディタ上でインライン検出します。

書き方別の検出方法一覧

パターン 必要な設定 検出ルール
css={{ }} インライン attributes: ["css"] css/no-unknown-property
css({ }) 変数 defineFunctions@emotion/react を追加 css/no-unknown-property
オブジェクト変数 → css 属性 attributes: ["css"] css/no-unknown-property
  • attributes: JSX 属性に渡されたオブジェクトを CSS として解釈する
  • defineFunctions: 関数呼び出しの引数オブジェクトを CSS として解釈する

Stylelint が利用できない理由

Stylelint で CSS-in-JS を解析するには @stylelint/postcss-css-in-js が必要でしたが、本パッケージは 2023 年 2 月にアーカイブされ、非推奨となっています。

This syntax is deprecated. Please refer to the Stylelint v15 migration guide.

postcss-css-in-js README

npm でインストールを試みると、以下の警告が表示されます。

npm warn deprecated @stylelint/postcss-css-in-js@0.37.3:
Package no longer supported.

公式情報:

また、Stylelint v16 との互換性がなく、実行時に以下のエラーが発生します。

TypeError: Cannot read properties of undefined (reading 'stringify')

(そもそも)Stylelint の対応範囲

仮に動作したとしても、Stylelint はテンプレートリテラル形式(css`...`)のみ解析可能であり、オブジェクト形式には対応していません。

// Stylelint 対象(テンプレートリテラル)
const style = css`
  color: red;
`;

// Stylelint 対象外(オブジェクト形式)
const style = css({
  color: "red",
});

eslint-plugin-css の導入

eslint-plugin-css は、CSS-in-JS のオブジェクト形式を ESLint で検証可能にするプラグインです。

インストール

npm install --save-dev eslint-plugin-css

ESLint 設定

// eslint.config.mjs
import * as cssPlugin from "eslint-plugin-css";

export default [
  // 他の設定

  cssPlugin.configs["flat/recommended"],
  {
    settings: {
      css: {
        target: {
          // css={...} 属性を検出対象に指定
          attributes: ["css"],
          // css({ }) 関数を検出対象に指定
          defineFunctions: {
            "@emotion/react": ["css"],
          },
        },
      },
    },
    rules: {
      // Emotionのネストセレクタ(&:hover など)を許可するように設定
      "css/no-unknown-property": [
        "error",
        {
          ignoreProperties: ["/^&/"], // & で始まるセレクタを許可
        },
      ],
    },
  },
];

eslint-plugin-css は CSS 標準プロパティのリストと照合してエラーを検出します。

Emotion では &:hover のようなネストセレクタをオブジェクトのキーとして記述できますが、css/no-unknown-property はこれを「プロパティ名」として解釈してしまうため、ignoreProperties で除外する必要があります。

構文 対処
ネストセレクタ &:hover, & > div ignoreProperties: ["/^&/"]
CSS変数 --primary-color ignoreProperties: ["/^--/"]

上記設定例では & で始まるネストセレクタを許可しています。CSS変数も使用する場合は以下のように追加してください。

ignoreProperties: ["/^&/", "/^--/"]

書き方パターン別の詳細

パターン 1: css={{ }}

<div
  css={{
    color: "red",
    colr: "blue",  // エラー
  }}
>

JSX の css 属性に直接オブジェクトを渡す形式です。インラインで検出されます。

パターン 2: オブジェクト変数

const style = {
  color: "red",
  colr: "blue",  // エラー
};

<div css={style}>

パターン 3: css({ }) 変数

const cssStyle = css({
  color: "red",
  colr: "blue", // エラー
});

設定: defineFunctions@emotion/react を追加
css() 関数の引数オブジェクトが自動的に検出されます。

補足:MUI を使用する場合

MUI の sx 属性も同様に検出対象に追加できます。eslint.config.mjsattributes"sx" を追加してください。

attributes: ["css", "sx"],

これにより、以下のようなコードでもタイポが検出されます。

import { Box } from "@mui/material";

<Box
  sx={{
    color: "red",
    colr: "blue",  // エラー
  }}
/>

おわりに

本記事は初心者が調査・検証した内容をまとめたものです。
より適切な方法や他のツールについてご存知の方がいらっしゃいましたら、コメントにてご教示いただけますと幸いです。


参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?