oward

Generate TwMerge Config

Script de génération de la configuration tailwind-merge depuis le fichier CSS de Tailwind 4.

⚙️ TAILWIND-MERGE CONFIG GENERATOR
CSS: app/globals.css
Output: lib/tw-merge-extended-config.ts
Parsing @theme tokens...
✔ CSS file parsed successfully
Analyzing color tokens...
✔ Found 35 color tokens
Analyzing spacing tokens...
✔ Found 12 spacing tokens
Analyzing radius tokens...
✔ Found 8 radius tokens
Building TypeScript config...
✔ Configuration generated
Writing output file...
✔ File written successfully

Installation

Le script fait partie du registry et peut être ajouté à votre projet via la CLI shadcn :

npx shadcn@latest add https://ui.oward.dev/r/registry.json generate-twmerge-config

Vue d'ensemble

Le script generate-twmerge-config.js est un outil d'automatisation qui génère automatiquement la configuration tailwind-merge depuis vos tokens personnalisés Tailwind CSS v4. Il analyse votre fichier CSS contenant des tokens @theme, extrait les valeurs personnalisées, et génère un fichier TypeScript prêt à l'emploi avec support complet des types.

  • Extraction automatique des tokens depuis @theme blocks
  • Support complet : colors, spacing, radius, shadows, font-size, font-family, etc.
  • Gestion des @import avec résolution récursive et protection path traversal

Pourquoi ce script ?

Lorsque vous utilisez des tokens personnalisés avec Tailwind CSS v4, tailwind-merge ne les reconnaît pas par défaut. Cela peut causer des problèmes lors de la fusion de classes :

// ❌ Sans configuration
cn("bg-primary", "bg-accent"); // Retourne: "bg-primary bg-accent" (les deux classes !)

// ✅ Avec configuration générée
cn("bg-primary", "bg-accent"); // Retourne: "bg-accent" (correctement fusionné)

Ce script automatise complètement la génération de cette configuration.

Intégration avec cn()

Une fois la configuration générée, utilisez-la dans votre fonction utilitaire cn() :

// lib/utils.ts (version de base)
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  // ⚠️ Les tokens personnalisés ne sont pas fusionnés correctement.
  return twMerge(clsx(inputs)); 
}

Structure attendue

Le script s'attend à trouver vos tokens Tailwind CSS v4 dans un fichier CSS avec des blocks @theme :

/* style.css */
@theme {
  /* Colors */
  --color-primary: #3b82f6;
  --color-secondary: #8b5cf6;
  --color-accent: #f59e0b;

  /* Spacing */
  --spacing-xs: 0.25rem;
  --spacing-sm: 0.5rem;
  --spacing-md: 1rem;

  /* Radius */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 1rem;
}

Utilisation

Commande de base

Exécutez le script depuis le répertoire racine de votre projet :

node generate-twmerge-config.js

Le script va :

  1. Lire votre fichier CSS (par défaut : app/globals.css)
  2. Extraire tous les tokens depuis les blocks @theme
  3. Générer le fichier TypeScript de configuration (par défaut : lib/tw-merge-extended-config.ts)
  4. Créer les exports de types pour l'autocomplétion IDE

Options CLI

Le script accepte plusieurs options pour personnaliser son comportement :

OptionAliasDescriptionValeur par défaut
--path <path>-pChemin de base du projetRépertoire courant
--css <path>-cChemin vers le fichier CSSapp/globals.css
--output <path>-oChemin du fichier de sortielib/tw-merge-extended-config.ts
--help-hAffiche l'aide-

Exemples d'utilisation

# Exécution depuis le répertoire courant
node generate-twmerge-config.js

# Avec un chemin spécifique

node generate-twmerge-config.js --path /path/to/project

# Avec vérification du code de sortie

node generate-twmerge-config.js || exit 1

Catégories de tokens supportées

Le script détecte automatiquement plusieurs catégories de tokens CSS :

CatégoriePattern CSSExemple
Colors--color-*--color-primary, --color-accent
Typography--font-*, --text-*--font-sans, --text-lg
Font Weight--font-weight-*--font-weight-bold
Tracking--tracking-*--tracking-tight
Leading--leading-*--leading-relaxed
Spacing--spacing-*--spacing-md, --spacing-xl
Container--container-*--container-sm
Radius--radius-*--radius-sm, --radius-full
Shadow--shadow-*--shadow-md, --shadow-2xl
Inset Shadow--inset-shadow-*--inset-shadow-sm
Drop Shadow--drop-shadow-*--drop-shadow-lg
Blur--blur-*--blur-sm, --blur-xl
Perspective--perspective-*--perspective-dramatic
Aspect--aspect-*--aspect-video
Breakpoint--breakpoint-*--breakpoint-mobile
Ease--ease-*--ease-in-out
Animate--animate-*--animate-spin

Résolution des @import

Le script supporte la résolution récursive des @import CSS :

/* base.css */
@import "./colors.css";
@import "./spacing.css";

/* colors.css */
@theme {
  --color-primary: blue;
}

/* spacing.css */
@theme {
  --spacing-md: 1rem;
}

Fonctionnalités :

  • Résolution récursive des imports imbriqués
  • Détection et prévention des imports circulaires
  • Protection contre le path traversal (sécurité)
  • Ignore automatiquement les imports HTTP/HTTPS

Fichier généré

Le script génère un fichier TypeScript avec la configuration complète :

/**
 * @fileoverview Auto-generated tailwind-merge configuration
 * @registry-ignore
 *
 * @description This file is generated by generate-twmerge-config script.
 * Do not edit manually - regenerate using the script instead.
 */

import { extendTailwindMerge } from "tailwind-merge";

/**
 * Custom color tokens extracted from Tailwind CSS v4 @theme
 */
const customColors = [
  "accent",
  "primary",
  "secondary",
  // ... (sorted alphabetically)
] as const;

/**
 * Type helper for customColors
 */
export type CustomColorsToken = (typeof customColors)[number];

/**
 * Extended tailwind-merge configuration
 */
export const twMergeExtendedConfig = {
  extend: {
    classGroups: {
      "text-color": [{ text: customColors }],
      "bg-color": [{ bg: customColors }],
      "border-color": [{ border: customColors }],
      // ... (all color utilities)
    },
  },
} as const;

/**
 * Extended tailwind-merge instance with custom tokens
 */
export const extendedTwMerge = extendTailwindMerge(twMergeExtendedConfig);

Limitations connues

Le script utilise un parser CSS personnalisé optimisé pour les tokens @theme.

Limitation connue : Les valeurs contenant des délimiteurs de commentaires CSS (/* et */) dans des chaînes de caractères peuvent être mal interprétées.

Exemple edge case :

--url: "https://example.com/*/path/*"; /* comment */