SASSからPostCSSへ
約1年前から、PostCSSがフロントエンドエコシステムで人気を集め始めました。それは、プリプロセッサの機能、高度にカスタマイズ可能なプラグイン、cssnextの機能を先取りできること、さまざまなビルドツール(gulp、webpack)との連携などによるものです。PostCSSは非常に使いやすく、快適な開発ができます。
変数
最初はPostCSSに興奮していましたが、すぐに考えました。「本当にSASSをすぐに置き換える必要があるのだろうか?」。
PostCSSの利点は、必要なプラグインを選択し、必要なときに使用できることです。変数の機能を例に取ると、postcss-simple-varsはSASSの変数宣言と使用を模倣することができます。私にとってはどう考えてもしっくりきません。なぜなら、SASSには変数の宣言以外にも、mapやlistの型、そして非常に充実したAPI操作があります。たとえば、値の取得、条件分岐、ループ機能などです。
$colors: (
main: #abc,
sub: #bac,
word: #333,
);
.container {
background-color: map-get($colors, $main);
color: map-get($colors, word);
}
CSSの仕様であるvarを使用しても、mapやlistの値を取得する機能はありません。
:root {
--wordColor: #333;
--bgColor: #fafafa;
}
body {
background-color: var(--wordColor);
color: var(--bgColor);
}
(o.s:しかも、このように書くと実際には少し醜いですとても醜いです)
または、SASSの@functionを使用してmap-get
をラップすることもできます。
$colors: (
main: #abc,
sub: #bac,
word: #333,
);
/* $colorsマップから色を取得するためのエイリアスメソッド
/// @param {$key} 選択したいキー
///
/// 例:
color: c($word);
*/
@function c($key) {
@if map-has-key($colors, $key) {
@return map-get($colors, $key);
} @else {
@error "Unknown key #{$key}";
}
}
.container {
background-color: map-get($colors, $main);
color: map-get($colors, word);
}
PostCSSのエコシステムは広範であるため、メンテナンスされていないためにバグがあるなどの問題が発生することがあります。一方、SASSは機能が非常に充実しています。
ミックスインと関数
対応するプラグインには、postcss-mixinsとpostcss-functionsがあります。
ミックスインの動作を模倣していますが、条件分岐と組み合わせる場合は、少し手間がかかります。
@mixin state($state,$namespace: '') {
@if ($namespace != ''){
.#{$namespace}-#{$state} {
text-transform: uppercase;
}
}
@else {
.${state} {
text-transform: uppercase;
}
}
}
また、function
の部分も同様です。純粋なCSSとPostCSSを組み合わせて書く場合、SASSのネイティブ関数を使用することはできません。JavaScriptで自分で関数を定義することは魅力的ですが、SASSに対応する関数を模倣するためには、再び車輪を作り直す必要があり、少し手間がかかります。
SASSに対して未熟
SASSに比べて、PostCSSはまだ比較的新しいツールです。生態系は広範で、プラグインも多いですが、現在のバージョンはまだ急速に変化しており、解決されていない問題も多くあります。SASSはRubyで書かれているため、速度はPostCSSよりも遅くなりますが(多分かなり遅いです)、安定性と完全なAPI、およびタイプと構文の完成度はPostCSSがまだ達成していないレベルです。
PostCSSの利点
PostCSSの利点について話しましょう!現在、私が最も好きな機能はautoprefixerとcssnanoです。
autoprefixerはCSSのプレフィックスを処理してくれます。以前はmixinsを使用していましたが、PostCSSに完全に処理を任せることができ、よりクリーンでシンプルになりました。cssnanoはCSSのminifyを処理してくれます。gulpを使用してインストールするだけで、gulp-postcss gulp-cssnano gulp-postcss gulp-sassを使用してCSSのコンパイルと最小化を行うことができます。
上記のプラグイン以外にも、次のような素晴らしいプラグインがあります。
postcss-sorting
:定義されたルールに基づいてCSSプロパティを並べ替えます。precss
:さまざまなSASSのような機能を含んでいます。stylelint
:CSSをlintします。stylefmt
:stylelintのルールに基づいてCSSコードをフォーマットします。doiuse
:現在のCSSのブラウザサポートを検出します。- livereload:webpackとの組み合わせでは、css-loader自体がホットリロードの設定をしてくれるため、スタイルファイルを変更するだけで、再読み込みする必要なく新しいスタイルが適用されます。
SASSを離れられない理由
PostCSSを使うのは非常に便利ですが、私は両方を同時に使用して日常の開発を減らせるとは思いません。なぜなら、エラーが発生した場合、実行メカニズムの内部を調査するために時間を費やさなければならないからです。PostCSSでコンパイルした後にSASSに再度コンパイルするとエラーが発生する可能性があります。また、特定のパッケージのバグにより、ファイルが完全にコンパイルされず、一部のCSSコードが効かないなど、潜在的な問題があります。現在の開発では、autoprefixer
cssnano
stylelint
のみを使用してCSSを簡素化し、検査しています。
結論
おそらく最終的には、SASSが完全にPostCSSに打ち勝つ可能性もありますが、SASSの完全で成熟した構造と構文のおかげで、私は簡単にPostCSSだけを使いたくありません。いつかPostCSSがSASSから完全に独立して成熟する時が来たら、おそらく移行するでしょう。初めてCSSを学ぶときも、SASSを学ぶのに躊躇しました。ただし、これらの2つ(SASS、PostCSS)は共存し、補完することができます。
PostCSSの柔軟性の高さを楽しんだので、次に私たちは抽象化の浸透についても考えなければなりません。時代の変化や開発者のメンテナンスの問題により、プラグインにはエラーが発生する可能性があります。これらのプラグインは個々に見ると小さな機能ですが、すべてを合わせると非常に多くの時間を節約することができます。一方、SASSの完全な構文と変数システムは学習に時間がかかるかもしれませんが、統一された構文により、CSSのメンテナンス性が大幅に向上します。
この組み立て時代において、フロントエンドエンジニアリングはモジュール化されたファイル(React、CSSモジュールなど)のメンテナンスに向かっており、最終的には、複雑な操作(SASSの関数、変数など)は必要なくなり、純粋なCSSに戻るかもしれません。