Sassから完璧なCSSファイルを出力するためのgulpfile.jsの書き方や、必要なパッケージpackage.json、.stylelintrcへの記述についてです。
最初に言っておくと、完璧なという表現は完全に主観です!自分がWordPressサイトを作る上で、特に不満なく作れている方法ということだけご理解の上、読み進めていただければ幸いです。
また、「Gulpとは?」や「package.jsonの使い方」みたいな話はなく、知っている前提で進めていきます。ですので、ある程度gulpなど使い慣れている方でないと理解できないかもしれません。
導入すべきパッケージをドバドバーっと紹介していきます
gulpfile.jsに書くこと
Gulpで処理させている内容です。最初にどばーっとやっていることの概要を説明して、後から個別に処理内容を深掘りしていきます。
SassからCSS変換の過程でやっていること
大雑把には以下のようなことを行っています。字にするとめっちゃ簡単ですね!
- autoprefixerでベンダープレフィックスを付与する
- cssdeclsortでプロパティを並び替える
- gulpStylelint({fix: true})で自動整形
ソースは以下のような感じです。
var gulp = require( 'gulp' );
var sass = require( 'gulp-sass' );
var plumber = require( 'gulp-plumber' );
var notify = require( 'gulp-notify' );
var sassGlob = require( 'gulp-sass-glob' );
var mmq = require( 'gulp-merge-media-queries' );
var gulpStylelint = require( 'gulp-stylelint' );
var postcss = require( 'gulp-postcss' );
var autoprefixer = require( 'autoprefixer' );
var cssdeclsort = require( 'css-declaration-sorter' );
gulp.task( 'sass', function() {
gulp
.src( './sass/**/*.scss' )
.pipe( plumber({ errorHandler: notify.onError( 'Error: <%= error.message %>' ) }) )
.pipe( sassGlob() )
.pipe( sass({ outputStyle: 'expanded' }) )
.pipe( postcss([ autoprefixer() ]) )
.pipe( postcss([ cssdeclsort({ order: 'alphabetically' }) ]) )
.pipe( mmq() )
.pipe(
gulpStylelint({
fix: true
})
)
.pipe( gulp.dest( './css' ) );
});
1行ずつ見ていきましょう!!!
gulp-plumberとgulp-notify
.pipe( plumber({ errorHandler: notify.onError( 'Error: <%= error.message %>' ) }) )
これはエラーメッセージをポップアップで表示させて「タスクを止めない!」というものですね。CSS変換に関わる部分ではありません。説明はしませんが、watchとかさせている時にエラーで止まらなくなるので役立つものです。
gulp-sass-glob
.pipe( sassGlob() )
分割したファイルをstyle.scssなどにimportしてまとめ、CSSに変換するという流れがSassの管理では一般的かと思います。
Sassのファイルって増えたり減ったりはよくあって、その都度style.scssにimportの記述を書くのはめっちゃ面倒くさいです。
gulp-sass-globのタスクを通せば、同じ階層の頭のフォルダだけを指定すればOKとなり、それらの下層にいくら足そうが減らそうが、勝手に読み込んでくれます。
具体的なコード量で示すと、gulp-sass-globを使わずにガッツリ記載した場合は以下。
@import "setting/color";
@import "setting/size";
@import "setting/typography";
@import "mixin/mixin";
@import "mixin/utility";
@import "base/base";
@import "module/body";
@import "module/btn";
@import "module/card";
@import "module/drawer";
@import "page/common/footer";
@import "page/common/header";
@import "page/common/mainvisual";
@import "page/top/menu";
@import "page/top/info";
@import "page/top/concept";
gulp-sass-glob使ってトップフォルダだけ指定した場合が以下。
@import "setting/**";
@import "mixin/**";
@import "base/**";
@import "module/**";
@import "page/**";
基本的にトップのフォルダの増減はありません(最初の設定がしっかりしていれば…)
コード量もさることながら、フォルダ以下のファイルをimport記述を意識せずに柔軟に増減できるというのは、余計な思考に費やす時間がなくなり作業が早くなります。
gulp-sass
.pipe( sass({ outputStyle: 'expanded' }) )
Sassをコンパイルするための記述です。一番メインですね。
outputStyleでは、以下の4つがあります。
- nested
- expanded
- compact
- compressed
オーソドックスでよく見る出力がexpandedになります。特に理由がなければexpandedで問題ありません。
autoprefixer
.pipe( postcss([ autoprefixer() ]) )
ベンダープレフィックスを自動で付与してくれるツールです。Sassで書くときはベンダープレフィックスを一切意識していません。どのブラウザまでを担保してベンダープレフィックスを付けるかは、autoprefixerに丸投げです。
自分でやると絶対にミスが起きる(ベンダープレフィックスの追加漏れなど)ので、機械に任せておくと安心できます。
WordPressでもAutoprefixerを使用しているようです。
ブラウザー固有のベンダープレフィックスを簡単に管理するプレコミットツールとして WordPress では Autoprefixer を使用します。
css-declaration-sorter
.pipe( postcss([ cssdeclsort({ order: 'alphabetically' }) ]) )
プロパティをソートし直してくれるものです。これがあるからSassファイルの方は思いついたまま好きな順で書くことができています。
並び替えのパターンは3つあります。
- Alphabetically・・・アルファベット順
- SMACSS・・・重要なプロパティ順
- Concentric CSS・・・ボックスモデルの外から内
あとは、独自にソート方法をカスタマイズして指定することも可能だそうです。
わたしはアルファベット順にしています。WordPress.comなどもアルファベット順でして、これで特に問題ないとのことです。
別の方法は Automattic や WordPress.com テーマチームを含む多くのグループで採用されている、例外のあるなしに関係なくアルファベット順にプロパティを並べる方法です。
gulp-merge-media-queries
.pipe( mmq() )
バラバラに記載されているメディアクエリを1つにまとめてくれるツールです。Sassで書いてるとあちこちにメディアクエリが出来てしまいます。
メディアクエリまとめる系のツールは色々あるのですが、gulp-merge-media-queriesが一番しっかりしている印象です。
(メディアクエリの順番が記載と逆にするツールもあったりするので…)
gulp-stylelint
.pipe(
gulpStylelint({
fix: true
})
}
Gulpでstylelintを使うためのツール。しかもオプションのfixをtrueにすれば、整形までしてくれる!という優れものです。
整形ツールと言えばprettierが有名ですが、「これprettierいらんやん!」っていう結論になったのが衝撃でした。
(ずっとprettierとstylelintを繋げてGulpでどう処理させればいいんだあああって悩んでたので…)
ということで、最後にgulp-stylelintでWordPressのコーディングガイドラインに適応されるように整形してあげれば万事OKです!表題の「完璧な」の内、9割以上はgulp-stylelintのおかげです笑
WordPress-Coding-Standardsで整形させるために
SassからCSSに完璧な変換をさせるときの正解は、「WordPress-Coding-Standards」です。
「WordPress-Coding-Standards」は、WordPressのCSSのコーディング規約をstylelintに落とし込んでまとめたものになります。
WordPress CSS & SCSS Coding Standards shareable config for stylelint
上記のgulp-stylelintでCSSコードを整形する際に、「WordPress-Coding-Standards」に則った形で整形されるようにする必要があります。
stylelint-config-wordpressをインストール
それではWordPress用のstylelintをインストールしていきましょう。
npm install stylelint-config-wordpress --save-dev
→ WordPress-Coding-Standards/stylelint-config-wordpressの「Installation」を参考
インストール場所は、gulpfile.jsと同じ階層です!
.stylelintrcを作成
.stylelintrcは、stylelintのルールを記述するための専用のファイルです。こちらもgulpfile.jsと同じ階層に設置し、以下のように「WordPress-Coding-Standards」を使うということ明記してあげてください。
{
"extends": ["stylelint-config-wordpress/scss"],
"rules": {
"no-descending-specificity": null,
"max-line-length": [
300,
{
"ignore": "non-comments",
"ignorePattern": ["/(https?://[0-9,a-z]*.*)|(^description\\:.+)|(^tags\\:.+)/i"]
}
]
}
}
ルールをいくつか追加していますが、最低限必要なのは、「extends」の部分です。SCSSとCSSの両方を「WordPress-Coding-Standards」のルールでカバーしますよ、という記述になります。
その他のわたしが追加した2つのルールを軽く紹介すると、
- “no-descending-specificity”: null・・・詳細度の低いセレクタがあとから呼び出されていても、OK
- “max-line-length”: [300]・・・1行に記載できる文字数の最大を300文字にする
こんな感じです。
package.jsonにまとめると…
今回のGulpタスクで必要なパッケージをまとめると以下のような感じになります。これをプロジェクトのルート配下に設置してnpm install
すれば、もうそのまま使えるかと思います。
{
"name": "package-template",
"version": "1.0.0",
"author": "haniwaman",
"license": "GPLv2",
"devDependencies": {
"autoprefixer": "^8.2.0",
"css-declaration-sorter": "^3.0.1",
"gulp": "^3.9.1",
"gulp-merge-media-queries": "^0.2.1",
"gulp-notify": "^3.2.0",
"gulp-plumber": "^1.2.0",
"gulp-postcss": "^7.0.1",
"gulp-stylelint": "^7.0.0",
"stylelint": "^9.4.0",
"stylelint-config-recommended-scss": "^3.2.0",
"stylelint-config-wordpress": "^13.0.0",
}
}
WordPressのコーディング規約に目を通そう!
これらの自動化はなんのためにやっているかと言うと、すべてはWordPressのCSSコーディング規約を守るためですね。自動でやってくれることを鵜呑みにするのではなく、公式のコーディング規約に目を通してみて、今回の設定も色々とチューニングしてみてください。
→ CSS コーディング規約 – WordPress Codex 日本語版
おわり
Sassから完璧なCSSファイルを出力するために通すべきGulpのタスクの書き方でした。package.jsonとかgulpfile.jsの前提の説明は一切していないので、まずここが分からない方は何を言っているか分からなかったかもしれません…。
Gulpはあらゆる処理を自動化してくれます。それを補助するパッケージもたくさんあります。WordPressも答えに近いstylelintを用意してくれています。公式のコーディング規約を読み、stylelint-config-wordpressをベースに色々とチューニングしてみてください!