Español
Migrar desde eslint-plugin-better-tailwindcss
eslint-plugin-better-tailwindcss corre en ESLint y, como JS plugin, en oxlint. oxlint-tailwindcss está hecho para oxlint y Tailwind v4. Cada una de las 15 reglas de better-tailwindcss 4.7.0 tiene su equivalente aquí, y cada par reporta el mismo ejemplo — las tablas de abajo se verifican contra él cada semana, con su última versión.
Reglas
| better-tailwindcss | oxlint-tailwindcss | Notas |
|---|---|---|
enforce-consistent-class-order | enforce-sort-order | Su order: "official" por defecto es el orden de esta regla. Las clases desconocidas van primero, en el orden en que están escritas, como con su unknownClassOrder: "preserve". order: "strict" → mode: "strict", que también agrupa las clases por cadena de variants (el orden dentro del grupo puede variar). asc, desc y las opciones componentClass* / unknownClass* no tienen equivalente. |
enforce-consistent-important-position | enforce-consistent-important-position | position: "recommended" → "suffix" (el default, p-4!); "legacy" → "prefix" (!p-4). |
enforce-consistent-line-wrapping | enforce-consistent-line-wrapping | printWidth, classesPerLine y group significan lo mismo. El autofix solo reescribe template literals — un atributo string se reporta, no se reescribe — y una línea que pasa el printWidth se vuelve a envolver solo con wrapLines. indent, tabWidth, lineBreakStyle, preferSingleLine, strictness y vueConvertToBinding no tienen equivalente: la indentación sale del código. |
enforce-consistent-variant-order | consistent-variant-order | Las dos escriben las cadenas de afuera hacia adentro (sm:hover:). Esta regla además ordena color scheme y variants de atributos (dark:hover:, data-[state=open]:hover:), que la suya deja como están; order fija el tuyo. |
enforce-consistent-variable-syntax | enforce-consistent-variable-syntax | syntax: "shorthand" es el default en las dos; "variable" → "explicit". |
enforce-shorthand-classes | enforce-shorthand | |
enforce-logical-properties | enforce-logical | ignore → allowlist (también expresiones regulares). direction la limita a las utilities inline o block; enforce-physical es la regla inversa. |
enforce-canonical-classes | enforce-canonical | Su collapse (juntar mt-2 mb-2 en my-2) aquí es enforce-shorthand. ignore y logical no tienen equivalente. |
no-duplicate-classes | no-duplicate-classes | |
no-deprecated-classes | no-deprecated-classes | |
no-unnecessary-whitespace | no-unnecessary-whitespace | Los saltos de línea siempre se conservan, como con su allowMultiline: true. |
no-concatenated-classes | no-dynamic-classes | Las dos reportan una clase armada con ${} o +. Esta la reporta cuando la clase armada empieza con una utility o una variant de Tailwind, así que "p-4 " + extra y `icon-${name}` están bien. |
no-unknown-classes | no-unknown-classes | ignore (expresiones regulares) → allowlist (nombres exactos) e ignorePrefixes. Las clases que define tu CSS (@layer components, @utility) siempre se conocen, así que su setting detectComponentClasses no tiene equivalente. |
no-conflicting-classes | no-conflicting-classes | También reporta una clase que otra vuelve redundante (reportRedundant), y allow exime pares. |
no-restricted-classes | no-restricted-classes | restrict: [{ pattern, message }] → patterns: [{ pattern, message }], y classes para nombres exactos. No hay fix. |
Settings
settings["better-tailwindcss"] | settings.tailwindcss | Notas |
|---|---|---|
entryPoint | entryPoint | Aquí es obligatorio. Un string, o un mapping glob → CSS para un monorepo. |
cwd | entryPoint | Mapea los archivos de cada package a su CSS con entryPoint: [{ files, use }], o dale al package su propio .oxlintrc.json. |
rootFontSize | rootFontSize | |
selectors | attributes, attributePatterns, callees, calleeExtractors, tags, variablePatterns | Los dos leen class / className, los mismos nombres de variables y la mayoría de los helpers por defecto. Agrega lo que liste el tuyo y este no: el helper dcnb a callees, los tags twc / twx a tags. |
detectComponentClasses | — | Siempre encendido: las clases que define tu CSS se conocen. |
tailwindConfig | — | Una config JavaScript de Tailwind v3; este plugin lee el CSS de Tailwind v4. |
tsconfig | — | |
messageStyle | — |
El cambio, paso a paso
- Instala el plugin:
pnpm add -D oxlint-tailwindcss(yoxlint, si better-tailwindcss corría en ESLint). - En
.oxlintrc.json, agrega"jsPlugins": ["oxlint-tailwindcss"]y pasasettings["better-tailwindcss"]asettings.tailwindcsscon la tabla de settings.entryPointes obligatorio. - Renombra cada
better-tailwindcss/<regla>a latailwindcss/<regla>de la tabla de reglas, y convierte sus opciones en las que nombran sus notas. O parte de la config recomendada y agrega encima lo que tenías. - Quita eslint-plugin-better-tailwindcss — de
jsPlugins, o de la config de ESLint — y desinstálalo, para que los dos no reporten la misma clase. - Corre
oxlint, y despuésoxlint --fixpara los autofixes.
Una config típica, antes y después:
jsonc
// Antes
{
"jsPlugins": ["eslint-plugin-better-tailwindcss"],
"settings": { "better-tailwindcss": { "entryPoint": "src/styles.css" } },
"rules": {
"better-tailwindcss/enforce-consistent-class-order": "warn",
"better-tailwindcss/enforce-consistent-important-position": ["warn", { "position": "legacy" }],
"better-tailwindcss/no-unknown-classes": ["error", { "ignore": ["^swiper-"] }],
"better-tailwindcss/no-concatenated-classes": "error"
}
}
// Después
{
"jsPlugins": ["oxlint-tailwindcss"],
"settings": { "tailwindcss": { "entryPoint": "src/styles.css" } },
"rules": {
"tailwindcss/enforce-sort-order": "warn",
"tailwindcss/enforce-consistent-important-position": ["warn", { "position": "prefix" }],
"tailwindcss/no-unknown-classes": ["error", { "ignorePrefixes": ["swiper-"] }],
"tailwindcss/no-dynamic-classes": "error"
}
}Qué más cambia
- Templates de Vue, Svelte y Astro. En oxlint, los JS plugins ven solo los bloques
<script>de esos archivos — better-tailwindcss corriendo en ESLint con un parser de framework también lee los templates. Mira Vue, Svelte y Astro. - Tailwind v3. Este plugin lee el CSS de Tailwind v4 (v4.1.15 en adelante); un proyecto con
tailwind.config.jstiene que quedarse en better-tailwindcss.
Reglas que better-tailwindcss no tiene
Para revisar una vez hecho el cambio:
enforce-negative-arbitrary-values · enforce-physical · max-class-count · no-arbitrary-value · no-borrowed-component-styles · no-contradicting-variants · no-dark-without-light · no-default-palette · no-hardcoded-colors · no-unnecessary-arbitrary-value · prefer-scale-token · prefer-theme-tokens