tailwindlabs / prettier-plugin-tailwindcss

A Prettier plugin for Tailwind CSS that automatically sorts classes based on our recommended class order.
MIT License
5.57k stars 131 forks source link

Incompatibility with other Prettier plugins #31

Closed reinink closed 1 year ago

reinink commented 2 years ago

To make this plugin work we had to use private Prettier APIs that can only be used by a single plugin at once. This means this plugin is incompatible with other Prettier plugins that are using the same APIs.

This GitHub issue will serve as a place to keep track of which Prettier plugins are incompatible β€”Β and hopefully we'll eventually find some workarounds, or even a proper long term solution. πŸ‘

Known incompatibilities

prettier-plugin-svelte

We've bundled the prettier-plugin-svelte directly into prettier-plugin-tailwindcss, so if you'd like to use this plugin with Svelte, just uninstall prettier-plugin-svelte and everything should work as expected.

Workarounds

While I have not tested it yet, @Mattinton provided one possible workaround in this comment.

jacobwgillespie commented 2 years ago

I originally opened issue #26 about prettier-plugin-organize-imports - in that specific case, I'm able to work around the incompatibility for now by monkey-patching prettier-plugin-tailwindcss so that each overlapping parser uses the preprocess function from prettier-plugin-organize-imports, like so:

// merged-prettier-plugin.js

const tailwind = require('prettier-plugin-tailwindcss')
const organizeImports = require('prettier-plugin-organize-imports')

const combinedFormatter = {
  ...tailwind,
  parsers: {
    ...tailwind.parsers,
    ...Object.keys(organizeImports.parsers).reduce((acc, key) => {
      acc[key] = {
        ...tailwind.parsers[key],
        preprocess(code, options) {
          return organizeImports.parsers[key].preprocess(code, options)
        },
      }
      return acc
    }, {}),
  },
}

module.exports = combinedFormatter
// .prettierrc.js

module.exports = {
  plugins: [require('./merged-prettier-plugin.js')],
  ...
}

This works for now because, from what I can tell, prettier-plugin-tailwindcss doesn't set a preprocessor, and prettier-plugin-organize-imports does all of its work in the preprocessor.

Looking forward to whatever eventual fix removes the need for the patch!

ianjamieson commented 2 years ago

Might be a bit of an edge case. But I am using Laravel and subsequently Blade template files.

So that prettier runs on these files I am using @shufo/prettier-plugin-blade. But as this issue suggests, Tailwind classes are not sorted when run with this plugin.

RobbieTheWagner commented 2 years ago

Seems this one might be incompatible as well https://github.com/withastro/prettier-plugin-astro

sandraroz commented 2 years ago

I'm in a vue 3 project where we use pug and the plugin is not really working with my current setup. I'm also using vetur as a vscode extension that is set to format everything with prettier (html, pug, etc).

Something strange is happening because if I add new lines or extra tabs, the formatter will kick in on save and do its job. However it does not format the order of tailwind classes, even in regular html template tags.

The only time I got the tailwind order to work was by doing the npx prettier --write ./some/file.vue. This only worked in a regular html template tag, not pug.

I tried removing the dependency for the prettier pug plugin and testing it out and it still does not order classes. Is it conflicting with something else?

    "dependencies": {
        "core-js": "^3.8.3",
        "ionicons": "^6.0.1",
        "vue": "^3.2.13",
        "vue-i18n": "^9.2.0-beta.30",
        "vue-router": "^4.0.3",
        "vuex": "^4.0.0"
    },
    "devDependencies": {
        "@babel/core": "^7.12.16",
        "@babel/eslint-parser": "^7.12.16",
        "@prettier/plugin-pug": "^1.19.2",
        "@vue/cli-plugin-babel": "~5.0.0-rc.2",
        "@vue/cli-plugin-eslint": "~5.0.0-rc.2",
        "@vue/cli-plugin-router": "~5.0.0-rc.2",
        "@vue/cli-plugin-vuex": "~5.0.0-rc.2",
        "@vue/cli-service": "~5.0.0-rc.2",
        "@vue/eslint-config-airbnb": "^6.0.0",
        "autoprefixer": "^10.4.2",
        "eslint": "^7.32.0",
        "eslint-plugin-import": "^2.25.3",
        "eslint-plugin-vue": "^8.0.3",
        "eslint-plugin-vuejs-accessibility": "^1.1.0",
        "postcss": "^8.4.5",
        "prettier": "^2.5.1",
        "prettier-plugin-tailwindcss": "^0.1.7",
        "pug": "^3.0.2",
        "pug-plain-loader": "^1.1.0",
        "sass": "^1.32.7",
        "sass-loader": "^12.0.0",
        "tailwindcss": "^3.0.18"
    }
dacodekid commented 2 years ago

