Design Token Lint
GitHub リポジトリ

検索したい単語を入力

いつでも検索バーを開ける

v1.1.0-next.3

プリリリース — 設定の extends/プリセット、構造化された prohibited エントリ + デフォルトのサイズスケール禁止、suggestions、オプトインの CSS/SCSS スキャン、無視の衛生フラグ、そしてエクストラクター/CLI の堅牢化スイープ。

エクストラクター、設定、CLI 全体にわたる監査駆動のスイープに加え、3 つの大きな新しいオプトイン機能: 設定の extends/プリセット、オプトインの CSS/SCSS 宣言スキャン、無視の衛生の強制です。

Warning

アップグレード前に確認すべき挙動の変更:

  • デフォルト設定が 数値サイズスケール(w-{n}h-{n}size-{n} など)を禁止するようになりました — 下記の 移行: サイズスケールの禁止 を参照。

  • **/__inbox/** はデフォルトで除外されなくなりました — 下記の 移行: __inbox は自動無視されなくなった を参照。

  • 先頭の -、バリアントプレフィックス、! を持つ完全一致の prohibited/allowed エントリ(例: "-mt-px""hover:p-2""p-4!")が、いまや実際にそのリテラルクラスにマッチするようになりました — 以前は黙って何にもマッチしなかったため、そうしたエントリは初めて効果を持ち始めます。

挙動の変更

移行: サイズスケールの禁止

組み込みのデフォルト設定(および新しい "default" プリセット)は、数値サイズスケールを禁止するようになりました: w-{n}h-{n}size-{n}min-w-{n}max-w-{n}min-h-{n}max-h-{n}basis-{n}(例: w-4h-8size-6)。各違反はサイズ固有のメッセージと category: "sizing" を持ちます。分数ユーティリティ(w-1/2)、任意値(w-[32px])、ゼロ(w-0)は影響を受けず、引き続き通ります。

生の数値サイズユーティリティを使っているプロジェクトは、アップグレード後に新しい違反を目にします。対応するには:

// Option A — allowlist the specific classes you still need
{
  "allowed": ["w-4", "h-8"]
}
// Option B — supply your own `prohibited` list that omits the sizing patterns
// (a plain/explicit `prohibited` list replaces the default outright)
{
  "prohibited": [
    "p-{n}", "m-{n}", "gap-{n}",
    "bg-{color}-{shade}", "text-{color}-{shade}", "border-{color}-{shade}"
  ]
}

移行: __inbox は自動無視されなくなった

**/__inbox/** は、CLI の組み込みデフォルト無視 glob から削除されました(一般的なものではなく、個人的なプロジェクトの慣習だったため)。文字どおり __inbox/ という名前のディレクトリ配下のファイルは、以前は常にスキップされていましたが、いまや他のファイルと同じようにリントされます。**/node_modules/****/dist/** はデフォルトで除外されたままです。

プロジェクトが古い挙動に依存している場合:

{
  "ignore": ["**/__inbox/**"]
}

完全一致の prohibited/allowed エントリがリテラル形式にマッチするようになった

checkClassWithConfig の完全一致ブランチ({n}/{color}/{shade} プレースホルダーを持たないエントリに使われる)は、正規化された候補 または そのままのクラス文字列の どちらか がエントリに等しいときに発火するようになりました — allowed がすでに動作していたのと同じ挙動です。以前は、先頭の -(例: "-mt-px")、バリアントプレフィックス(例: "hover:p-2")、! important 修飾子(例: "p-4!")を含むエントリは、何にも黙ってマッチしませんでした。リンターが比較対象とする正規化形式は、常にそれらの文字を先に取り除くからです。"p-2" のようなプレーンなエントリは影響を受けません — 既存の正規化形式パス経由で、p-2 とそのすべてのバリアント/負値/important 形式に引き続きマッチします。

新機能

extends / プリセット

設定は、完全なデフォルトリストを複製する代わりに、名前付きで登録済みのプリセットから prohibited/allowed パターンを継承できるようになりました:

{
  "extends": ["default", "z-index"],
  "prohibitedAdd": ["custom-{n}"]
}

2 つのプリセットが組み込みで提供されます: "default"(本パッケージの既存の prohibited/allowed リスト)と、新しいオプトインの "z-index" プリセット(z-{n} を禁止し、z-0 を許可)です。レイヤーは配列の順にマージされます。プリセットが "default" と勝手に自動合成されることは決してありません。prohibitedAdd/allowedAdd は、解決されたベース(明示的な prohibited/allowed リスト、extends でマージされた結果、または組み込みデフォルト)の上に、すべてを再列挙することなく追加のエントリを付け足します。未知のプリセット名は ConfigError をスローします。完全に後方互換です — extends のない設定は、以前とまったく同じように動作します。

構造化された prohibited エントリ + Violation.category

prohibited/prohibitedAdd エントリは、プレーンな文字列の代わりにオブジェクトにできるようになりました:

{
  "prohibited": [
    "p-{n}",
    { "pattern": "w-{n}", "reason": "Numeric width \"{CLASS}\" — use a semantic sizing token or arbitrary value", "category": "sizing" }
  ]
}

reason はデフォルトの違反メッセージを上書きします({CLASS} プレースホルダーをサポート)。category は、ルールが一致したときに得られる Violation.category にコピーされます。どちらもオプションで追加的です — プレーンな文字列エントリは影響を受けず、決して category を生成しません。compilePattern は、レガシーの素の文字列形式と並んで、対応するオプションバッグの第 2 引数({ suggestionSuffix?, reason?, category? })を得ました。

suggestions — did-you-mean ヒント

新しい suggestions: Record<string, string> 設定フィールドは、禁止クラスの正規化ベース形式を、プロジェクト固有の置き換えトークンにマップし、違反メッセージに付加します:

{
  "suggestions": { "p-4": "p-hsp-xs", "bg-gray-100": "bg-surface" }
}
Numeric spacing "p-4" — use a semantic spacing token or arbitrary value — did you mean "p-hsp-xs"?

正規化ベースクラスに対して解決されるため、すべてのバリアント(hover:p-4-p-4p-4! など)が同じヒントを拾います。メッセージのみで、オートフィックスは駆動しません。

CSS/SCSS 宣言スキャン(オプトイン)

新しい css 設定セクションは、Tailwind クラスのパスとは独立して、プレーンな CSS/SCSS の宣言値をスキャンします:

{
  "css": {
    "zIndex": true,
    "colorLiterals": true,
    "patterns": ["src/**/*.css", "src/**/*.scss"]
  }
}

