汚いコード書いてない?フロントエンダー必須のPostCSS+Stylelintがいい感じ

2016/06/15

Pavels Jelisejevs

18

Articles in this issue reproduced from SitePoint
Copyright © 2016, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2016, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

チームでCSSを書くなら、コードをなるべくきれいに保ちたいもの。CSS変換ツールとして注目を集めるPostCSSとStylelintを使えば、効率よく実現できそうですよ。

「コード品質」は、プログラマーにとって目新しいものではありません。開発者は、コードがただ機能するだけでは不十分だと知っています。コードは読みやすく、明快な構成で、一貫性があるべきです。また、ある一定の評価指標に沿っている必要があります。

あいにく、この点はCSSを書く際に見落とされがちです。理由を長々と話してもよいのですが、重要な点は、CSSもJavaScriptやPHPなどと同様のコードであり、その書き方には気をつけるべきだということです。そうしないと、より複雑な事態を招きかねません。

記事では、「PostCSS」というツールを使ってCSSコードを高品質に保つ方法を説明します。最初に「より良いCSSコード」とは実際どのようなものであるか、注意すべき点をいくつか挙げます。

  • コードのスタイルに一貫性があること - クラス名、改行位置、プロパティの一覧は好きに選択できますが、それをスタイルシートで一貫した形にする必要があります。首尾一貫したスタイルは読みやすいだけでなく、コードを理解しやすくします。
  • コードは一定の基準に従うこと - たとえば、あるセクターの最大精度やページで使用される色数など、測定可能で一定のしきい値を保つ指標があります。
  • ハッキングを回避すること - !important命令のような概念は便利な方法に見えますが、たいていコードをより複雑にするだけです。

もちろんこれで全部ではありませんが、記事では上記の問題点に注目します。あたりまえのことですが、いろいろなスキルを持つ人のいる大きなチームで一大プロジェクトに取り組むときには、このような問題点を容易に見過ごしてしまうことがあります。必要なのは、基準を自動的に強化するコード分析ツールです。そこでPostCSSの出番です。

PostCSSの活用法

前回のPostCSSの記事では、PostCSSとは何か、さまざまな用途に使えるプラグインの利用方法を紹介しました。今回は、CSSコードの品質を最高レベルに保つのに役立つPostCSSプラグインに着目します。

事例用のサンドボックスプロジェクトを設定しましょう。前回の記事で紹介したコマンドラインでPostCSSを使用する方法ではなく、代わりにGulpを使用します。新規フォルダーを作成し、npmプロジェクトを起動します。そのあと、GulpとPostCSSプラグイン、PostCSSプラグインのアウトプット表示をするreporterプラグインをインストールします。新規作成したプロジェクトを表示して、次のコマンドを実行します。

npm i gulp gulp-postcss postcss-reporter --save-dev

それから、空のstyle.cssファイルと次のようなgulpfile.jsを作成してください。

var gulp = require('gulp');
gulp.task('analyze-css', function () {
  var postcss = require('gulp-postcss');
  var reporter = require('postcss-reporter');

  return gulp.src('style.css')
    .pipe(postcss([ 
      reporter()
    ]));
});

gulpfile.jsは、style.cssの内容をスキャンして、一連のPostCSSプラグインを実行するタスクを定義しています。すぐにgulp analyze-cssを実行できますが、レポート内容が浅いプラグインしかないのであまり役に立たないでしょう。lintプラグインを追加していきましょう。

Stylelint

これまでにも各言語でlintするプログラムはありましたが、CSSも例外ではありません。Stylelintを使えば、一貫性のある書式設定、特定のルール、単位またはディレクティブの使用方法、(不正な色など)の潜在的なミスなどについて定義済みのルールで、CSSコードを検証できます。また、100以上のルールを定義することができ、そのルールの中には、たとえば、セレクターとその次の波括弧の間にスペースが入っているかどうかや、引用符が片方しかないことを指摘するといった基本的なものもあります。さらに興味深い例をいくつか挙げます。

  • property-blacklistunit-blacklistを使うと、使用不可のプロパティと単位のリストを表示できます。
  • property-no-vendor-prefixは、Can I useサイトのデータに基づいて、ベンダープレフィックスを必要としないプロパティに対するベンダープレフィックスの使用について警告します。
  • declaration-no-importantは、!important命令の使用を禁止します。
  • selector-max-specificityは、セレクターの詳細度の上限を設定します。

