tailwindlabs / tailwindcss-jit

MIT License
2.19k stars 40 forks source link

Javascript template literals with inline brackets are not interpolated and break the JIT compiler forcing a manual kill/restart #154

Closed sklawren closed 3 years ago

sklawren commented 3 years ago

What version of @tailwindcss/jit are you using?

0.1.8

What version of Node.js are you using?

12.18.4

What browser are you using?

Chrome

What operating system are you using?

macOS

Reproduction repository

https://www.youtube.com/watch?v=3O_3X7InOw8

As reported on Discord in the help channel

I'm using React, but I assume this could happen anywhere you're doing this.

When the JIT encounters an open bracket, it does not interpolate what's inside and instead reads it literally.

This works:

const minW = {
    sm: '[7rem]',
    md: '[8.25rem]',
};

<div className={`min-w-${minW[size]}`}/>

However, this breaks the compiler since when it encounters the open bracket, it reads it literally and creates invalid css:

const minW = {
    sm: '7rem',
    md: '8.25rem',
};

<div className={`min-w-[${minW[size]}]`}/>

Error
 1623 | .min-w-\[\$\{minW\[size\]\}\] {
 1624 |     min-width: ${minW[size]};
      |                  ^
 1625 | }

Even though the JIT is still running after this and you can update and save your file, it's actually stuck in this error state and continues to output the above error even after the code has changed to fix the issue. You have to kill/restart the process for it to read the updated code and rewrite the css.

I'm not sure whether this is fixable or it should be documented as something to look out for.

fedeci commented 3 years ago

Hi @sklawren, keep in mind that the approach you are using is wrong, however this is definitely a bug that should be investigated.

sklawren commented 3 years ago

Gotcha! Thanks for pointing that out.

sklawren commented 3 years ago

This gives me an idea. What if the JIT compiler could detect concatenation like this and post an error/warning into the console to let the developer know they're doing it wrong (and a link to the documentation)?

šŸ’” šŸ¤©

homoky commented 3 years ago

Yeah I understand that it is not the 100 % correct but we (and I guess many more) have use cases, that for example in production we have a module (imagine some site) and anyone can change a color of some element, and this approach with brackets would help us to get rid of style={{}} in our React components that are used only for this kind of customization that is not possible to predict in build time.

const Test = ({ color }: { color: string }) => <div className={`bg-[${color}]`}>Hello Tailwind guys!</div>;
TrisMcC commented 3 years ago

@homoky In that case you could either map the color inputs to a tailwind class name { blue: 'bg-blue' } or pass in the class name instead of a color.

adamwathan commented 3 years ago

Hey! Yeah this is intended behavior, it would be nice if we could throw better errors when truly illogical stuff ends up the stylesheet though.

Right now we support literally any string within square brackets for stuff like min-width, and we just kind of trust that the input you give us is the CSS you want output, with no external judgment applied.

If you want min-w-[potatosandwich], we will generate min-width: potatosandwich ā€” you want, you got it boss!

But yeah as mentioned earlier in the thread the CSS is all generated statically, and can't depend on run-time data, so things like interpolating strings will not work.

We're going to explore some ideas around the error handling at least though ā€” we can probably do a better job of detecting stuff that is garbage input from our perspective, or at least showing lint warning with our VS Code IntelliSense extension.

Going to close as no real bug here per se but feedback definitely noted and will look for ways to prevent others from getting caught by this šŸ‘šŸ»