「Stylelint」「Prettier」を使ってコードの品質を高める【2023年版】

仕事で初めてStylelintを使うのですが、今まで使ったことがなく、なんとなくしか理解できていなかったので今回ドキュメントを読みながら使い方についてまとめてました。

また、合わせて普段拡張機能で使っていたPrettierと合わせて使う方法についてもまとめてみました。
拡張機能とnpmでインストールするPrettierって何が違うのかも良く分かっていなかったのでそのあたりも調査したので同じようになんとなく使っているかたの参考になれば幸いです。

Stylelintを初めて使うので、ベストプラクティスでなかったり現場では使用しない書き方などがあるかもしれません。
なるべく正しい情報をお届けしようとは思っておりますが、ご容赦ください。

本記事の信頼性

30歳から異業種への転職をして、Shopify Experts企業で1年半ほどフルリモートで勤務していました。
現在は名古屋の自社開発企業のフロントエンドエンジニアしています。フリーランスとしても活動しています。

スポンサーリンク

目次

Stylelintとは

公式ドキュメントには下記のようなことが書いてあります。

  • CSSやSCSSの構文をチェックするツールです。
  • 自動修正機能
  • 共有可能な設定

では、どんな構文をチェックすることができるのかというと、

  • 1行あけるのかどうか
  • カラーコードのcolor: red;の指定の可否
  • プロパティの順番

などです。CSSはかなり色々な記述ができるので、実装者によってバラバラになりがちなことを統一することができます。

Stylelintのメリット
  • CSSやSCSSの記述にルールを設けることで、コードの品質を高めることができる。
  • プロパティの記述方法や順番などを気にせずにもっと本質的な実装部分について時間を使える。
  • チーム間でルールを共有することができる。
  • コードレビューするときに、コーディング規約に沿って実装されているのかについてチェックする必要がなくなる。

正しく使うことができれば、受けられる恩恵はかなりありそうです。

ゼロからStylelintを使ってみる

まずは、新規プロジェクトに対して、Stylelintを使ってみよう思います。
ベースはStylelintの公式サイトに沿って行っていきます。

npmが使えることが前提となっております。記事執筆時点のオカログ環境は以下。
npm 8.19.3
node v19.0.1

プロジェクトの作成とインストールする

今回は、okalog-stylelintとはフォルダを作成します。

下記コマンドでstylelintstylelint-config-standardのパッケージをインストールします。

npm install --save-dev stylelint stylelint-config-standard
npm
stylelint A mighty CSS linter that helps you avoid errors and enforce conventions.. Latest version: 16.4.0, last published: 2 days ago. Start using stylelint in your proj...
npm
stylelint-config-standard Standard shareable config for Stylelint. Latest version: 36.0.0, last published: 4 months ago. Start using stylelint-config-standard in your project by running ...

そうすると、下記のようにファイルやnode_modulesフォルダがインストールされてきます。

okalog-stylelint
├ node_modules
├ package-lock.json
└ package.json

package.jsonの中身を確認すると、インストールされたパッケージのバージョンを確認することができます。

{
  "devDependencies": {
    "stylelint": "^15.1.0",
    "stylelint-config-standard": "^30.0.1"
  }
}

まだ、これだけでは、stylelintを使用することができないので、設定ファイルを作成します。

.stylelintrc.jsonファイルをプロジェクト直下に作成して下記のように記述します。

{
  "extends": "stylelint-config-standard"
}
考える人

stylelint-config-standartって何?

stylelintの基本的な設定を記述しているものになります。

Githubを見ると下記のような記述があり基本設定内容を確認することができます。

設定の中身を確認する(クリックすると確認できます。)
'use strict';