Stylelintではルールがデフォルトですべて無効になっているので、自分でルールを設定しなければなりません。設定量を考慮すると、かなりの時間がかかります。ほかには、stylelint-config-standardのような既定のconfigを使ったルールセットから拡張する方法もあります。

Stylelintで基本ルールセットを使えるように設定しましょう。

npm i stylelint stylelint-config-standard --save-dev

新しいプラグインを有効にするため、次のようにgulpfileを拡張する必要があります。

var gulp = require('gulp');
gulp.task('analyze-css', function () {
  var postcss = require('gulp-postcss');
  var stylelint = require('stylelint');
  var reporter = require('postcss-reporter');

  return gulp.src('style.css')
    .pipe(postcss([
      stylelint(), 
      reporter()
    ]));
});

Stylelintのルールはgulpfileのインラインで設定できますが、私は別ファイルに保存する方が好きです。プロジェクトフォルダーに次のような.stylelintrcファイルを作成してください。

{
  "extends": "stylelint-config-standard"
}

このファイルで、Stylelintは基本のconfigに基づいたルールセットを使用します。style.cssファイルを更新し、まだ一定のルールで書かれていないCSSファイルでプラグインを試してみましょう。

.title,.content{ 
  background: #FFFFFF; 
  font-size:0.9em;


  margin: 0;
}

gulp analyze-cssを実行すると、誤り箇所の一覧が表示されます。

style.css
1:7    Expected newline after "," (selector-list-comma-newline-after) [stylelint]
1:15   Expected single space before "{" (block-opening-brace-space-before) [stylelint]
1:17   Expected newline after "{" of a multi-line block (block-opening-brace-newline-after) [stylelint]
1:17   Unexpected whitespace at end of line (no-eol-whitespace) [stylelint]
2:5    Expected indentation of 2 spaces (indentation) [stylelint]
2:17   Expected "#FFFFFF" to be "#ffffff" (color-hex-case) [stylelint]
2:17   Expected "#FFFFFF" to be "#FFF" (color-hex-length) [stylelint]
2:25   Expected newline after ";" in a multi-line rule (declaration-block-semicolon-newline-after) [stylelint]
2:25   Unexpected whitespace at end of line (no-eol-whitespace) [stylelint]
3:5    Expected indentation of 2 spaces (indentation) [stylelint]
3:15   Expected single space after ":" with a single-line value (declaration-colon-space-after) [stylelint]
4:4    Unexpected whitespace at end of line (no-eol-whitespace) [stylelint]
5:4    Unexpected whitespace at end of line (no-eol-whitespace) [stylelint]
6:5    Expected indentation of 2 spaces (indentation) [stylelint]
7:1    Unexpected missing newline at end of file (no-missing-eof-newline) [stylelint]

このプラグインを使用すると、CSSを書くよい練習になります。ルールを理解し、納得のいかない基本configのルールを無効にしていきましょう。できあがったルールリストはあとで、プロジェクトやチームに配布できます。必要なルールがなければ、いつでも付け加えられます。

Do I Use

CSSを書くときに苦労することは、対象とするブラウザーの種類や、使う機能の種類を念頭に置かなければならないことです。Do I Useは、CSSが対象ブラウザーでサポートされているかを確認するのに役立つプラグインです。サポートしたいブラウザーを決めたあとプラグインを実行すると、コードをスキャンし、Can I useサイトのデータに基づいてCSSを検証し、非サポートコードがあればエラーを表示します。

このプラグインの使用はとても簡単です。次のようにインストールしてください。

npm i doiuse --save-dev

続いて、gulpfileを更新します。

return gulp.src('style.css')
  .pipe(postcss([
    doiuse({
      browsers: ['ie >= 9', 'last 2 versions'],
    }),
    reporter()
]));

この設定は、IE9とそのバージョンアップ版というように、各ブラウザーの最新バージョン2つをサポートの対象としています。

結果を表示するため、グリッドレイアウトモジュールを使っている、架空の新規CSSでプラグインを実行します。

body {
  display: grid;
  grid-columns: 200px 1% 1fr;
  grid-rows: auto 15px auto 15px auto;
}

以下のように、結果が示されます。

style.css
11:2      CSS3 Multiple column layout not supported by: IE (9), Firefox (43,44), Chrome (48,49), Safari (8,9), Opera (34,35), iOS Safari (8.1-8.4,9.0-9.2) (multicolumn) [doiuse]

