自動検出と自動修正でCSSを保守する

CSSの保守に便利なcsscombとscss-lintについて説明します。

scss-lint :hocho:

scss-lintは、SCSSのコードから与えた設定に違反している箇所を報告してくれるツールです。jslintやrubocopのSCSS版のようなものです。これをCI等で定期的に実行しておくことで、ルールに違反したコードの蔓延を防ぎます。

gem install scss-lint
scss-lint app/assets/stylesheets/**/*.scss

csscomb :hammer:

csscombはNode製のツールで、CSSのコードを与えた設定に従って自動で変換してくれるものです。scss-lintを初めて導入するときに利用すれば、大半の警告を自動で修正してくれるでしょう。但しCSSの文法しか解釈できないため、SCSSに適用すると失敗する場合があります。SCSSで書かれたファイルに対して適用してみたところ、@includeなどの文法は受理されるものの、@ifなどの文法を受理できないようです。しかしながら問題となるケースがそこまで多くないため、SCSSが対象でも十分実用に足るかと思います。csscombは .csscomb.json に記述された設定を元に動作しますが、 この設定内容は公式サイトで生成できます。

npm install csscomb -g
vi .csscomb.json
csscomb app/assets/stylesheets/**/*.scss

導入 :beginner:

既存のプロジェクトに導入する場合、大枠としては次のような流れになるでしょう。最初の目標はscss-lintから警告が出ないようにすることですから、最初はscss-lintで検閲する項目を極力減らしてCIが通るようにし、そこから徐々にscss-lintのルールを増やしつつ、漸近的に改善していくと良いでしょう。

  1. csscombで修正する
  2. scss-lintが警告を出さないようにする
  3. scss-lintをCIで動かす

体験 :speech_balloon:

最後に、Qiitaにcsscombとscss-lintを導入したときの話をしましょう。Qiitaでは最初、scss-lintを動かすと1,540件の警告が出ましたが、csscombを実行することで警告の数は数十件に減り、小一時間手作業で修正することで警告が出なくなったため、その段階でCIでscss-lintを走らせるように設定しました。csscombで修正できず手作業で直した警告内容は、ネストが深すぎるというものだけでした。また、csscombが受理できないSCSSの文法に出会したときにも次のファイルに進んでほしかったので、今回は雑にこういうコマンドを実行しました。

rails runner 'Dir.glob("app/assets/stylesheets/**/*.scss").each {|path| `scss-lint #{path}` }'

scss-lintにはRakeタスクが付属しているので、特にCIではこれを利用するのが良いでしょう。.scss-lint.ymlにscss_filesという設定があれば、rake scss_lint を実行することでscss-lintを実行できます。シェルのグロブの機能を利用できないCI等で役に立つかもしれません。なお、このRakeタスクは現在最新のv0.29.0では未だ満足に動作しないので、利用する場合はGitHub上のmasterブランチなどを利用しましょう。

# Define `rake scss_lint`
require 'scss_lint/rake_task'
SCSSLint::RakeTask.new

終わりに :bow:

CSSの保守に便利なcsscombとscss-lintについて説明しました。導入してみたところ思ったより良かったのでチームへの共有も兼ねて投稿しましたが、荒れ果てたCSSを持て余している方の参考になれば幸いです。