@rwwagner90 It's not that this plugin is incompatible with prettier-plugin-astro, but this plugin only works with a few extensions (such as vue, html, etc).

darylknight commented 2 years ago

Subscribing to this. Working with Craft CMS, it's disappointing to see this is incompatible with prettier-plugin-twig-melody.

RobbieTheWagner commented 2 years ago

@rwwagner90 It's not that this plugin is incompatible with prettier-plugin-astro, but this plugin only works with a few extensions (such as vue, html, etc).

Would it be possible to add astro support?

doubled3264 commented 2 years ago

plugin not work when i use @apply on .scss file ? :(

JamesIves commented 2 years ago

Seem to be having problems when parsing Angular HTML files too

nunocasteleira commented 2 years ago

I don't know if it is also related to this, but I can't have prettier-plugin-tailwindcss working alongside @tailwindcss/forms. It says it doesn't find it.

joshmedeski commented 2 years ago

@nunocasteleira this issue is related to prettier plugins conflicting with each other.

If your system can't find @tailwindcss/forms try reinstalling it with npm install @tailwindcss/forms.

If you continue to have problems open an issue on the forms repo.

nunocasteleira commented 2 years ago

If your system can't find @tailwindcss/forms try reinstalling it with npm install @tailwindcss/forms.

Yes, but the problem arises when prettier-plugin-tailwindcss is installed. If I uninstall it, I'm able to run prettier (with @tailwind/forms also installed), whereas it fails with prettier plugin tailwindcss added to my package.json.

joshmedeski commented 2 years ago

@nunocasteleira Can you share your prettier config file with us?

christiaansnoei commented 2 years ago

Might be a bit of an edge case. But I am using Laravel and subsequently Blade template files.

So that prettier runs on these files I am using @shufo/prettier-plugin-blade. But as this issue suggests, Tailwind classes are not sorted when run with this plugin.

Did you find a way to get this working?

nunocasteleira commented 2 years ago

@joshmedeski I have a very minimal prettierrc, it's a Vue project:

{
  "endOfLine": "lf",
  "singleQuote": true,
  "printWidth": 120
}
joshmedeski commented 2 years ago

@nunocasteleira I'm stumped. I don't know why @tailwindcss/forms has any relationship with prettier-plugin-tailwindcss.

nunocasteleira commented 2 years ago

I can share the repo if you want. On 21 Apr 2022, 22:01 +0100, Josh Medeski @.***>, wrote:

@nunocasteleira I'm stumped. I don't know why @tailwindcss/forms has any relationship with prettier-plugin-tailwindcss. β€” Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

scott-lc commented 2 years ago

Also appears to be incompatible with prettier-plugin-jsdoc.

My prettier config:

{
  "$schema": "http://json.schemastore.org/prettierrc",
  "endOfLine": "lf",
  "jsxSingleQuote": true,
  "printWidth": 100,
  "quoteProps": "consistent",
  "singleQuote": true,
  "trailingComma": "none",
  "useTabs": false,

  "overrides": [
    {
      "files": ["**/*.html"],
      "options": {
        "singleQuote": false,
        "tabWidth": 2
      }
    }
  ]
}
tianyingchun commented 2 years ago

what's progress of this issue, i run into this issue, it will break pluginprettier-plugin-organize-imports,

joshmedeski commented 2 years ago

No one has taken ownership to fix this issue.

For now, I suggest everyone expect prettier-plugin-tailwindcss can only be used on its own right now, your other prettier plugins aren't compatible.

After reviewing https://github.com/prettier/prettier/issues/10261 it seems like this plugin is highjacking the typescript parser and so any other plugin that also wants to interact with the same parser they are ignored. If someone understands this please feel free to experiment with rewriting this plugin so other plugins continue to work as expected.

MusicOnline commented 2 years ago

Both prettier-plugin-style-order and prettier-plugin-css-order do not work with prettier-plugin-tailwindcss.

joshmedeski commented 2 years ago

If you want a workaround, you could use the prettier --config flag and have two different configs (using the sharing configurations patter for consistent formatting).

This solution won't work with your IDE on saving, but it could work with a lint-stage solution.

prettier --config ./.prettierrc.tailwind.js --write .
prettier --config ./.prettierrc.other.js --write .

It's not a pretty solution, but I think it's possible for those that strongly want multiple plugin support.

I, personally, have decided to use the tailwind prettier plugin on its own for now to avoid adding this much complexity to my projects.

bai commented 2 years ago

It's not a pretty solution, ...

I see what you did there.

kxpro commented 2 years ago

Also appears to be incompatible with https://github.com/prettier/plugin-php

tianyingchun commented 2 years ago

how about this issue

devrsi0n commented 2 years ago

If you want a workaround, you could use the prettier --config flag and have two different configs (using the sharing configurations patter for consistent formatting).

This solution won't work with your IDE on saving, but it could work with a lint-stage solution.

prettier --config ./.prettierrc.tailwind.js --write .
prettier --config ./.prettierrc.other.js --write .

It's not a pretty solution, but I think it's possible for those that strongly want multiple plugin support.

I, personally, have decided to use the tailwind prettier plugin on its own for now to avoid adding this much complexity to my projects.

Thanks for the idea, I made a lintstaged script to run eslint (with prettier tailwindcss) + prettier (with prettier sort imports), here is an example

guilhermetod commented 2 years ago

Also incompatible with prettier-plugin-organize-attributes

jlarmstrongiv commented 2 years ago

Any workarounds @guilhermetod ?

manavm1990 commented 2 years ago

I for one can say that I can install and integrate: @tailwindcss/forms and it has 0 affect on this Prettier plugin.

I don't particular care for the defaults put forth in the forms extension, so I don't usually use it. Just tried it out when I saw these issues.

As to all of the other plugins, I don't personally use all of those, but other ones such as standard prettier, or prettier for Jest I do use and never had any issue.

jcamato commented 2 years ago

@manavm1990 This issue is specifically in regards to those other plugins, not for the standard prettier plugin which this tailwind plugin was built for and can be used in tandem with forms πŸ‘

kagurazaka-0 commented 2 years ago

I found a new workaround to make @trivago/prettier-plugin-sort-imports and prettier-plugin-tailwindcss work at the same time in React+TypeScript(work in vscodeπŸŽ‰).

  1. if you do not have prettier.config.js, create a file and move your config to `prettier.config.js
  2. copy to prettier.config.js.
const pluginSortImports = require("@trivago/prettier-plugin-sort-imports")
const pluginTailwindcss = require("prettier-plugin-tailwindcss")

/** @type {import("prettier").Parser}  */
const myParser = {
  ...pluginSortImports.parsers.typescript,
  parse: pluginTailwindcss.parsers.typescript.parse,
}

/** @type {import("prettier").Plugin}  */
const myPlugin = {
  parsers: {
    typescript: myParser,
  },
}

module.exports = {
  plugins: [myPlugin],
  // your settings
}
  1. it will look like this
Sample Code ```tsx import { fuga } from "./hoge" import { Alert } from "~/components/atoms/Alert" type Props = {} export function Component(props: Props) { return (
) } // after /* config = { plugins: [hackedPlugin], tabWidth: 2, semi: false, printWidth: 120, arrowParens: "always", importOrder: ["^[~/]", "^[../]", "^[./]"], importOrderSeparation: true, } */ import { Alert } from "~/components/atoms/Alert" import { fuga } from "./hoge" type Props = {} export function Component(props: Props) { return (
) } ```

References.

Underlying problem ## Underlying problem After some investigation, I suspect that there is a problem with prettier core `getParsers()`. https://github.com/prettier/prettier/blob/cd9955f1431ca3814ea9b713aa7275ceefa980d9/src/main/parser.js#L15-L25 For example ```js // prettier.config.js const APlugin = { parsers: { typescript: ... , }, } const BPlugin = { parsers: { typescript: ... , }, } module.exports = { plugins: [APlugin, BPlugin], // ... } ``` APlugin does not work when formatted with a ts file, and only BPlugin works. I assume this is because the `parsers` in `getParsers()` are overwritten for each plugin. I am currently investigating.
nirtamir2 commented 2 years ago

