Design Token Lint

Type to search...

to open search from anywhere

プログラマティック API

作成2026年4月10日Takeshi Takatsudo

design-token-lint を Node.js ライブラリとして使用 — 文字列、ファイル、または個別のクラス名をリント。

@zudolab/design-token-lint は、ビルドツール、エディタ、またはカスタムツールとの統合のための小さな API をエクスポートしています。

インストール

pnpm add @zudolab/design-token-lint

エクスポート

import {
  // ファイル/コンテンツのリント
  lintFile,
  lintContent,
  type LintResult,

  // 単一クラスのチェック
  checkClass,
  checkClassWithConfig,
  type Violation,

  // 設定の読み込みとコンパイル
  loadConfig,
  compileConfig,
  compilePattern,
  setConfig,
  getConfig,
  DEFAULT_CONFIG,
  type LintConfig,
  type CompiledConfig,
  type CompiledRule,

  // クラス抽出
  extractClasses,
  type ExtractedClass,
} from '@zudolab/design-token-lint';

ファイルとコンテンツのリント

lintFile(filePath)

ディスクからファイルを読み込み、違反ごとに 1 エントリの配列を返します。

const results = await lintFile('src/App.tsx');
for (const r of results) {
  console.log(`${r.filePath}:${r.line}  ${r.className}  ${r.reason}`);
}

Promise<LintResult[]> を返します:

interface LintResult {
  filePath: string;
  line: number;
  className: string;
  reason: string;
}

各エントリは 1 つの違反を表すフラットなレコードです。違反がない場合は空配列が返ります。

lintContent(filePath, content)

文字列を直接リントします — エディタプラグインやインメモリコンテンツに便利です。LintResult[] を返します(上記と同じ形)。

const results = lintContent('file.tsx', '<div className="p-4 bg-gray-500">');
// [
//   { filePath: 'file.tsx', line: 1, className: 'p-4', reason: '...' },
//   { filePath: 'file.tsx', line: 1, className: 'bg-gray-500', reason: '...' }
// ]

単一クラスのチェック

checkClass(className)

1 つのクラス名をアクティブな設定に対してチェックします。禁止されている場合は Violation、通る場合は null を返します。

const violation = checkClass('p-4');
if (violation) {
  console.error(violation.reason);
  // "Numeric spacing \"p-4\" — use semantic token (hgap-*/vgap-*) or arbitrary value"
}

Violation | null を返します:

interface Violation {
  className: string;
  reason: string;
}

checkClassWithConfig(className, compiledConfig)

上記と同じですが、グローバル設定ではなく明示的なコンパイル済み設定を使用します。

import { loadConfig, compileConfig, checkClassWithConfig } from '@zudolab/design-token-lint';

const config = await loadConfig(process.cwd());
const compiled = compileConfig(config);

const violation = checkClassWithConfig('bg-blue-500', compiled);

設定の操作

loadConfig(cwd)

ディレクトリから .design-token-lint.json または design-token-lint.config.json を読み込みます。どちらも存在しない場合は DEFAULT_CONFIG にフォールバックします。

const config = await loadConfig(process.cwd());

compileConfig(config)

プレーンな設定オブジェクトをマッチング用の効率的なルールセットにコンパイルします。

const compiled = compileConfig({
  prohibited: ['p-{n}', 'bg-{color}-{shade}'],
  allowed: ['p-0'],
  ignore: [],
});

setConfig(compiled) / getConfig()

checkClass()lintFile() が使用するグローバルなコンパイル済み設定を設定または取得します。

setConfig(compiled);
const active = getConfig();

compilePattern(pattern)

単一のパターン文字列(p-{n} など)を CompiledRule にコンパイルします。

const rule = compilePattern('bg-{color}-{shade}');
// { prefix: 'bg', valuePattern: /^(slate|gray|...)-(\d{2,3})$/, reasonTemplate: '...', isSpacingRule: false }

クラスの抽出

extractClasses(content)

ソースファイル文字列からすべてのクラス名トークンを行番号付きで抽出します。

const extracted = extractClasses('<div className="p-4 bg-red-500">');
// [
//   { className: 'p-4', line: 1 },
//   { className: 'bg-red-500', line: 1 }
// ]

ExtractedClass[] を返します:

interface ExtractedClass {
  className: string;
  line: number;
}

サポートされる構文:

  • className="..."class="..."(JSX/Astro)
  • className={'...'} シングルクォート中括弧
  • className={`...`} テンプレートリテラル(単純なケース)
  • class:list={["...", '...']} Astro class
    配列
  • cn(...)clsx(...)classNames(...)twMerge(...) ユーティリティ呼び出し

LintConfig

interface LintConfig {
  prohibited: string[];
  allowed: string[];
  ignore: string[];
  patterns?: string[];
  suggestionSuffix?: string;
}

LintResult

interface LintResult {
  filePath: string;
  line: number;
  className: string;
  reason: string;
}

Violation

interface Violation {
  className: string;
  reason: string;
}

例: カスタムリンタースクリプト

import { glob } from 'glob';
import {
  loadConfig,
  compileConfig,
  setConfig,
  lintFile,
} from '@zudolab/design-token-lint';

async function main() {
  const config = await loadConfig(process.cwd());
  setConfig(compileConfig(config));

  const files = await glob('src/**/*.{tsx,jsx}');
  let totalViolations = 0;

  for (const file of files) {
    const results = await lintFile(file);
    for (const r of results) {
      console.log(`${r.filePath}:${r.line}  ${r.className}  ${r.reason}`);
      totalViolations++;
    }
  }

  process.exit(totalViolations > 0 ? 1 : 0);
}

main();

Revision History