module.exports = {
	extends: 'stylelint-config-recommended',
	rules: {
		'alpha-value-notation': [
			'percentage',
			{
				exceptProperties: [
					'opacity',
					'fill-opacity',
					'flood-opacity',
					'stop-opacity',
					'stroke-opacity',
				],
			},
		],
		'at-rule-empty-line-before': [
			'always',
			{
				except: ['blockless-after-same-name-blockless', 'first-nested'],
				ignore: ['after-comment'],
			},
		],
		'at-rule-no-vendor-prefix': true,
		'color-function-notation': 'modern',
		'color-hex-length': 'short',
		'comment-empty-line-before': [
			'always',
			{
				except: ['first-nested'],
				ignore: ['stylelint-commands'],
			},
		],
		'comment-whitespace-inside': 'always',
		'custom-property-empty-line-before': [
			'always',
			{
				except: ['after-custom-property', 'first-nested'],
				ignore: ['after-comment', 'inside-single-line-block'],
			},
		],
		'custom-media-pattern': [
			'^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
			{
				message: (name) => `Expected custom media query name "${name}" to be kebab-case`,
			},
		],
		'custom-property-pattern': [
			'^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
			{
				message: (name) => `Expected custom property name "${name}" to be kebab-case`,
			},
		],
		'declaration-block-no-redundant-longhand-properties': true,
		'declaration-empty-line-before': [
			'always',
			{
				except: ['after-declaration', 'first-nested'],
				ignore: ['after-comment', 'inside-single-line-block'],
			},
		],
		'font-family-name-quotes': 'always-where-recommended',
		'function-name-case': 'lower',
		'function-url-quotes': 'always',
		'hue-degree-notation': 'angle',
		'import-notation': 'url',
		'keyframe-selector-notation': 'percentage-unless-within-keyword-only-block',
		'keyframes-name-pattern': [
			'^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
			{
				message: (name) => `Expected keyframe name "${name}" to be kebab-case`,
			},
		],
		'length-zero-no-unit': [
			true,
			{
				ignore: ['custom-properties'],
			},
		],
		'media-feature-name-no-vendor-prefix': true,
		'number-max-precision': 4,
		'property-no-vendor-prefix': true,
		'rule-empty-line-before': [
			'always-multi-line',
			{
				except: ['first-nested'],
				ignore: ['after-comment'],
			},
		],
		'selector-attribute-quotes': 'always',
		'selector-class-pattern': [
			'^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
			{
				message: (selector) => `Expected class selector "${selector}" to be kebab-case`,
			},
		],
		'selector-id-pattern': [
			'^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
			{
				message: (selector) => `Expected id selector "${selector}" to be kebab-case`,
			},
		],
		'selector-no-vendor-prefix': true,
		'selector-not-notation': 'complex',
		'selector-pseudo-element-colon-notation': 'double',
		'selector-type-case': 'lower',
		'shorthand-property-no-redundant-values': true,
		'value-keyword-case': 'lower',
		'value-no-vendor-prefix': [
			true,
			{
				// `-webkit-box` is allowed as standard. See https://www.w3.org/TR/css-overflow-3/#webkit-line-clamp
				ignoreValues: ['box', 'inline-box'],
			},
		],
	},
};

上記の設定をベースにCSSをチェックすることになります。

次にstyle.cssを作成して適当に下記のような記述をしてみてコマンドを叩いて見ます。

.hoge {
  color: red;
}
.fuga {
  color: yellow;
}
.piyo{
  color: blue;
}
npx stylelint "**/*.css"

Expected empty line before ruleというエラーが出ており、設定元が表示されておりますね!

エラー内容: Expected empty line before rule
ルール: rule-empty-line-before

エラーを読むと、空白行を入れるというのがわかりますね。stylelint-config-standardで設定されている内容は下記の部分です。

'at-rule-empty-line-before': [
  'always',
    {
		  except: ['blockless-after-same-name-blockless', 'first-nested'],
		  ignore: ['after-comment'],
	  },
],

※設定されている内容は公式で確認可能なので興味あれば読んでみてください。

あわせて読みたい
rule-empty-line-before | Stylelint Require or disallow an empty line before rules.