https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/31#issuecomment-1195411734 @kagurazaka-0 Thank you! I try it and it works well! Now I wait until I would be able to remove this workaround.

linkb15 commented 2 years ago

I don't know if it is also related to this, but I can't have prettier-plugin-tailwindcss working alongside @tailwindcss/forms. It says it doesn't find it.

I found a workaround on this one

Create a tailwind.shared.config.js contains all the things without @tailwindcss/forms

/** @type {import("tailwindcss").Config}  */
module.exports = {
  darkMode: 'class',
  content: [
    './src/pages/**/*.{js,ts,jsx,tsx}',
    './src/components/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {},
}

Then in normal tailwind.config.js add the plugins back.

const config = require('./tailwind.shared.config.js')

/** @type {import("tailwindcss").Config}  */
module.exports = {
  ...config,
  plugins: [
    require('@tailwindcss/forms'),
  ],
}

in .prettierrc.js use the config file without @tailwindcss/forms

module.exports = {
  // other configs
  tailwindConfig: './tailwind.shared.config.js',
}
rbluethl commented 2 years ago

@kagurazaka-0 This works like a charm, thanks a lot! ✌️πŸ₯°

tusamni commented 2 years ago

Seems this one might be incompatible as well https://github.com/withastro/prettier-plugin-astro

Agreed, having this issue as well.

mikesnoeren commented 2 years ago

Are all these incompatibilities meant to be fixed at some point, or is this issues point to inform us that we can't use a combination of said plugins without odd workarounds?

igitur commented 2 years ago

Are all these incompatibilities meant to be fixed at some point, or is this issues point to inform us that we can't use a combination of said plugins without odd workarounds?

I think the premise of your question is a bit misplaced. My experience with open-source software, unless funded by big sponsors, is that contributors submit patches mostly to solve their own problems. So either you have to get your hands dirty and submit a PR to solve this, or cross your fingers and hope that someone else has enough motivation to sacrifice their free time one day and do the work for you.

hamatoyogi commented 2 years ago

Seems this one might be incompatible as well https://github.com/withastro/prettier-plugin-astro

Agreed, having this issue as well.

same.

scott-lc commented 2 years ago

For those that are using eslint (with autofix) in conjunction with prettier, eslint-plugin-tailwindcss might be a viable alternative.

tobiasriemenschneider commented 2 years ago

Seems this one might be incompatible as well https://github.com/withastro/prettier-plugin-astro

Agreed, having this issue as well.

same.

same.

raszi commented 2 years ago

It seems to be incompatible with https://github.com/ggascoigne/prettier-plugin-import-sort

blueambr commented 2 years ago

Would be very nice, if we had support for this one: https://github.com/prettier/plugin-pug The markup used in pug can look like this: h1(class="text-center font-serif"), which is in terms of classes is the same as HTML. If anyone has a possible solution, I'd be very grateful. Thanks!

raszi commented 2 years ago

It seems to be incompatible with https://github.com/trivago/prettier-plugin-sort-imports

cmalard commented 2 years ago

Reading the discussion here, according to Prettier's team, re-ordering classes should not be done through Prettier but through ESLint, which is why they do not plan to solve it πŸ˜… Should the effort be redirected to an ESLint plugin? (official support for the existing ones?)

mattcroat commented 2 years ago

I'm using SvelteKit and used the instructions but it doesn't work.

Reproduction:

Settings:

"[svelte]": {
  "editor.defaultFormatter": "svelte.svelte-vscode"
}

Thank you! πŸ™

mattcroat commented 2 years ago

I figured out what I was doing wrong and the reason I couldn't get it to work for SvelteKit before was because I was trying to include the plugin inside .prettierrc which for some reason breaks it, so don't include it and it should pick it up.

πŸ‘ŽοΈ .prettierrc

{
  "plugins": ["prettier-plugin-tailwindcss"]
}

Here are the steps for SvelteKit users:

  1. pnpm i -D prettier-plugin-tailwindcss
  2. pnpm remove prettier-plugin-svelte

You can keep using the svelte.svelte-vscode formatter.

"[svelte]": {
  "editor.defaultFormatter": "svelte.svelte-vscode"
}

You can look at the updated repo if you need an example.

Princesseuh commented 2 years ago

Hello, Erika from the Astro team here. Any idea when the current main will be released?

We contributed Astro support 2 months ago now and our users understandably keep asking us to support this. I know there was some needed changes after our PR, but it seems like those changes were merged in a month ago.

If there's anything we can do to help get this released - please let us know and we'll gladly contribute!

adamwathan commented 2 years ago

@Princesseuh I think it's still blocked by what @thecrypticace outlined here: https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/87#issuecomment-1218432784

We're really busy trying to get Tailwind CSS v3.2 out the door this week and then out for a team retreat the following week, but we can look at this again the first week of November. One idea we might need to explore is multiple plugins, like a prettier-plugin-tailwindcss-astro plugin and a separate pretter-plugin-tailwindcss-svelte plugin or similar since it seems to be proving challenging to build something that works everywhere πŸ˜•

jerriclynsjohn commented 1 year ago

@mattcroat I really appreciate this, and I did try but IDE kept showing Saving '+page.svelte': Running 'Svelte for VS Code' Formatter toast message while I was trying to save. If I try to navigate to a different file the toast message disappears and saves the file.

The formatting was successful by the end of the wait and consequent save did not have this problem. Just throwing this here to see if others faced this issue. I faced this issue both with my personal repo and also the repo shared by @mattcroat

cc. @reinink

TrevorLeeman commented 1 year ago

@kagurazaka-0 Thanks for sharing. This looks like a promising solution, but I was personally not able to get it working. Continuously got this error in the Prettier output after making the change to the prettier.config.js:

Error formatting document. TypeError: Cannot read properties of undefined (reading 'map') at Object.getExperimentalParserPlugins

When only using plugins: [require('prettier-plugin-tailwindcss')] or plugins: [require('@trivago/prettier-plugin-sort-imports')], individually, Prettier works as expected.