eslint-plugin-tailwindcss icon indicating copy to clipboard operation
eslint-plugin-tailwindcss copied to clipboard

[BUG] The plugin does not pick up tailwind configs in projects nested within monorepos

Open quesabe opened this issue 1 year ago • 14 comments

Describe the bug When a frontend project is nested within a monorepo, any linting process run not from the frontend folder does not see the tailwind config. This is especially apparent with VSCode intellisense - the eslint process is run at the project root level, while the tailwind config resides somewhere nested. Since the config is not found the plugin des not pick up any custom colours and other stuff.

To Reproduce Assumed folder structure:

/rootProject
├ package.json
├ /frontend
│  ├ .eslintrc.js 
│  ├ package.json
│  ├ tailwind.config.js
  1. When eslint is run from rootProject folder the tailwind.config.js is not found.
  2. When eslint is run from frontend folder the tailwind.config.js is found.
  3. eslint process in VSCode is run from rootProject and thus does not find the tailwind.config.js.

BTW, the eslint config is picked up and the rules from eslint-plugin-tailwindcss apply - they just don't use the custom theme and other settings.

Expected behavior Tailwind config is discoverable as long as it is in the same folder with the eslint config.

Environment (please complete the following information):

Additional context Seems like this code is the reason for the behaviour: https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/lib/util/customConfig.js#L26

The path.resolve() resolves to the rootProject folder, while the config is at rootProject/frontend.

PS. I can make it work if I open the frontend folder in a separate editor window. However it is very inconvenient in a large project.

quesabe avatar May 04 '23 19:05 quesabe

Do you mind sharing your current .eslintrc.js file?

I just fixed a similar issue and this worked for me:

// .eslintrc.js
settings: {
  tailwindcss: {
    config: path.join(__dirname, './tailwind.config.js'),
  },
},

Gomah avatar May 08 '23 06:05 Gomah

I can confirm @Gomah 's solution works.

av-erencelik avatar May 10 '23 10:05 av-erencelik

Do you mind sharing your current .eslintrc.js file?

I just fixed a similar issue and this worked for me:

// .eslintrc.js
settings: {
  tailwindcss: {
    config: path.join(__dirname, './tailwind.config.js'),
  },
},

It's fairly simple:

{
  "env": {
    "browser": true,
    "jest": true,
    "node": false
  },
  "plugins": [
    "tailwindcss"
  ],
  "rules": {
    "tailwindcss/classnames-order": [
      "error"
    ],
    "tailwindcss/enforces-negative-arbitrary-values": [
      "error"
    ],
    "tailwindcss/enforces-shorthand": [
      "error"
    ],
    "tailwindcss/migration-from-tailwind-2": [
      "error"
    ],
    "tailwindcss/no-arbitrary-value": [
      "off"
    ],
    "tailwindcss/no-contradicting-classname": [
      "error"
    ],
    "tailwindcss/no-custom-classname": [
      "error",
    ]
  },
  "settings": {
    "tailwindcss": {
      "callees": [
        "cn"
      ],
      "config": "tailwind-config.js"
    }
  }
}

In fact I can't use the workaround, since I use a JSON config.

quesabe avatar May 13 '23 19:05 quesabe

@quesabe did your commit provide a solution for your issue with JSON config ? @Gomah , @av-erencelik & @quesabe Can we close this issue ? It looks like you found a workaround...

francoismassart avatar May 30 '23 08:05 francoismassart

@quesabe did your commit provide a solution for your issue with JSON config ? @Gomah , @av-erencelik & @quesabe Can we close this issue ? It looks like you found a workaround...

@francoismassart Actually no, the commit does not solve the current issue completely. It helps in my case, where I can get rid of the custom config. But if anybody needs to use a json eslint config, refer to a custom tailwind config, and all this done not in the root folder of a project, then it still won't load the tailwind config properly.

However I'm not sure if it has a solution within the plugin repo - maybe it's a problem with eslint itself.

quesabe avatar Jun 07 '23 05:06 quesabe

After doing some digging, it looks like the vscode-eslint extension is not passing the context object to the rules when running from a higher level folder. You can confirm this yourself by being in your root project folder and running npx eslint ./your-package where your-package is where the eslint and tailwind config files are and it will lint the whole project without issue.

Apparently the solution is the eslint.workingDirectories setting in the workspace .vscode/settings.json. The following config should fix the problem.

// .vscode/settings.json
{
  "eslint.workingDirectories": ["./your-package"],
}

lachieh avatar Jun 30 '23 00:06 lachieh

@lachieh Your suggested workaround with custom .vscode/settings.json wouldn't be practical for teams working on same monorepo, since custom vscode settings do not normally belong to codebase committed to git.

maslennikov avatar Jul 18 '23 11:07 maslennikov

@lachieh Your suggested workaround with custom .vscode/settings.json wouldn't be practical for teams working on same monorepo, since custom vscode settings do not normally belong to codebase committed to git.

@maslennikov I didn't actually say that this file should be committed. I just provided a solution for correctly configuring the eslint extension.

Whether it is practical or not is subjective and committing this file is a team decision. If your team has decided that shared workspace settings should actually not be shared, then perhaps you can find and suggest a different solution instead of just spreading your (unsolicited) opinion.

For example, a common pattern is to add the .vscode/settings.json file in .gitignore but include shared settings in a .vscode/settings.default.json so that developers can copy required settings and customize the settings themselves.

lachieh avatar Jul 18 '23 11:07 lachieh

Gomah thanks for the suggestion! Works 🚀

jrozbicki avatar Jul 31 '23 11:07 jrozbicki

@quesabe Thank you for the solution! It was working for me

nodegin avatar Sep 12 '23 11:09 nodegin

I was also facing this problem in a Monorepo environment using Turborepo, but I tried the contents of https://github.com/microsoft/vscode-eslint/issues/1706#issuecomment-1785746444 I tried the contents of and it worked fine.

yossydev avatar Nov 08 '23 03:11 yossydev

I think the only way to solve this reliably is by searching for the config based on the location of the file that is being linted. Similar to what typescript-eslint is doing now, see: https://typescript-eslint.io/blog/parser-options-project-true/#introducing-true

joshuajaco avatar Dec 12 '23 13:12 joshuajaco

Do you mind sharing your current .eslintrc.js file?

I just fixed a similar issue and this worked for me:

// .eslintrc.js
settings: {
  tailwindcss: {
    config: path.join(__dirname, './tailwind.config.js'),
  },
},

it works in monorepo thank you soo much!!

mamlzy avatar Jan 16 '24 10:01 mamlzy

Do you mind sharing your current .eslintrc.js file?

I just fixed a similar issue and this worked for me:

// .eslintrc.js
settings: {
  tailwindcss: {
    config: path.join(__dirname, './tailwind.config.js'),
  },
},

This works but I'm not using a monorepo. I'm using the base Vite template from pnpm create vite.

This worked for me when my pnpm lint script was complaining that __dirname is not defined in ES module scope

  tailwindcss: {
    config: path.join(import.meta.dirname, 'tailwind.config.js'),
  }

DigitalNaut avatar Aug 13 '24 12:08 DigitalNaut