プログラマティック API
design-token-lint を Node.js ライブラリとして使用 — 文字列、ファイル、または個別のクラス名をリント。
@takazudo/zudo-design-token-lint は、ビルドツール、エディタ、またはカスタムツールとの統合のための小さな API をエクスポートしています。
インストール
pnpm add @takazudo/zudo-design-token-lint
エクスポート
import {
// ファイル/コンテンツのリント
lintFile,
lintContent,
type LintResult,
// 単一クラスのチェック
checkClass,
checkClassWithConfig,
type Violation,
// 設定の読み込みとコンパイル
loadConfig,
compileConfig,
compilePattern,
setConfig,
getConfig,
DEFAULT_CONFIG,
DEFAULT_CLASS_ATTRIBUTES,
DEFAULT_CLASS_FUNCTIONS,
type LintConfig,
type CompiledConfig,
type CompiledRule,
// クラス抽出
extractClasses,
type ExtractedClass,
type ExtractorOptions,
} from '@takazudo/zudo-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 '@takazudo/zudo-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, options?)
ソースファイル文字列からすべてのクラス名トークンを行番号付きで抽出します。オプションで ExtractorOptions を渡すと、抽出対象の属性名や関数名をカスタマイズできます。
const extracted = extractClasses('<div className="p-4 bg-red-500">');
// [
// { className: 'p-4', line: 1 },
// { className: 'bg-red-500', line: 1 }
// ]
カスタム属性や関数名を指定する場合:
const extracted = extractClasses('<div myClass="p-4">', {
classAttributes: ['className', 'class', 'myClass'],
classFunctions: ['cn', 'clsx', 'myMerge'],
});
ExtractedClass[] を返します:
interface ExtractedClass {
className: string;
line: number;
}
省略時は DEFAULT_CLASS_ATTRIBUTES と DEFAULT_CLASS_FUNCTIONS が使用されます。
サポートされる構文:
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;
classAttributes?: string[];
classFunctions?: string[];
}
ExtractorOptions
interface ExtractorOptions {
classAttributes?: string[];
classFunctions?: string[];
}
DEFAULT_CLASS_ATTRIBUTES / DEFAULT_CLASS_FUNCTIONS
抽出に使用するデフォルトの属性名と関数名の定数です。
const DEFAULT_CLASS_ATTRIBUTES: string[];
// ['className', 'class']
const DEFAULT_CLASS_FUNCTIONS: string[];
// ['cn', 'clsx', 'classNames', 'twMerge']
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 '@takazudo/zudo-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();