8

Colocating code (graphql/css/js/html) in files is great.

I use the TailwindCSS library to style my components, and the classnames package to insert classes dynamically.

I also use Prettier to format my code. The problem is that it will format my classes rules with one class per line, which quickly bloats my files.

Wanted:

const container = cn("flex", "flex-col", "min-h-lg", "mb-12", "transition-opacity", "duration-500", "ease-in-out");
const buttons = cn(
  "inline-grid", "row-gap-5", "col-gap-10", "grid-rows-5", "grid-flow-col",
  "sm:grid", "sm:grid-cols-3",
);
const character = cn(
  "hidden", "row-span-5", "h-48", "place-self-end", "origin-center",
  "animation-once", "animation-ease-out", "animation-0.8s", "animation-fill-forwards",
  "sm:block", "sm:animation-lightspeedin",
);

What I get with prettier:

const container = cn(
  "flex",
  "flex-col",
  "min-h-lg",
  "mb-12",
  "transition-opacity",
  "duration-500",
  "ease-in-out"
);
const buttons = cn(
  "inline-grid",
  "row-gap-5",
  "col-gap-10",
  "grid-rows-5",
  "grid-flow-col",
  "sm:grid",
  "sm:grid-cols-3"
);
const character = cn(
  "hidden",
  "row-span-5",
  "h-48",
  "place-self-end",
  "origin-center",
  "animation-once",
  "animation-ease-out",
  "animation-0.8s",
  "animation-fill-forwards",
  "sm:block",
  "sm:animation-lightspeedin"
);

As you can see, it quickly gets out of control. I'm wondering what other peoples with a similar stack are doing to keep their files readable. I'm always striving for files with less than 100 lines, but this is not possible anymore with prettier+tailwindcss. I'd have gone with prettier-ignore-{start,end} if that was supported on js/jsx/ts/tsx files. Do you ignore every rule?

// prettier-ignore
const container = cn("flex", "flex-col", "min-h-lg", "mb-12", "transition-opacity", "duration-500", "ease-in-out");
// prettier-ignore
const buttons = cn(
  "inline-grid", "row-gap-5", "col-gap-10", "grid-rows-5", "grid-flow-col",
  "sm:grid", "sm:grid-cols-3",
);
// prettier-ignore
const character = cn(
  "hidden", "row-span-5", "h-48", "place-self-end", "origin-center",
  "animation-once", "animation-ease-out", "animation-0.8s", "animation-fill-forwards",
  "sm:block", "sm:animation-lightspeedin",
);

Or do you move all classes to the bottom of the file to make it less visible / reduce the need to scroll to get to the component? I suppose I'll do both, and will move them back to the top of the file when prettier-ignore-{start,end} is made available.

Adrien Lemaire
  • 1,744
  • 2
  • 20
  • 29
  • I'm pretty sure it is not prettier rule, its eslint. – Dennis Vash May 18 '20 at 06:46
  • 1
    Using multiple lines for this is the imo the best way. It's clear and easy to read from top to bottom. When adding or removing a class you can see exactly which class it is in Git instead that Git says that the whole line is replaced. – oscarteg Aug 06 '20 at 09:07
  • I really WANT the one class per line using @apply rules in TailwindCSS, and I cant figure out how to do it. – theUtherSide May 06 '21 at 00:23

1 Answers1

1

I don't think that is something you can change about Prettier. It's pretty opinionated, and for good reason. The less you can tweak the cleaner and more standardised it can keep your code (most of the time). I think there are forks of Prettier that allow more customisation, but honestly I have a simpler solution for you. Add your classes like this:

const container = cn("flex flex-col min-h-lg mb-12 transition-opacity");

const buttons = cn(
  "inline-grid row-gap-5 col-gap-10 grid-rows-5 grid-flow-col",
  "sm:grid sm:grid-cols-3",
);

const character = cn(
  "hidden row-span-5 h-48 place-self-end origin-center",
  "animation-once animation-ease-out animation-0.8s animation-fill-forwards",
  "sm:block sm:animation-lightspeedin",
);
Geoff Davids
  • 887
  • 12
  • 15
  • this raises the error "[tsserver 2345] [E] Argument of type '...' is not assignable to parameter of type 'TArg'. – Adrien Lemaire Nov 29 '21 at 06:44
  • Ah - looks like there's some type-checking on the classes strings you add. It's possible you could tweak the typing to do partial string matching with TypeScript 4's new features. I have been using clsx rather than classnames, and I haven't run into this problem so far. – Geoff Davids Nov 29 '21 at 14:49