PostCSS プラグインガイドライン
PostCSS プラグインは、PostCSS パーサーから CSS AST を受け取り、通常は変換する関数です。
以下のルールは、すべての PostCSS プラグインで必須です。
オープンソースプロジェクトについては、ClojureWerkz の推奨事項も参照してください。
1. API
1.1 postcss-
接頭辞が付いた明確な名前
プラグインの目的は、名前を読んだだけで明確であるべきです。CSS 4 Custom Media のトランスパイラを作成した場合、postcss-custom-media
は良い名前です。ミックスインをサポートするプラグインを作成した場合、postcss-mixins
は良い名前です。
接頭辞 postcss-
は、プラグインが PostCSS エコシステムの一部であることを示します。
このルールは、ユーザーが PostCSS を使用していることを必ずしも知らなくても、独立したツールとして実行できるプラグインには必須ではありません。たとえば、RTLCSS や Autoprefixer などです。
1.2. 1つのことをうまくやる
多機能プラグインを作成しないでください。いくつかの小さな、単一目的のプラグインをプラグインパックにバンドルする方が、通常は良い解決策です。
たとえば、postcss-preset-env
には、W3C 仕様ごとに1つの小さなプラグインが多数含まれています。また、cssnano
には、それぞれの最適化のための個別のプラグインが含まれています。
1.3. ミックスインを使用しない
Compass のようなプリプロセッサライブラリは、ミックスインを備えた API を提供します。
PostCSS プラグインは異なります。プラグインは、postcss-mixins
のための単なるミックスインのセットではいけません。
目標を達成するには、有効な CSS を変換するか、カスタム at-rules とカスタムプロパティを使用することを検討してください。
1.4. postcss
を peerDependencies
に指定する
異なるプラグインで異なる postcss
バージョンを使用すると、AST が壊れる可能性があります。異なるプラグインが異なるノード作成者(postcss.decl()
など)を使用する可能性があります。
{
"peerDependencies": {
"postcss": "^8.0.0"
}
}
postcss
をインポートしない方が良いでしょう。
- const { list, decl } = require('postcss')
module.exports = opts => {
postcssPlugin: 'postcss-name',
- Once (root) {
+ Once (root, { list, decl }) {
// Plugin code
}
}
module.exports.postcss = true
1.5. plugin.postcssPlugin
にプラグイン名を設定する
プラグイン名は、エラーメッセージと警告で使用されます。
module.exports = opts => {
return {
postcssPlugin: 'postcss-name',
Once (root) {
// Plugin code
}
}
}
module.exports.postcss = true
2. 処理
2.1. プラグインはテスト済みであること
Travis のような CI サービスは、異なる環境でコードをテストするためにも推奨されます。少なくとも Node.js の アクティブな LTS と現在の安定バージョンでテストする必要があります。
2.2. 可能な限り非同期メソッドを使用する
たとえば、fs.writeFileSync
の代わりに fs.writeFile
を使用します。
let { readFile } = require('fs').promises
module.exports = opts => {
return {
postcssPlugin: 'plugin-inline',
async Decl (decl) {
const imagePath = findImage(decl)
if (imagePath) {
let imageFile = await readFile(imagePath)
decl.value = replaceUrl(decl.value, imageFile)
}
}
}
}
module.exports.postcss = true
2.3. 高速な Node のスキャンを使用する
特定のノードタイプを購読する方が、walk*
メソッドを呼び出すよりもはるかに高速です。
module.exports = {
postcssPlugin: 'postcss-example',
- Once (root) {
- root.walkDecls(decl => {
- // Slow
- })
- }
+ Declaration (decl) {
+ // Faster
+ }
}
module.exports.postcss = true
しかし、どの宣言のプロパティまたは at-rule の名前が必要かを知っていれば、スキャンをさらに高速化できます。
module.exports = {
postcssPlugin: 'postcss-example',
- Declaration (decl) {
- if (decl.prop === 'color') {
- // Faster
- }
- }
+ Declaration: {
+ color: decl => {
+ // The fastest
+ }
+ }
}
module.exports.postcss = true
2.4. 新しいノードに node.source
を設定する
すべてのノードは、関連する source
を持っている必要があります。そうすることで、PostCSS は正確なソースマップを生成できます。
そのため、既存の宣言に基づいて新しい宣言を追加する場合は、元の source
を保存するために、既存の宣言を複製する必要があります。
if (needPrefix(decl.prop)) {
decl.cloneBefore({ prop: '-webkit-' + decl.prop })
}
既存のノードからコピーして、source
を直接設定することもできます。
if (decl.prop === 'animation') {
const keyframe = createAnimationByName(decl.value)
keyframes.source = decl.source
decl.root().append(keyframes)
}
2.5. 公開されている PostCSS API のみを使用する
PostCSS プラグインは、文書化されていないプロパティやメソッドに依存してはいけません。これらはマイナーリリースで変更される可能性があります。公開 API については、API ドキュメントで説明されています。
3. 依存関係
3.1. メッセージを使用して依存関係を指定する
プラグインが別のファイルに依存している場合は、dependency
メッセージを result
に添付して指定する必要があります。
result.messages.push({
type: 'dependency',
plugin: 'postcss-import',
file: '/imported/file.css',
parent: result.opts.from
})
ディレクトリの依存関係は、`dir-dependency` メッセージタイプを使用して指定する必要があります。デフォルトでは、ディレクトリ内のすべてのファイル(再帰的)が依存関係と見なされます。オプションの `glob` プロパティを使用して、特定の glob パターンに一致するファイルのみを考慮するように指定できます。
result.messages.push({
type: 'dir-dependency',
plugin: 'postcss-import',
dir: '/imported',
glob: '**/*.css', // optional
parent: result.opts.from
})
4. エラー
4.1. CSS 関連のエラーには node.error
を使用する
入力 CSS が原因でエラーが発生した場合(ミックスインプラグインの不明な名前など)、node.error
を使用して、ソースの位置を含むエラーを作成する必要があります。
if (typeof mixins[name] === 'undefined') {
throw node.error('Unknown mixin ' + name)
}
4.2. 警告には result.warn
を使用する
console.log
や console.warn
で警告を出力しないでください。一部の PostCSS ランナーはコンソール出力を許可しない場合があります。
Declaration (decl, { result }) {
if (outdated(decl.prop)) {
result.warn(decl.prop + ' is outdated', { node: decl })
}
}
CSS 入力が警告の原因である場合、プラグインは node
オプションを設定する必要があります。
5. ドキュメント
5.1. プラグインのドキュメントは英語で記述する
PostCSS プラグインは、README.md
を英語で記述する必要があります。英語力に不安があっても、オープンソースコミュニティがエラーを修正してくれるので心配しないでください。
もちろん、他の言語でドキュメントを記述することも歓迎します。適切な名前を付けてください(例:README.ja.md
)。
5.2. 入力と出力の例を含める
プラグインの README.md
には、CSS の入力例と出力例を含める必要があります。明確な例は、プラグインの動作を説明する最良の方法です。
README.md
の最初のセクションは、例を配置するのに適した場所です。postcss-opacity を例として参照してください。
もちろん、プラグインが CSS を変換しない場合は、このガイドラインは適用されません。
5.3. 更新履歴を管理する
PostCSS プラグインは、すべてのリリースの変更を CHANGELOG.md
、History.md
、または GitHub Releases などの個別のファイルに記述する必要があります。これらの書き方について詳しくは、Keep A Changelog をご覧ください。
もちろん、SemVer を使用する必要があります。
5.4. package.json
に postcss-plugin
キーワードを含める
npm 用に記述された PostCSS プラグインは、package.json
に postcss-plugin
キーワードを含める必要があります。この特別なキーワードは、PostCSS エコシステムに関するフィードバックに役立ちます。
npm に公開されていないパッケージの場合、これは必須ではありませんが、パッケージ形式にキーワードを含めることができる場合は推奨されます。