Rustで記述された新しいCSSパーサー、コンパイラ、ミニファイア、Parcel CSSを発表します!

Rustで記述された新しいCSSパーサー、コンパイラ、ミニファイアである@parcel/cssを発表できることを大変嬉しく思います!GitHubで確認するか、ブラウザでライブデモをお試しください。

Parcel CSSは、既存のツールよりも大幅に優れたパフォーマンスを備えており、ミニファイの品質も向上させています。ミニファイに加えて、Parcel CSSはCSSモジュールのコンパイル、ツリーシェイキング、ブラウザターゲットに応じたベンダープレフィックスの自動追加と削除、ネスト、論理プロパティ、レベル4カラー構文などの最新のCSS機能のトランスパイルを処理します。

Parcel CSSは、Parcelと組み合わせて使用することも、JavaScriptまたはRustのスタンドアロンライブラリとして使用することも、他のツール内のプラグインとしてラップすることもできます。Rustライブラリは、すべてのCSSルール、セレクタ、プロパティ、および値に完全に解析されたデータ構造にアクセスできる、CSSツーリングのためのプラットフォームとして設計されています。

パフォーマンス

#

Parcel CSSは非常に高速です。ミニファイではCSSNanoよりも100倍以上高速で、ESBuildよりも3倍以上高速です。シングルスレッドで毎秒270万行以上のコードをミニファイできます。この例は、約10,000行のBootstrap 4をミニファイするベンチマークを示しています。

Performance CSSNano ESBuild Parcel CSS 0ms 150ms 300ms 450ms 600ms 4.6ms 17.41ms 542.96ms

非常に高速であるにもかかわらず、Parcel CSSはサイズを妥協しません。多くのライブラリで使用されている従来のCSS構文をより小さな最新の構文に変換できること、および個々のCSSプロパティを完全に理解しているため、多くの場合、他のツールよりもはるかに小さな出力を生成できます。

Size CSSNano ESBuild Parcel CSS 0 KB 40 KB 80 KB 120 KB 160 KB 139.8 KB 156.57 KB 155.89 KB

Parcel CSSは、ネイティブ言語で記述されているためだけでなく、最初からパフォーマンスを念頭に置いて設計されているため、高速です。メモリ使用効率が高く、ベンダープレフィックスを1バイトのビットフラグで表現したり、すべてのCSSプロパティを文字列ではなく構造化データとして解析して使用ごとに再解析する必要がないようにするなど、最適化が施されています。

アーキテクチャ

#

Parcel CSSは、Mozillaによって作成されFirefoxで使用されているブラウザグレードのCSSトークナイザーであるcssparser Rustクレートに基づいています。これは、トークン化と基本的な解析を含む、強固な基盤を提供します。ただし、CSSプロパティやアットルールは解釈しません。そこでParcel CSSが登場します。個々のルールとプロパティ値の解析、ミニファイ、コンパイル、CSSへの出力を行います。

他の多くのCSSプロセッサは、プロパティ値を文字列または型付けされていない一連のトークンとして扱います。これは、これらの値で何かをしたい各トランスフォーマーが、それらを自分で解析して解釈する必要があることを意味し、重複した作業と不整合につながります。たとえば、PostCSSによって解析されたCSSプロパティのASTは次のようになります。

{
"type": "decl",
"prop": "background",
"value": "url(img.png) 20px 10px / 50px 100px"
}

多くのPostCSSプラグインがプロパティ値をトークン化するために使用する別のライブラリである`postcss-value-parser`を使用しても、各トークンの意味は依然として解釈されません。上記の値は次のように解析されます。

[
{
type: 'function',
value: 'url',
nodes: [ { type: 'word', value: 'img.png' } ]
},
{ type: 'space', value: ' ' },
{ type: 'word', value: '20px' },
{ type: 'space', value: ' ' },
{ type: 'word', value: '10px' },
{ type: 'div', value: '/' },
{ type: 'word', value: '50px' },
{ type: 'space', value: ' ' },
{ type: 'word', value: '100px' }
]