残念ながら、今のところCSSのグリッドモジュールはまだ完璧ではありませんが、長所に目を向けましょう。便利なツールのおかげで、ブラウザーの実装は追いかけられるのですから!

Immutable CSS

バグや複雑なスタイルシートの主な原因の1つは、CSSルールが無効にされているところがあることです。最新のデバッグツールを使っても、スタイルが無効にされている箇所やその理由を見つけるのが困難な場合もあります。そのため、スタイルを無効にするのではなく、むしろセレクターに変更を追加するほうが良いと考えられています。Immutable CSSプラグインは、スタイルが無効にされていることを警告してくれます。

プラグインの使い方には、2つの方法があります。デフォルトでは、複数のファイルでスタイルを無効にしようとすると、単に警告を発するだけです。複数のファイルが1つのファイルにまとめられると、スタイルの出所を見つけるソースマップを利用します。これは、Sassのインポートまたはpostcss-importプラグインを上手に利用する方法です。別の方法として、厳格モードを有効にして、1つのファイルのみでスタイルが無効にされた場合にも警告されるようにもできます。

以上のことを次の簡単な例で確かめましょう。はじめにプラグインをインストールします。

npm i immutable-css --save-dev

gulpfileでプラグインを厳格モードで有効化します。

return gulp.src('style.css')
  .pipe(postcss([
    immutableCss({
      strict: true
    }),
    reporter()
  ]))

少し難解なCSSで確かめてみましょう。

.title {
  color: blue;
  font-weight: bold;
}

.title {
  color: green;
}

.article .title {
  font-size: 1.2em;
}

するとプラグインが、.titleクラスが変更されたと表示します。

  .title was mutated 3 times
[line 1, col 1]: /Users/pavels/Documents/projects/sandbox/postcss/style.css
[line 6, col 1]: /Users/pavels/Documents/projects/sandbox/postcss/style.css
[line 10, col 1]: /Users/pavels/Documents/projects/sandbox/postcss/style.css

immutable-cssでは、プラグインを使っていろいろと遊ぶことができます。

CSS StatsList Selectors

紹介する最後の2つのプラグインは、CSS statsList Selectorsです。今まで検証してきたプラグインとは少し違い、問題点を指摘するのではなく、カスタム分析のためのデータを提供してくれるものです。

CSS statsは通常、使用されているルールやセレクター、宣言の数や内容、セレクターの標準的な特徴、コード内で要求されるフォントサイズなど、スタイルシートについて広範にわたる情報を提供します。ここにあげた項目は、レポートに書かれている情報の一例にすぎません。より詳しい記述はits GitHub pageに載っています。また、プラグインからのデータを利用して作成されるレポート例を見るには、cssstats.comを参照してください。

List Selectorsはさらにシンプルなプラグインで、スタイルシートで使われているセレクターのリストを抽出し、クラスセレクターや属性、ID、タグなど、カテゴリーごとに分類します。

この2つのプラグインは、次の例のようにさまざまなコード分析に使われています。

  • 特徴やサイズ、使用される数の一定のしきい値
  • セレクターがすべてコーディングスタイルに沿っているかの確認
  • メディアクエリに一貫性があるかの確認

以上、思いついたことを少し書きました。さらに実践的なアプローチとしては、ここで紹介したプラグインをすべてセットアップした結果から、より有益な情報を得られるように検証することです。

終わりに

コードのlintと分析は、PostCSSを使用する1つの方法に過ぎませんが、それでも時間を節約したり、開発者の苦労を軽減したり、開発プロセスに大きな価値をもたらしてくれるものです。他のプログラミング領域では常識になりつつありますが、CSSに関してはまだ軽視される傾向があります。PostCSSと紹介したプラグインで、開発はより容易になり、信頼性も高まるでしょう。

(原文:Improving the Quality of Your CSS with PostCSS

[翻訳:Noriko O. Romano]
[編集:Livit

Image:solkanar / Shutterstock.com

Copyright © 2016, Pavels Jelisejevs All Rights Reserved.

Pavels Jelisejevs

Pavels Jelisejevs

ラトビア、リガ出身のソフト開発者で、Web全般に強い関心があります。興味の対象は、分析やオートメーションをはじめ、バックエンド・フロントエンド開発にも及びます。FacebookまたはLinkedInでいつでも相談に応じています。

Loading...