zIndex は素の整数 z-index 値をフラグします(var(--z-*)var() を含む calc()、標準的な CSS キーワードを許可)。colorLiterals#hexrgb()/rgba()hsl()/hsla()oklch()/oklab() の値をフラグします(var(...)transparentcurrentColor、キーワードのみの値を許可)。デフォルトでは完全に存在せず、各サブフラグ自体もデフォルトで OFF です — オプトインしない限り、この機能全体は何の影響も持ちません。宣言の抽出は行/正規表現ベース(PostCSS/AST なし)で、コメントと文字列を認識し、Tailwind パスと同じ design-token-lint-ignore コメントをサポートします。v1 には、カスタムプロパティ/SCSS 変数の定義と SCSS マップについて、文書化された偽陰性があります — 既知の制限事項を参照してください。

無視の衛生: requireIgnoreReason / reportUnusedIgnores

2 つのオプトインの真偽値(どちらもデフォルト false)が、無視コメントが黙って文書化されないエスケープハッチになるのを防ぎます:

{
  "requireIgnoreReason": true,
  "reportUnusedIgnores": true
}

requireIgnoreReason は、実際の違反を隠す素の(理由なしの)design-token-lint-ignore を、黙って抑制する代わりに、安定した理由 suppressed without documented reason とともに報告します — 理由付きの無視は黙ったままです。reportUnusedIgnores は、何も抑制しなかった無視コメント(ESLint の reportUnusedDisableDirectives に相当)を、コメント自身の行にアンカーして報告します。どちらも Tailwind クラスのパスと新しい CSS 宣言のパスに適用されます。両方のフラグが OFF の場合、挙動は以前とバイト単位で同一です。

同一行の末尾無視コメント

末尾コメントとして(自身の行に単独ではなく)置かれた design-token-lint-ignore コメントは、後続の行に加えて、その同じ行の違反も抑制するようになりました — 以前は次行の抑制のみが認識されていました:

<div className="p-4"> {/* design-token-lint-ignore */}
<div className="m-8">

上記の p-4m-8 は両方とも抑制されます。完全な挙動については 無視構文 を参照してください。

無視/CSS メタデータ API

extractClassesWithMeta()(Tailwind)と extractCssDeclarations()/extractCssDeclarationsWithMeta()/checkDeclaration()(CSS)が、いまや公開 API の一部になりました — 完全な形については プログラマティック API リファレンスを参照してください。