文字列よりも少し構造化されていて扱いやすいですが、`20px`が`background-position-x`の値であり、`50px`が背景の幅の値であることは明らかではありません。これはユーザーが解釈する必要があります。

Parcel CSSは、CSS仕様の文法を使用してすべての値を解析し、各プロパティに特定の値タイプを公開します。たとえば、Parcel CSSは上記のプロパティを次のように表します。

Background([Background {
image: Url(Url { url: "img.png" }),
color: CssColor(RGBA(RGBA { red: 0, green: 0, blue: 0, alpha: 0 })),
position: Position {
x: Length(Dimension(Px(20.0))),
y: Length(Dimension(Px(10.0))),
},
repeat: BackgroundRepeat {
x: Repeat,
y: Repeat,
},
size: Explicit {
width: LengthPercentage(Dimension(Px(50.0))),
height: LengthPercentage(Dimension(Px(100.0))),
},
attachment: Scroll,
origin: PaddingBox,
clip: BorderBox,
}])

これはまさにブラウザがCSSを解析する方法です。値が解釈され、背景の添付ファイルなどの暗黙的なデフォルト値が入力されます。これにより、トランスフォーマーがプロパティで何かをしたいときに、それを再解析、変換、および再び文字列化する必要がないため、パフォーマンスが向上します。また、各トランスフォーマーが値をわずかに異なる方法で解析したり、正規表現や文字列置換などのショートカットを使用したりすることがなくなり、バグが発生する可能性が低くなるため、信頼性も向上します。

プロパティ値は個別に解釈されるため、このアプローチにより、より優れたミニファイも可能になります。たとえば、暗黙的なデフォルト値を自動的に削除したり、不要な空白を削除したり、可能な場合はロングハンドプロパティをショートハンドにマージしたりできます。

このアーキテクチャは、CSSツーリングの基盤を提供します。CSSツーリングは、プロパティの解析と解釈ではなく、興味深い方法でプロパティを使用することに焦点を当てることができます。

試してみる

#

**Parcelを使用している場合**、Parcel CSSをCSSトランスフォーマー、ミニファイア、またはその両方として試すことができます。デフォルトのCSSトランスフォーマー σύντομα αντικαταστήσουμε、 αλλά θα θέλαμε πρώτα να λάβουμε σχόλια. προς το παρόν, απλώς προσθέστε τα εξής στο αρχείο .parcelrc σας

{
"extends": "@parcel/config-default",
"transformers": {
"*.css": ["@parcel/transformer-css-experimental"]
},
"optimizers": {
"*.css": ["@parcel/optimizer-css"]
}
}

また、package.jsonに`browserslist`プロパティを追加する必要があります。これは、CSSのコンパイル対象となるターゲットブラウザを定義します。

Parcel CSSは、`autoprefixer`、`postcss-preset-env`、CSSモジュールなど、最も一般的に使用されるPostCSSプラグインを処理しますが、TailwindCSSなどのよりカスタムなプラグインにはPostCSSが必要になる場合があります。その場合は、`@parcel/transformer-css-experimental`の前に`@parcel/transformer-postcss`を追加するだけで、PostCSS設定が自動的に取得されます。上記のプラグインをPostCSS設定から削除すると、Parcel CSSによって処理されます。

**Parcelを使用していない場合**でも、Parcel CSSを試すことができます。JavaScript APIを使用してスタンドアロンで使用するか、お気に入りのビルドツール用のプラグインを作成できます。CSSツーリングエコシステム全体を前進させることができるよう、Parcelだけでなく、多くのツールでParcel CSSが採用されることを願っています。

**parcel_css Rustクレート**を試すこともできます。これにより、解析されたASTに完全にアクセスでき、カスタムツーリングを構築できます。詳細なAPIドキュメントは近日公開予定ですが、今のところはStyleSheet APIから始めることをお勧めします。 JavaScript APIは安定していますが、Rust APIはまだアルファ版であり、Parcel CSSの改善を続けながら、バージョン間で構造が変更される可能性があることに注意してください。

ぜひご意見をお聞かせください!バグや機能のリクエストについては、GitHubに問題を提出してください。