From 92793177bd9b2fb023309ce0b9103fb8a277751d Mon Sep 17 00:00:00 2001 From: bymyself Date: Mon, 27 Oct 2025 12:42:25 -0700 Subject: [PATCH] fix: Replace eslint-plugin-tailwindcss with v4-compatible plugin The eslint-plugin-tailwindcss@4.0.0-beta.0 plugin is incompatible with Tailwind v4 as it tries to access removed v3 internal files, causing: "Cannot find module 'tailwindcss/dist/lib/setupContextUtils.js'" This replaces it with eslint-plugin-tailwind-v4@1.0.13 which is specifically designed for Tailwind v4 compatibility. --- eslint.config.ts | 13 +++++------ package.json | 3 +-- pnpm-lock.yaml | 56 ++++++++++++++------------------------------- pnpm-workspace.yaml | 3 +-- 4 files changed, 25 insertions(+), 50 deletions(-) diff --git a/eslint.config.ts b/eslint.config.ts index 2a4d219a9..9b1f3058a 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -5,7 +5,9 @@ import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescrip import { importX } from 'eslint-plugin-import-x' import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' import storybook from 'eslint-plugin-storybook' -import tailwind from 'eslint-plugin-tailwindcss' +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore No types available for this plugin +import tailwindV4Plugin from 'eslint-plugin-tailwind-v4' import unusedImports from 'eslint-plugin-unused-imports' import pluginVue from 'eslint-plugin-vue' import { defineConfig } from 'eslint/config' @@ -94,10 +96,6 @@ export default defineConfig([ pluginJs.configs.recommended, tseslintConfigs.recommended, - // Difference in typecheck on CI vs Local - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore Bad types in the plugin - tailwind.configs['flat/recommended'], pluginVue.configs['flat/recommended'], eslintPluginPrettierRecommended, storybook.configs['flat/recommended'], @@ -109,7 +107,8 @@ export default defineConfig([ plugins: { 'unused-imports': unusedImports, // @ts-expect-error Bad types in the plugin - '@intlify/vue-i18n': pluginI18n + '@intlify/vue-i18n': pluginI18n, + 'tailwind-v4': tailwindV4Plugin }, rules: { '@typescript-eslint/no-floating-promises': 'error', @@ -129,7 +128,7 @@ export default defineConfig([ 'import-x/no-relative-packages': 'error', 'unused-imports/no-unused-imports': 'error', 'no-console': ['error', { allow: ['warn', 'error'] }], - 'tailwindcss/no-custom-classname': 'off', // TODO: fix + 'tailwind-v4/no-custom-classname': 'off', // TODO: fix 'vue/no-v-html': 'off', // Enforce dark-theme: instead of dark: prefix 'vue/no-restricted-class': ['error', '/^dark:/'], diff --git a/package.json b/package.json index 3513162b0..d7878f85b 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "@storybook/vue3-vite": "catalog:", "@tailwindcss/vite": "catalog:", "@trivago/prettier-plugin-sort-imports": "catalog:", - "@types/eslint-plugin-tailwindcss": "catalog:", "@types/fs-extra": "catalog:", "@types/jsdom": "catalog:", "@types/node": "catalog:", @@ -78,7 +77,7 @@ "eslint-plugin-import-x": "catalog:", "eslint-plugin-prettier": "catalog:", "eslint-plugin-storybook": "catalog:", - "eslint-plugin-tailwindcss": "catalog:", + "eslint-plugin-tailwind-v4": "catalog:", "eslint-plugin-unused-imports": "catalog:", "eslint-plugin-vue": "catalog:", "fs-extra": "^11.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb38350f7..1f7f4a7b3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,9 +87,6 @@ catalogs: '@trivago/prettier-plugin-sort-imports': specifier: ^5.2.0 version: 5.2.2 - '@types/eslint-plugin-tailwindcss': - specifier: ^3.17.0 - version: 3.17.0 '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 @@ -153,9 +150,9 @@ catalogs: eslint-plugin-storybook: specifier: ^9.1.6 version: 9.1.6 - eslint-plugin-tailwindcss: - specifier: 4.0.0-beta.0 - version: 4.0.0-beta.0 + eslint-plugin-tailwind-v4: + specifier: ^1.0.13 + version: 1.0.13 eslint-plugin-unused-imports: specifier: ^4.2.0 version: 4.2.0 @@ -519,9 +516,6 @@ importers: '@trivago/prettier-plugin-sort-imports': specifier: 'catalog:' version: 5.2.2(@vue/compiler-sfc@3.5.13)(prettier@3.6.2) - '@types/eslint-plugin-tailwindcss': - specifier: 'catalog:' - version: 3.17.0 '@types/fs-extra': specifier: 'catalog:' version: 11.0.4 @@ -570,9 +564,9 @@ importers: eslint-plugin-storybook: specifier: 'catalog:' version: 9.1.6(eslint@9.35.0(jiti@2.4.2))(storybook@9.1.6(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@5.4.19(@types/node@20.14.10)(lightningcss@1.30.1)(terser@5.39.2)))(typescript@5.9.2) - eslint-plugin-tailwindcss: + eslint-plugin-tailwind-v4: specifier: 'catalog:' - version: 4.0.0-beta.0(tailwindcss@4.1.12) + version: 1.0.13(eslint@9.35.0(jiti@2.4.2)) eslint-plugin-unused-imports: specifier: 'catalog:' version: 4.2.0(@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2)) @@ -3155,9 +3149,6 @@ packages: '@types/diff-match-patch@1.0.36': resolution: {integrity: sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==} - '@types/eslint-plugin-tailwindcss@3.17.0': - resolution: {integrity: sha512-ucQGf2YIdTcndYcxRU3UdZgmhUHsOlbIF4BaRtl0op+7k2JmqM2i3aXZ6XIcfZgVq1ZKov7VM5c/BR81ukmkyg==} - '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -4700,11 +4691,11 @@ packages: eslint: '>=8' storybook: ^9.1.6 - eslint-plugin-tailwindcss@4.0.0-beta.0: - resolution: {integrity: sha512-WWCajZgQu38Sd67ZCl2W6i3MRzqB0d+H8s4qV9iB6lBJbsDOIpIlj6R1Fj2FXkoWErbo05pZnZYbCGIU9o/DsA==} - engines: {node: '>=18.12.0'} + eslint-plugin-tailwind-v4@1.0.13: + resolution: {integrity: sha512-IXCv/Miug48/mXaipqdxypsozGvbgLz/8C0ZMCf0WFW1FBXJz4xPaRJFjbsY9vu1Vbf4+xfyLqz8inbQyc6MZw==} + engines: {node: '>=14.0.0'} peerDependencies: - tailwindcss: ^3.4.0 || ^4.0.0 + eslint: '>=8.0.0' eslint-plugin-unused-imports@4.2.0: resolution: {integrity: sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==} @@ -7163,11 +7154,6 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tailwind-api-utils@1.0.3: - resolution: {integrity: sha512-KpzUHkH1ug1sq4394SLJX38ZtpeTiqQ1RVyFTTSY2XuHsNSTWUkRo108KmyyrMWdDbQrLYkSHaNKj/a3bmA4sQ==} - peerDependencies: - tailwindcss: ^3.3.0 || ^4.0.0 || ^4.0.0-beta - tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} @@ -7626,6 +7612,9 @@ packages: vue-component-type-helpers@3.1.1: resolution: {integrity: sha512-B0kHv7qX6E7+kdc5nsaqjdGZ1KwNKSUQDWGy7XkTYT7wFsOpkEyaJ1Vq79TjwrrtuLRgizrTV7PPuC4rRQo+vw==} + vue-component-type-helpers@3.1.2: + resolution: {integrity: sha512-ch3/SKBtxdZq18vsEntiGCdSszCRNfhX5QaTxjSacCAXLlNQRXfXo+ANjoQEYJMsJOJy1/vHF6Tkc4s85MS+zw==} + vue-demi@0.14.10: resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} engines: {node: '>=12'} @@ -10308,7 +10297,7 @@ snapshots: storybook: 9.1.6(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@5.4.19(@types/node@20.14.10)(lightningcss@1.30.1)(terser@5.39.2)) type-fest: 2.19.0 vue: 3.5.13(typescript@5.9.2) - vue-component-type-helpers: 3.1.1 + vue-component-type-helpers: 3.1.2 '@swc/helpers@0.5.17': dependencies: @@ -10613,8 +10602,6 @@ snapshots: '@types/diff-match-patch@1.0.36': {} - '@types/eslint-plugin-tailwindcss@3.17.0': {} - '@types/estree@1.0.5': {} '@types/estree@1.0.8': {} @@ -12380,13 +12367,9 @@ snapshots: - supports-color - typescript - eslint-plugin-tailwindcss@4.0.0-beta.0(tailwindcss@4.1.12): + eslint-plugin-tailwind-v4@1.0.13(eslint@9.35.0(jiti@2.4.2)): dependencies: - fast-glob: 3.3.3 - postcss: 8.5.6 - synckit: 0.11.11 - tailwind-api-utils: 1.0.3(tailwindcss@4.1.12) - tailwindcss: 4.1.12 + eslint: 9.35.0(jiti@2.4.2) eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2))(typescript@5.9.2))(eslint@9.35.0(jiti@2.4.2)): dependencies: @@ -15431,13 +15414,6 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tailwind-api-utils@1.0.3(tailwindcss@4.1.12): - dependencies: - enhanced-resolve: 5.18.3 - jiti: 2.5.1 - local-pkg: 1.1.2 - tailwindcss: 4.1.12 - tailwind-merge@2.6.0: {} tailwindcss-primeui@0.6.1(tailwindcss@4.1.12): @@ -15983,6 +15959,8 @@ snapshots: vue-component-type-helpers@3.1.1: {} + vue-component-type-helpers@3.1.2: {} + vue-demi@0.14.10(vue@3.5.13(typescript@5.9.2)): dependencies: vue: 3.5.13(typescript@5.9.2) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a7e91efdc..397b8c44d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -30,7 +30,6 @@ catalog: '@storybook/vue3-vite': ^9.1.1 '@tailwindcss/vite': ^4.1.12 '@trivago/prettier-plugin-sort-imports': ^5.2.0 - '@types/eslint-plugin-tailwindcss': ^3.17.0 '@types/fs-extra': ^11.0.4 '@types/jsdom': ^21.1.7 '@types/node': ^20.14.8 @@ -52,7 +51,7 @@ catalog: eslint-plugin-import-x: ^4.16.1 eslint-plugin-prettier: ^5.5.4 eslint-plugin-storybook: ^9.1.6 - eslint-plugin-tailwindcss: 4.0.0-beta.0 + eslint-plugin-tailwind-v4: ^1.0.13 eslint-plugin-unused-imports: ^4.2.0 eslint-plugin-vue: ^10.4.0 firebase: ^11.6.0