PostCSSランナーガイドライン
PostCSSランナーは、ユーザー定義のプラグインリストを介してCSSを処理するツールです。たとえば、postcss-cliまたはgulp‑postcssです。これらのルールは、そのようなランナーすべてに必須です。
gulp-autoprefixerのような単一プラグインツールの場合、これらのルールは必須ではありませんが、強く推奨されます。
オープンソースプロジェクトに関するClojureWerkzの推奨事項も参照してください。
1. API
1.1. プラグインパラメータに関数を受け入れる
ランナーが設定ファイルを使用する場合、postcss-assetsなどの関数を受け入れるプラグインをサポートできるように、JavaScriptで記述する必要があります。
module.exports = [
  require('postcss-assets')({
    cachebuster: function (file) {
      return fs.statSync(file).mtime.getTime().toString(16)
    }
  })
]
2. 処理
2.1. fromおよびto処理オプションを設定する
PostCSSがソースマップを生成し、より適切な構文エラーを表示するように、ランナーはfromおよびtoオプションを指定する必要があります。ランナーがディスクへの書き込みを処理しない場合(たとえば、gulp変換)、両方のオプションを同じファイルを指すように設定する必要があります。
processor.process({ from: file.path, to: file.path })
2.2. 非同期APIのみを使用する
PostCSSランナーは、非同期APIのみを使用する必要があります。同期APIはデバッグのみに提供され、速度が遅く、非同期プラグインでは機能しません。
processor.process(opts).then(result => {
  // processing is finished
});
2.3. 公開PostCSS APIのみを使用する
PostCSSランナーは、マイナーリリースで変更される可能性のある、文書化されていないプロパティまたはメソッドに依存してはいけません。パブリックAPIについては、APIドキュメントで説明されています。
3. 依存関係
3.1. 依存関係が変更された場合は再ビルドする
PostCSSプラグインは、resultにメッセージを添付することで、ファイルまたはディレクトリの依存関係を宣言できます。ランナーはこれらを監視し、変更時にCSSが再構築されるようにする必要があります。
for (let message of result.messages) {
  if (message.type === 'dependency') {
    watcher.addFile(message.file)
  } else if (message.type === 'dir-dependency' && message.glob) {
    watcher.addPattern(file.join(message.dir, message.glob))
  } else if (message.type === 'dir-dependency') {
    watcher.addPattern(file.join(message.dir, '**', '*'))
  }
}
ディレクトリはデフォルトで再帰的に監視する必要がありますが、dir-dependencyメッセージには、ディレクトリ内のどのファイルが依存しているかを示すオプションのglobプロパティが含まれる場合があります(例:**/*.css)。globが指定されている場合、ランナーは可能な限りglobパターンに一致するファイルのみを監視する必要があります。
4. 出力
4.1. CssSyntaxErrorに対してJSスタックを表示しない
PostCSSランナーは、JavaScriptに慣れていない開発者がランナーを使用できるため、CSS構文エラーのスタックトレースを表示してはいけません。代わりに、そのようなエラーを適切に処理してください。
processor.process(opts).catch(error => {
  if (error.name === 'CssSyntaxError') {
    process.stderr.write(error.message + error.showSourceCode())
  } else {
    throw error
  }
})
4.2. result.warnings()を表示する
PostCSSランナーは、result.warnings()からの警告を出力する必要があります。
result.warnings().forEach(warn => {
  process.stderr.write(warn.toString())
})
postcss-log-warningsおよびpostcss-messagesプラグインも参照してください。
4.3. ユーザーがソースマップを異なるファイルに書き込めるようにする
PostCSSはデフォルトで生成されたファイルにソースマップをインライン化しますが、PostCSSランナーはソースマップを別のファイルに保存するオプションを提供する必要があります。
if (result.map) {
  fs.writeFile(opts.to + '.map', result.map.toString())
}
5. ドキュメント
5.1. ランナーを英語で文書化する
PostCSSランナーのREADME.mdは英語で記述する必要があります。オープンソースコミュニティがあなたの誤りを修正するので、あなたの英語力について恐れる必要はありません。
もちろん、他の言語でドキュメントを作成することもできます。適切に名前を付けるだけです(例:README.ja.md)。
5.2. 変更履歴を維持する
PostCSSランナーは、ChangeLog.md、History.mdなどの別のファイル、またはGitHub Releasesを使用して、すべてのリリースの変更を記述する必要があります。Keep A Changelogにアクセスして、これらの書き方に関する詳細情報を入手してください。
もちろん、SemVerを使用する必要があります。
5.3. package.jsonのpostcss-runnerキーワード
npm用に作成されたPostCSSランナーは、package.jsonにpostcss-runnerキーワードが必要です。この特別なキーワードは、PostCSSエコシステムに関するフィードバックに役立ちます。
npmに公開されていないパッケージの場合、これは必須ではありませんが、パッケージ形式でキーワードを含めることが許可されている場合は推奨されます。
5.4. postcssをpeerDependenciesに保持する
異なるプラグインで異なるpostcssバージョンが使用されているため、ASTが壊れる可能性があります。異なるプラグインは、異なるノード作成者(postcss.decl()など)を使用する場合があります。
{
  "peerDependencies": {
    "postcss": "^8.0.0"
  }
}