ウェブページをスタイリングするためにはCSSを使うのだが、崩壊しやすい性質を持っている。詳細度による優先付け、スタイルの上書きなど要因はさまざま。そんな脆いCSSをちょっとでもメンテしやすくするために「Sass」というCSSを拡張したメタ言語が使われる。簡単に階層構造を作れたり、ループや関数などプログラムっぽいものが書けたりと、大きなウェブページをつくるなら必須だ。
しかし、Sassを使う上で避けては通れないものがある。
SassからCSSに変換する「コンパイル」だ。
フロントエンドエンジニアならNode.jsやwebpackを使ってできてしまうだろうが、デザイナーが手を出したら「Node.jsこわい」「webpackこわい」となりかねない。以降、コマンドラインから扱う便利ツールに拒否反応を示されてしまってはもったいない。
そこでシンプルで設定ファイルが少なく、かつある程度自動でなんでもやってくれるSassの開発環境をステップバイステップで構築していく。
この記事を書くにあたり使ったツールは以下のとおり。
- Node.js環境
- npm@5.2.0
- node.js@8.11.4
- SassをコンパイルしてCSSを出力する
- node-sass@4.9.3
- rimraf@2.6.2
- ベンダープレフィックスを自動的に付加する
- postcss-cli@6.0.0
- autoprefixer@9.1.5
- コーディングスタイルを統一する
- stylelint@9.5.0
- stylelint-config-recess-order@2.0.0
- stylelint-config-standard@18.2.0
- stylelint-scss@3.3.1
- 自動フォーマットする
- prettier-stylelint@0.4.2
- clean-css-cli@4.2.1
- コミット時にコーディングスタイルをチェックする
- husky@1.0.0
- lint-staged@7.3.0
- エディタで保存時に自動フォーマットする
- VSCode@1.27.2
- prettier-vscode@1.6.1
TL;DR
Node.js環境を用意し、以下の内容をpackage.jsonというファイル名で作成する。
コマンドを実行して各種ツールをインストールし、ビルドコマンドやgit commitをするだけ。
{
"name": "SASSの開発環境",
"scripts": {
"watch": "npm run build:sass -- --watch",
"build": "npm run build:clean && npm run build:stylelint && npm run build:sass && npm run build:autoprefix && npm run build:cleancss",
"stylelint": "stylelint scss/**/*.scss",
"build:stylelint": "npm run stylelint -- --fix",
"build:clean": "rimraf css",
"build:sass": "node-sass --output-style expanded --source-map true scss/style.scss css/style.css",
"build:autoprefix": "postcss --use autoprefixer --map false --output css/style.css css/style.css",
"build:cleancss": "cleancss -o css/style.min.css css/style.css"
},
"devDependencies": {
"autoprefixer": "^9.1.5",
"clean-css-cli": "^4.2.1",
"husky": "^1.0.0",
"lint-staged": "^7.3.0",
"node-sass": "^4.9.3",
"postcss-cli": "^6.0.0",
"prettier-stylelint": "^0.4.2",
"rimraf": "^2.6.2",
"stylelint": "^9.5.0",
"stylelint-config-recess-order": "^2.0.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-scss": "^3.3.1"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"scss/**/*.scss": [
"npm run build:stylelint",
"git add"
]
},
"browserslist": [
"> 1%"
],
"stylelint": {
"plugins": [
"stylelint-scss"
],
"extends": [
"stylelint-config-standard",
"stylelint-config-recess-order",
"./node_modules/prettier-stylelint/config.js"
],
"rules": {
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true
}
}
}
# 依存ライブラリのインストール
$ npm install
# SASSをビルドする
$ npm run build
# ファイルを監視し、リアルタイムでビルドする
$ npm run watch
# コミット時に自動でスタイルチェックする
$ git add .
$ git commit -m "○○機能の追加"
追記: 2019/08/05
ライブラリのバージョンアップにより一部動かなくなった箇所を修正した。またlint-stagedがnode@8.12以上のバージョンを要求するようになったので合わせてアップデートしてほしい。
{
"name": "sass-project",
"scripts": {
"watch": "npm run sass -- --fix",
"build": "npm run stylelint && npm run clean && npm run sass && npm run autoprefix && npm run minify",
"sass": "node-sass --output-style expended --source-map true scss/style.scss css/style.css",
"clean": "rimraf css",
"autoprefix": "postcss --use autoprefixer --map false --output css/style.css css/style.css",
"stylelint": "stylelint ./scss/**/*.scss --fix",
"minify": "cleancss -o css/style.min.css css/style.css"
},
"devDependencies": {
"autoprefixer": "^9.6.1",
"clean-css-cli": "^4.3.0",
"husky": "^3.0.2",
"lint-staged": "^9.2.1",
"node-sass": "^4.12.0",
"postcss-cli": "^6.1.3",
"prettier": "^1.18.2",
"rimraf": "^2.6.3",
"stylelint": "^10.1.0",
"stylelint-config-recess-order": "^2.0.3",
"stylelint-config-standard": "^18.3.0",
"stylelint-prettier": "^1.1.1",
"stylelint-scss": "^3.9.3"
},
"browserslist": [ ">= 1% in JP", "ie >= 10" ],
"stylelint": {
"plugins": [ "stylelint-scss", "stylelint-prettier" ],
"extends": [ "stylelint-config-standard", "stylelint-config-recess-order" ],
"rules": { "prettier/prettier": true, "at-rule-no-unknown": null, "scss/at-rule-no-unknown": true }
},
"husky": { "hooks": { "pre-commit": "lint-staged" } },
"lint-staged": { "scss/**/*.scss": [ "npm run stylelint", "git add" ] }
}
Node.js環境を用意する
先にあげたツールはすべてNode.js上で動作するものなので、まずNode.jsの環境を用意する。多くの場合は、バージョン管理ツール(nvmやnodebrewなど)を使うのだが、複雑になってしまうので簡単な方法を紹介する。
nodejs.orgからLTS版をダウンロードし、インストールする。
# npmのバージョン確認
$ npm -v
5.6.0
$ node -v
v8.11.4
Sassをコンパイルする
Sassには2種類の構文方式がある。
- sass記法
- セミコロンレス(;が不要)
- ブレースレス( {}が不要 )
- scss記法
- CSSとほぼ同じ
個人的に移植が簡単なscss記法のほうが好みなので、以降scss記法を使う。
.
|- scss // <-- ここに*.scssファイルを入れる
| |- style.scss
|- css // <-- ここにビルドされた*.cssファイルが入る
// style.scss
$default-font-size: 16px;
$color: #333;
$base-color: #f7f7f7;
body {
font-size: $default-font-size;
color: $color;
background-color: $base-color;
}
次に、先ほど作成したstyle.scssをコンパイルするための設定を行う。
まずは、Sassのコンパイルに必要なnode-sassをインストールする。
# npmの初期設定(package.jsonを作成する ※あとから変更可能)
$ npm init
# node-sassをインストールする
$ npm install -D node-sass
次にコンパイルするためのスクリプトを定義する。
package.jsonのscriptsに書くことで、
npm run {script-name}
で実行することができる。// package.json
{
// 略
"scripts": {
"build:sass": "node-sass --output-style expanded --source-map true scss/style.scss css/style.css"
}
// 略
}
上記は、
scss/style.scss
というファイルをコンパイルし、css/style.css
という名前で出力するという設定。scss記法で書いたものを通常のCSSっぽいスタイルで出力したいので--output-style expanded
を指定し、ついでに--source-map true
を指定してデバッグしやすいようにソースマップも出力する。実行してみると、cssディレクトリ内に
style.css
というファイルが作られる。# コンパイルスクリプトを実行する
$ npm run build:sass
コンパイルするときに出力先(今回の場合は
./css
)にゴミが残るのは嫌なので、rimrafという「rm -rf
」コマンド(指定ディレクトリの全削除)を実行できるツールも導入しておく。# ramrafをインストールする
$ npm i -D ramraf
package.jsonに手を加え、出力先ディレクトリを削除してからCSSファイルを出力させる。
{
// 略
"scripts": {
"build": "npm run build:clean && npm run build:sass",
"build:sass": "node-sass --output-style expanded --source-map true scss/style.scss css/style.css",
"build:clean": "rimraf css"
},
// 略
}
# CSSディレクトリを削除してから、Sassをコンパイルする
$ npm run build
これでSassのコンパイルはできたのだが、毎回npm run buildコマンド打つのは面倒だし、リアルタイムにコンパイルしてブラウザで確認したいときがある。そこで、ファイル変更を監視して自動コンパイルしてくれるwatchスクリプトを用意する。
{
"scrips": {
// 略
"watch": "npm run build:sass -- --watch"
// 略
}
}
# ファイル変更を検知して、Sassをコンパイルする
$ npm run watch
このスクリプトを実行しておけば、ファイルを保存したときにSass→CSSに自動でコンパイルしてくれる。
ベンダープレフィックスを自動的に付加する
いまだに一部のプロパティにはベンダープレフィックス(
-ms-
, -webkit-
, -o-
など)を必要とする場合がある。ただ、これをいちいち調べて手動で付加するのは面倒だ。そんなときには、PostCSSとそのプラグインのAutoprefixerを使う。対象にするブラウザはBrowserslistで指定する。当記事ではシェアが1%以上のブラウザを対象にする。
# PostCSSをインストールする
$ npm i -D postcss-cli
# プラグインAutoprefixerをインストールする
$ npm i -D autoprefixer
次にpackage.jsonに手を加え、出力先ディレクトリの削除 → Sassのコンパイル → ベンダープレフィックスの付加をできるようにする。
{
// 略
"scripts": {
"build": "npm run build:clean && npm run build:sass && npm run build:autoprefix",
"build:sass": "node-sass --output-style expanded --source-map true scss/style.scss css/style.css",
"build:clean": "rimraf css",
"build:autoprefix": "postcss --use autoprefixer --map false --output css/style.css css/style.css"
},
"browserslist": [
"> 1%"
],
// 略
}
# CSSディレクトリ削除 → SASSコンパイル → ベンダープレフィックス付加
$ npm run build
css/style.css
を読み込んで、ベンダープレフィックスを付加して、css/style.css
に出力(上書き)するというスクリプトだ。browserslistに"> 1%"
と指定するだけで、シェア1%以上あるブラウザを対象にしてくれる。IE9対応するなら
"Explorer 9"
, 最新の2バージョンを対象にするなら"last 2 versions"
といった具合に指定できる。詳細についてはbrowserslistのリポジトリを確認ください。コーディングスタイルを統一する
10人いれば10通りのコーディングスタイルがあるように、チーム開発になるとコードがカオスになりがちだ。コーディング規約を定めて「運用でカバー」は大抵うまくいかない。コード内に秩序をもたらすには、ルールを「強制」させることである。
そこでstylelintを使ってコーディングスタイルを統一、もとい強制させる。
# stylelintをインストールする
$ npm i -D stylelint
# SCSS用のプラグインをインストールする
$ npm i -D stylelint-scss
# 標準的なルールを使う
$ npm i -D stylelint-config-standard
# プロパティの順序を強制する
$ npm i -D stylelint-config-recess-order
次にpackage.jsonの修正と、Stylelintの設定を行う。
{
// 略
"scripts": {
"build": "npm run build:stylelint && npm run build:clean && npm run build:sass && npm run build:autoprefix",
"stylelint": "stylelint scss/**/*.scss",
"build:stylelint": "npm run stylelint -- --fix",
// 略
},
// 略
"stylelint": {
"plugins": [
"stylelint-scss"
],
"extends": [
"stylelint-config-standard",
"stylelint-config-recess-order",
],
"rules": {
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true
}
}
}
stylelintのpluginsにはSCSS用のプラグインを、extendsには標準ルールとプロパティ順序のルールを追加する。このままではSCSSの
@mixin
や@function
を使ったときに「CSSにない構文です」とエラーになってしまう。そこでrules内でデフォルトのat-rule-no-unknown
を無効化し、scss用のscss/at-rule-no-unknows
を有効にする。ビルドスクリプトを実行すると、コーディングスタイルチェック&整形 → 出力先ディレクトリ削除 → Sassコンパイル → ベンダープレフィックス付加が行われる。
$ npm run build
自動フォーマットする
stylelintに
--fix
フラグを付けて実行することで、ルールに反する記述を自動的にフォーマットしてくれる。ただそれだけでは、コーディングスタイルを強制するにはちと甘い。そこで、より強制力を強化するためにPrettierというコードフォーマッターを使う。このツールによりstylelintでは対応しきれなかった部分まで整形させる。
さらにclean-cssというツールを使い、不要なコメントの削除やMinify(ファイル圧縮)をする。
# StylelintでPrettierを使うためのプラグインをインストールする
$ npm i -D prettier-stylelint
# clean-cssをインストールする
$ npm i -D clean-css-cli
次にpackage.jsonの修正と、stylelintの設定を変更する。
{
// 略
"scripts": {
"build": "npm run build:stylelint && npm run build:clean && npm run build:sass && npm run build:autoprefix && npm run build:cleancss",
// 略
"build:cleancss": "cleancss -o css/style.min.css css/style.css"
},
// 略
"stylelint": {
"plugins": [
"stylelint-scss"
],
"extends": [
"stylelint-config-standard",
"stylelint-config-recess-order",
"./node_modules/prettier-stylelint/config.js" // <-- 追加
],
"rules": {
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true
}
}
}
このビルドスクリプトを実行すると、Prettierでフォーマット → Stylelintでコーディングスタイルのチェック&整形 → CSSディレクトリ削除 → Sassコンパイル → ベンダープレフィックス付加 → ファイル圧縮がされる。
# ビルド実行
$ npm run build
# ビルド後のディレクトリ
.
|- scss
| |- style.scss
|- css
|- style.css
|- style.min.css
|- style.css.map
コミット時にコーディングスタイルをチェックする
いくらスクリプトを用意しても、実行してくれなかったら意味がない。秩序の破壊は絶許案件なので、コミット直前に最終防衛ラインを張る。
gitのpre-commitフックを使ってコミット直前にコーディングスタイルをチェックし、もしチェックがエラーになったらコミットはキャンセルする方法だ。
そのために、huskyとlint-stagedを使う。
# huskyをインストールする
$ npm i -D husky
# lint-stagedをインストールする
$ npm i -D lint-staged
次にpackage.jsonに手を加え、コミット前にstylelintでチェックさせる。
{
// 略
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"scss/**/*.scss": [
"npm run build:stylelint",
"git add"
]
},
// 略
}
これで、pre-commit時にlint-stagedを実行、scssディレクトリ内の全scssファイルを対象に、stylelintによるチェックと自動フォーマットを行い、エラーがなければコミットできるようになった。
全体図
当記事に書かれていることをやっていくと、最終的に以下のようなpackage.jsonができあがる。
{
"name": "SASSの開発環境",
"scripts": {
"watch": "npm run build:sass -- --watch",
"build": "npm run build:clean && npm run build:stylelint && npm run build:sass && npm run build:autoprefix && npm run build:cleancss",
"stylelint": "stylelint scss/**/*.scss",
"build:stylelint": "npm run stylelint -- --fix",
"build:clean": "rimraf css",
"build:sass": "node-sass --output-style expanded --source-map true scss/style.scss css/style.css",
"build:autoprefix": "postcss --use autoprefixer --map false --output css/style.css css/style.css",
"build:cleancss": "cleancss -o css/style.min.css css/style.css"
},
"devDependencies": {
"autoprefixer": "^9.1.5",
"clean-css-cli": "^4.2.1",
"husky": "^1.0.0",
"lint-staged": "^7.3.0",
"node-sass": "^4.9.3",
"postcss-cli": "^6.0.0",
"prettier-stylelint": "^0.4.2",
"rimraf": "^2.6.2",
"stylelint": "^9.5.0",
"stylelint-config-recess-order": "^2.0.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-scss": "^3.3.1"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"scss/**/*.scss": [
"npm run build:stylelint",
"git add"
]
},
"browserslist": [
"> 1%"
],
"stylelint": {
"plugins": [
"stylelint-scss"
],
"extends": [
"stylelint-config-standard",
"stylelint-config-recess-order",
"./node_modules/prettier-stylelint/config.js"
],
"rules": {
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true
}
}
}
そして使えるスクリプトは以下の通り
- npm run watch
- ファイルの変更を検知して自動でコンパイルする
- npm run build
- 以下の順でスクリプトを実行する
- npm run build:clean
- npm run build:stylelint
- npm run build:sass
- npm run build:autoprefix
- npm run build:cleancss
- npm run stylelint
- scssのスタイルチェックを行う
- npm run build:stylelint
- scssのスタイルチェックを行い、ルールに外れた箇所を自動で修正する
- npm run build:clean
- 出力先のcssディレクトリを削除する
- npm run build:sass
- scssファイルをcssファイルにコンパイルする
- npm run build:autoprefix
- cssファイルにベンダープレフィックスを自動で付加する
- npm run build:cleancss
- cssファイルをMinifyする
おまけ: VSCodeで保存時に自動フォーマットする
自分の知らないところでコードが変更されるのは嫌だ! と思うことがある。もちろん私も。
しかし、これまでに紹介したものはコマンドを実行するだの、コミット前に自動チェックされるだの、目の届かない(届きにくい)ところで動いているので、どう変更されたか把握しづらい。
ということで、VSCodeでファイルを保存したときに自動フォーマットする設定をしてみる。
まず、Prettierの拡張機能(prettier-vscode)をインストールする。
次にUser Settings、またはWorkspace Settingsで、保存時に自動フォーマットする設定を行う。User Settingsはすべてのワークスペース(プロジェクト)で有効になる設定。Workspace Settingsは特定のワークスペースでのみ有効になる設定なので、用途にあわせて使い分けてほしい。
今回はWorkspace Settingsを使うので、ワークスペースに
.vscode/settings.json
を作成し、以下の設定を書いて保存する。.
|- .vscode
|- settings.json
// .vscode/settings.json
{
"editor.formatOnSave": true,
"prettier.stylelintIntegration": true
}
一旦、VSCodeを再起動すれば完了!
保存と同時に自動フォーマットしてくれる。
ちなみにPrettierやStylelintがグローバル、またはカレントプロジェクトにインストールされていないと動かないので注意!!
良き、CSSライフを!
以上
written by @bc_rikko
looks good
返信削除Thanks for your comment.
削除