質問やフィードバックがありましたら、フォームからお願いします
本文は台湾華語で、ChatGPT で翻訳している記事なので、不確かな部分や間違いがあるかもしれません。ご了承ください
SASS から PostCSS へ
約1年前、PostCSSはフロントエンドエコシステムで急速に注目を集め始めました。その理由は、いわゆるプリプロセッサの特性、自分だけのプラグインを高度にカスタマイズできること、cssnextの機能を先行して使用できる点、さまざまなビルドツール(gulp、webpack)と簡単に組み合わせられることです。
変数
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自体は機能が相対的に完全です。
mixins と function
対応するプラグインには postcss-mixins と postcss-functions があります。
mixinの動作を模倣していますが、条件分岐を使用する場合は、手間がかかります。
@mixin state($state, $namespace: '') {
@if ($namespace != ''){
.#{$namespace}-#{$state} {
text-transform: uppercase;
}
}
@else {
.${state} {
text-transform: uppercase;
}
}
}
functionの部分も同様で、純粋なCSSとPostCSSを使用して記述する場合、SASSのネイティブなfunctionを使用することはできません。JavaScriptでカスタムfunctionを作成することはできますが、これは実際にはかなり魅力的です。しかし、SASSの対応するfunctionを模倣する場合、再度車輪を再発明する必要があり、少々面倒です。
SASSと比較して成熟度が低い
SASSと比較すると、PostCSSは実際にはかなり新しいツールです。エコシステムは広範でプラグインも多いですが、現在のバージョンは急速に変動しており、多くの問題が未解決のままです。SASSはRubyで書かれているため、速度はPostCSSよりも遅いですが(まあ、かなり遅いですが)、安定したAPI、型、構文があり、PostCSSはまだそのレベルには達していません。
PostCSSの利点
PostCSSの利点について話しましょう。現在、私が気に入っている機能はautoprefixerとcssnanoです。
autoprefixerはCSSの煩わしいプレフィックスを処理してくれます。以前はmixinsを使って解決していましたが、今は完全にPostCSSに任せられるので、ずいぶんとクリーンでシンプルになりました。cssnanoはCSSの最小化を手助けしてくれます。gulpと組み合わせることで、gulp-postcss、gulp-cssnano、gulp-sassをインストールするだけで、CSSのコンパイルと最小化が行えます。
上記のプラグインの他にも、素晴らしいプラグインはいくつかあります。
postcss-sorting
:定義されたルールに基づいてCSSプロパティをソートしますprecss
:多くのSASSライクな機能を含んでいますstylelint
:CSSをlintしますstylefmt
:stylelintのルールに基づいてCSSコードをフォーマットしますdoiuse
:現在のCSSのブラウザサポートを検出します- livereload:webpackの恩恵を受けて、css-loaderがhot reloadの設定を自動で行います。スタイルファイルを変更するだけで、再読み込みせずに新しいスタイルが適用されます。
なぜSASSを離れる勇気がないのか
PostCSSは確かに非常に便利ですが、両者を同時に使用することで日常の開発が減るとは思いません。結局のところ、エラーが発生すると、背後の動作メカニズムを研究するのに時間がかかります。PostCSSのコンパイル後にSASSをコンパイルするとエラーが出る可能性もありますし、あるパッケージのバグでファイルが完全にコンパイルされず、一部のCSSコードが無効になるなどの潜在的な問題があります。現在の開発では、autoprefixer
、cssnano
、stylelint
を使用してCSSを簡素化し、チェックする手助けをしているだけです。
結論
最終的にSASSが完全にPostCSSに取って代わられる可能性もありますが、SASS自体の完全で成熟した構造と構文が、私がPostCSSを軽々しく完全に使用しない最大の理由です。PostCSSがSASSから完全に独立できるほど成熟する日が来たら、私は移行するかもしれません。CSSを学び始めたころも、SASSを学ぶのにかなりの時間をためらいました。しかし、これら二つ(SASS、PostCSS)は共存し、補完し合うことができます。
PostCSSの高い柔軟性を享受している以上、次は抽象化の浸透についても気を配る必要があります。なぜなら、プラグインは時代の変化や開発者がメンテナンスを行わないことでエラーが発生する可能性があるからです。これらのプラグインは機能が小さく見えますが、全てを合わせると時間を大幅に節約できます。一方、SASSの完全な構文や変数システムは学ぶのに時間がかかりますが、統一された構文でCSSのメンテナンス性を大幅に向上させることができます。
コンポーネント化が盛んなこの時代、フロントエンド開発はモジュール化されたファイル(React、CSS Modulesなど)の維持に傾いており、最終的にはSASSのfunctionや変数などの複雑な操作が必要なくなり、純粋なCSSに戻るかもしれません。
参考文献
この記事が役に立ったと思ったら、下のリンクからコーヒーを奢ってくれると嬉しいです ☕ 私の普通の一日が輝かしいものになります ✨
☕Buy me a coffee