4行目の方にだけ空白行を入れて再度コマンドを叩いてみるとエラーが解消されたのがわかりますね。

.hoge {
  color: red;
}

.fuga {
  color: yellow;
}
.piyo{
  color: blue;
}
考える人

けど、プロジェクトで

最初にも言ったように、このルールはstylelint-config-standardに沿って設定されています。
プロジェクトによっては、CSSのクラス間に余白は入れたくないなどといったことがでてくると思います。

そのときには、下記のようにルールを追加することで設定を変更することができます。

{
  "extends": "stylelint-config-standard",
  "rules": {
    "rule-empty-line-before": null
  }

先程まででていたエラーがでなくなると思うので、試してみてください^^

ちなみに、全て自分で設定を書いていくという場合には、extendsの部分は記述せずにrulesのところにだけ設定を加えていけます。既存プロジェクトとかにも導入するのであれば、意外とこれのほうがいいのかなー思ったりしています。

{
  "rules": {
    "rule-empty-line-before": null
  }
}

また、ここまではエラー内容が確認できる状態だけのコマンドでしたが、実はオプションをつけることで自動で修正してくれます。

npx stylelint "**/*.css" --fix
あわせて読みたい
Options | Stylelint Options shared by the:

CSSの順番を変更する「stylelint-config-recess-order」

CSSってどの順番で書いても問題なく動きますよね。いいっちゃいいのですが、ここも揃っているとよりリーダブルなコードになります。そのためのパッケージが用意されているので入れておきましょう。

npm
stylelint-config-recess-order Recess-based property sort order for Stylelint.. Latest version: 5.0.1, last published: 10 days ago. Start using stylelint-config-recess-order in your project b...
npm install --save-dev stylelint-config-recess-order

次に、stylelintrc.json"stylelint-config-recess-order"を追加します。

"extends": ["stylelint-config-standard", "stylelint-config-recess-order"]

適当にstyle.cssにCSSを書いてみます。

.hoge::before {
  content: "";
  display: inline-block;
}

.hoge {
  flex-direction: column;
  display: flex;
  background-color: yellow;
  color: red;
}

.fuga {
  color: yellow;
}

.piyo {
  color: blue;
}

コマンドを叩くと、

おぉ自動で並び替えてくれました!これはよい!!!!

デフォルトはプロパティ順になっています。recessというものに基づいているようですが詳しくは理解できていません…

VSCodeの拡張機能「Stylelint」を導入する

上記まででも便利ですが、怠惰なエンジニアはこう思うわけです。

考える人

毎回コマンド入力するのがめんどくさい

いちいちコマンド入力するのめんどくささいですよね...。そんなときは、VSCodeの拡張機能がオススメです。

ExtensionsからStylelintと検索してインストールしてください。
インストール後、一度読み込むためにリロードする必要があるのでリロード(再起動)してください。

そうすると、いままでコマンド叩くことでしか確認することができなかったエラーが確認できるようになります。

ちなみに、このときに入れた拡張機能Stylelintはconfigファイル(.stylelintrc.json)を参照するので設定値を変えれば拡張機能が検出してくれるエラー内容も変わります。

これでより良い開発体験を得ることができそうです。

Prettierを導入してフォーマットをする

次にPrettierを導入してフォーマットをしていきます。
他の方が書いた古い記事などを見ながらやると混乱してしまったので、公式を確認するようにします。

Stylelint v14以前では、StylelintとPrettierの競合を避けるためにstylelint-config-prettierなどを導入しないといけなかった。
けど、Stylelint v15以降であれば、特に必要なくなったそうです。

v15に以降した際の変更点についてまとめたもの

ということで、これからはPrettierのみを入れれば問題ないようです。

では、prettierを入れていきます。

npm install --save-dev prettier

一度、package.jsonを確認します。

{
  "devDependencies": {
    "prettier": "^2.8.4",
    "stylelint": "^15.1.0",
    "stylelint-config-standard": "^30.0.1"
  }
}

ここでコマンドを叩いてみます。

npx prettier --write .

npx prettier --write .は全てのファイルを意味します。
特定のファイルのみ、フォーマットをかけるのであれば、npx prettier --write style.cssのように指定します。

説明のためにnpx prettier --write .コマンドを実行したのですが、本来であればnode_modulesなどはフォーマットの対象外にします。その際に、自動でフォーマットさせたくないファイルを.prettierignore ファイルで指定しておくことができます。

あわせて読みたい
Ignoring Code · Prettier Use `.prettierignore` to ignore (i.e. not reformat) certain files and folders completely.
node_modules
package-lock.json

のように記述しておくといいはず…です!

考える人

あれっstyle.cssにはまだstylelintのエラーが残っている…

そうです、実は先程やったフォーマットは別にstylelintに沿った形でフォーマットしているわけではないので別途パッケージを入れる必要があります。

npm install --save-dev stylelint-prettier

下記にも追加します。

{
  "plugins": ["stylelint-prettier"],
  "extends": ["stylelint-config-standard"],
  "rules": {
    "prettier/prettier": true
  }
}

コマンドを叩きます。

npx prettier --write .

正しくフォーマットされたようです!よさそうです^^

ただ、プロジェクトによって設定を変えたいときがあると思います。
そのときには、.prettierrcファイルを作成して上書きすることで設置を変更することが可能です。

基本デフォルトで良さそうですが、僕はprintWidthだけ変えています。

{
  "printWidth": 120
}
あわせて読みたい
Options · Prettier Prettier ships with a handful of format options.

VSCodeの拡張機能「Prettier」を導入する

Stylelintのときと同様に、毎回コマンド叩くのはめんどくさいですよね。

VSCodeを使っていれば拡張機能が用意されています。検索でPrettierと入れれば拡張機能がでてくるのでインストールします。

次に、保存時に変更が効くようにしておきます。

  1. Format on Saveで検索して、チェックを入れます。
  2. default formatterをPrettierに変更する。

実際にフォーマットされるのか見てみます。

オカ

かなり快適になりました!

コマンドをまとめる

VSCodeで基本は整形されるようになったし、Stylelintでもチェックできるようになりましたが、チーム開発の際には同じエディターを使っている保証はありません。

なので、必ずnpmコマンドで実行するようにしたほうが安全です。

stylelint "*/.css"prettier --write .をまとめるために、pacakge.jsonに追記します。

{
  "scripts": {
    "format": "stylelint style.css --fix && prettier --write ."
  },
  "devDependencies": {
    "prettier": "^2.8.4",
    "stylelint": "^15.1.0",
    "stylelint-config-standard": "^30.0.1",
    "stylelint-prettier": "^2.0.0"
  }
}

これで下記コマンドでエディターに依存せずに同じようにファイルを管理することができます。

実際に実行した結果です。

対象のファイルなどはご自身の環境に合わせて設定してください。

既存プロジェクトに導入してみる

こちらも合わせて本記事に書いていこうと思ったのですが、冗長になりすぎそうなので、別記事を書いていきます。

また、記事が書けたらアップしますのでお待ち下さい。

まとめ

自分でまとめていくことでかなり理解を深めることができました。

品質を担保したコードを書けるようにするというよりも、仕組みで対応できるようにすることが重要だと思うようになったのでこれからのプロジェクトには導入していこうと思います。

また、今回はSCSSやCSSの順番を整形するパッケージなどについては書ききれていないので別の記事で書いていこうと思います。

参考記事

こちらの記事非常にわかりやすかったので紹介になります。

AI can fly !!
【Prettier】「なんとなく使う」から「分かって使う」へ【Visual Studio Code】 - AI can fly !! フロントエンドのコードフォーマッターのデファクトスタンダードである Prettier についてまとめました。 Visual Studio Code の Prettier 拡張機能の使い方についても併せ...

スポンサーリンク

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
目次