💅
styled-componentsでstylelintを使おう
業務でstylelintをstyled-componentsで使用する機会があったので備忘として書いておきます.
とりあえず導入する
-
styled-components公式を参考にとりあえず導入
yarn add -D stylelint \ stylelint-config-standard \ postcss-styled-syntax
-
.stylelintrc
を作成し,以下記述.stylelintrc{ "extends": [ "stylelint-config-standard", ], "customSyntax": "postcss-styled-syntax" }
-
package.json
にスクリプト追加package.json{ "scripts": { "lint:style": "stylelint '**/*.ts'", "lint:style:fix": "stylelint --fix '**/*.ts'", }, }
- これでスクリプトを実行すればstylelintが実行されるようになるはず.
ライブラリ追加する
今回はスタイルのプロパティをよしなにソートしてくれるライブラリを追加.
(stylelint-config-recess-order)
- インストール
yarn add -D stylelint-config-recess-order
-
.stylelintrc
に追記
.stylelintrc
{
"extends": [
"stylelint-config-standard",
+ "stylelint-config-recess-order", // ここ
],
"customSyntax": "postcss-styled-syntax"
}
ルールをカスタマイズしていく
おそらく必須
-
media-query-no-invalid
を無効に- stylelint公式ドキュメントで非推奨とされています.
ケースバイケース
-
no-empty-source
を無効に- 空白のコンポーネントを許可するルール
- 名前をつけて管理したい場合は許可してもいいかもしれない
-
stylelint-disable
とstylelint-enable
は対の関係にする- 一度コメントアウトで
disable
にしてしまうと再度enable
にするまでルールが無効化されてしまう. - 上記の問題を解決するためにプラグインを自作して使用しています.
- 以下のような挙動になります.
// エラーになる例(stylelint-enableをつけていない) export const $Title = styled.div` /* stylelint-disable */ color: red; font-size: 16px; `; // エラーにならない例(stylelint-enableをつけている) export const $Title = styled.div` /* stylelint-disable */ color: red; font-size: 16px; /* stylelint-enable */ `; // エラーにならない例(stylelint-enable-next-lineは次の行のみに適用されるためOK) export const $Title = styled.div` /* stylelint-disable-next-line */ color: red; font-size: 16px; `;
- 一度コメントアウトで
コード
// eslint-disable-next-line @typescript-eslint/no-var-requires
const stylelint = require("stylelint");
const ruleName = "plugin/check-disable-enable-pair";
const messages = stylelint.utils.ruleMessages(ruleName, {
disable:
"Found an unmatched `stylelint-disable` comment. Ensure every `stylelint-disable` is followed by a corresponding `stylelint-enable` comment.",
});
const reportError = (comment, result) => {
stylelint.utils.report({
ruleName: ruleName,
result: result,
node: comment,
message: messages.disable,
});
};
const stylelintDisableRule = () => {
return function (root, result) {
let lastDisableComment = null;
root.walkComments((comment) => {
const text = comment.text.trim();
if (/stylelint-disable-(next-line|line)/.test(text)) return;
if (text.startsWith("stylelint-disable")) {
// 既に無効化コメントがある場合はエラー
if (lastDisableComment) reportError(lastDisableComment, result);
lastDisableComment = comment;
}
// ペアが見つかった場合はリセット
if (text.startsWith("stylelint-enable") && lastDisableComment) lastDisableComment = null;
});
// ファイルの最後に無効化コメントが残っている場合はエラー
if (lastDisableComment) reportError(lastDisableComment, result);
};
};
module.exports = stylelint.createPlugin(ruleName, stylelintDisableRule);
module.exports.ruleName = ruleName;
module.exports.messages = messages;
- 他にも色々あるので見てみてください〜
まとめ
最終的な.stylelintrc
はこんな感じです
.stylelintrc
{
"extends": [
"stylelint-config-standard",
"stylelint-config-recess-order"
],
"plugins": ["プラグインまでのパス/check-disable-enable-pair"],
"rules": {
"media-query-no-invalid": null,
"no-empty-source": null,
"plugin/check-disable-enable-pair": true
},
"customSyntax": "postcss-styled-syntax"
}
備考
v15ではPrettierとの併用が推奨されたためPrettierの拡張は必要なくなった
参考:https://stylelint.io/migration-guide/to-15/
おまけ:VSCodeでのStylelint設定
- VSCodeにて拡張機能をインストール
-
settings.json
に追記する
settings.json
{
"stylelint.configFile": ".stylelintrcへの絶対パス",
"stylelint.packageManager": "yarn",
"stylelint.snippet": [
"typescript"
],
"stylelint.validate": [
"typescript"
],
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
},
}
- これで保存すると自動修正されるはず.
Discussion