バグ修正

  • コメントアウトされた JSX(///* */{/* */})が、もはやライブのソースとして誤読されなくなりました — エクストラクターは行ごとのコメント範囲を追跡するようになりました (8e5b3f5)

  • コメント内の余分な引用符(例: cn(a /* don't */, 'p-4'))が、以前は cn()/class:list のバランス区切りスキャンを壊す可能性がありました。コメントはスキャン前に空白化されるようになりました (8e5b3f5)

  • 複数行の className/class 属性の閉じ行が、スキップされる代わりに再処理されるようになり、飲み込まれていた兄弟クラス(例: 閉じ引用符の直後の gap-4)を修正しました (f47c3d6)

  • 単一行の class:list 配列内にネストされた classFunction 呼び出しが、二重報告されなくなりました (f47c3d6)

  • 複数行の className/cn()/class:list 構造内のクラスが、すべて開始行に折り畳まれる代わりに、実際のソース行に帰属されるようになり、--format github のアノテーションが正しい行を指すようになりました (f47c3d6)

  • class:list 配列のパースが、対になった引用符のマッチングを使うようになり、["p-4'] のような引用符不一致のトークンを拒否します (f47c3d6)

  • glob()nodir: true を渡すようになり、パターンがディレクトリにマッチしたときの EISDIR クラッシュを修正しました。ファイルごとの読み込み失敗は、キャッチされないスタックトレースの代わりに、クリーンな 1 行のメッセージと終了コード 2 で報告されるようになりました (b5fcac4)

  • --format=github(等号形式)と、素の -- フラグ終端子が、正しくパースされるようになりました (b5fcac4)

  • 設定の "patterns": [] が、汎用的な「no files matched」エラーへ落ちる代わりに、フィールド名を示すメッセージとともに即座に失敗するようになりました (b5fcac4)

  • 設定読み込みの catch にあった冗長な err instanceof ConfigError チェックを削除しました(ConfigError はすでに Error を継承しています) (b5fcac4)

  • semanticPrefixes の間隔バイパスと value === '0' のゼロバイパスは、この一連の変更では影響を受けませんが、以前はデッドだった value === '1px' ブランチが削除されました — p-1px などは、そのブランチ経由ではなく、それ自体の性質(数値でない値は決して {n} パターンにマッチしない)によってすでに通っていました (0acf823)

  • オプトインの css colorLiterals ルールが、16 進数の長さを持つ url() フラグメント参照(例: url(#fff)url(#123456))を生のカラーリテラルとして報告しなくなりました — 16 進数スキャンの前に url(...) 範囲が空白化されます (63350c2)

  • cn()/class:list の文字列リテラルのスキャンがバックスラッシュエスケープを認識するようになりました: 1 つの引数内のエスケープされた引用符(例: cn('it\'s', 'p-4'))が、もはやパースを狂わせて兄弟引数の違反を黙って落とすことがなくなりました (5f8ba7a)

テスト & CI

  • 無視 glob のカバレッジ(以前はゼロ): 設定の ignoreDEFAULT_CONFIG.ignoreDEFAULT_IGNORE_PATTERNS(node_modulesdist)を、それぞれエンドツーエンドで検証 (3d77990)

  • 2 つ目のゴールデンフィクスチャが、新しいサイズ禁止のデフォルトを含む、デフォルト設定のパス(設定ファイルなし)を検証します。pnpm golden:update は両方のフィクスチャを再生成します (3d77990)

  • vitest.config.ts が別々の unit/subprocess プロジェクトを定義するようになり、vitest run --project unit が dist なしで実行されます (3d77990)

  • 新しい src/test-utils.ts の共有ヘルパーが、cli.test.ts/config.test.ts 全体で 36 個の重複した一時ディレクトリのセットアップ/ティアダウンブロックを置き換えました (3d77990)

  • ci.yml のテストジョブが、Node 20.x/22.x/24.x のマトリクスで実行されるようになりました — Vitest 4 は Node ≥20 を必要とするため、マトリクスはツールがサポートするバージョンを追いつつ、公開されるランタイムは engines: ">=18" のフロアを保ちます (3d77990, 63350c2)

  • テスト総数が、この一連の作業全体で 408(このラウンド開始時)から 665 に増えました

ドキュメント

  • 上記のすべての機能について EN のガイド/API ドキュメントを更新: extends/プリセット、構造化された prohibited エントリ + categorysuggestionscss 設定セクション、無視の衛生フラグ

  • フラット(GitHub スタイル)の見出しスラグを前提としていたイントラドキュメントのアンカーリンクを、このサイトの階層的で親セクションをプレフィックスに持つスラグに合わせて修正しました

  • 0/1px の間隔バイパスのドキュメントを修正(ゼロバイパスは allowed の中のごく一部の 0 サフィックス付きクラスだけでなく、あらゆる 数値間隔/サイズルールに適用される)し、設定、例、メソドロジー、制限事項の各ページで他のいくつかの正確性の修正を行いました

  • README を上記すべてについてドキュメントサイトと再同期しました