sveltejs / language-tools

The Svelte Language Server, and official extensions which use it
MIT License
1.25k stars 199 forks source link

Tailwind style modifiers like hover: and md: throw errors when no error present #1574

Closed rogadev closed 2 years ago

rogadev commented 2 years ago

Describe the bug

When I try to do the following:

<style lang="postcss">
  .nav-item {
    @apply px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 text-2xl md:text-xl font-semibold;
  }
</style>

My IDE throws an error at the first occurrence of : in the string. image

It seems that Svelte thinks this is a "css-syntax-error", however the lang property on my style block is clearly set to "postcss". Furthermore, Tailwind is correctly handling and applying these styles. You can even see that the Tailwind CSS extension is picking up that this is a hover modifier and displays the correct tooltip accordingly. image

Reproduction

  1. Follow this Tailwind CSS guide to set up a Svelte project and configure Tailwind CSS.
  2. Create the following component and put it in your main view.

    
    <header class="block md:flex md:justify-between md:items-center">
    <a
    id="brand-link"
    href="/"
    class="flex items-center justify-between md:justify-start"
    >
    <img
      id="brand-logo"
      src="/img/viu_logo.svg"
      alt="VIU Logo"
      class="h-[70px]"
    />
    <h1
      id="brand-title"
      class="font-extrabold text-3xl text-center mx-auto md:text-left md:ml-4"
    >
      Career Outlook Tool
    </h1>
    </a>
    
    <nav aria-label="Main" class="text-xl md:text-2xl">
    <ul
      class="flex gap-4 items-center mr-4 justify-evenly md:justify-start mt-4 md:mt-0 text-center"
    >
      <!-- <li class="nav-item"><a href="/outlook/2175">X</a></li> -->
      <li class="nav-item"><a href="/careers/search">Search Credentials</a></li>
      <li class="nav-item">
        <a href="/careers/by-program">Search Program</a>
      </li>
    </ul>
    </nav>
    </header>

Your IDE should yell at you.

### Expected behaviour

No error message on the modifiers that use a `:` colon after the TailwindCSS `@apply` directive.

### System Info

- OS:
  - Edition Windows 10 Education
  - Version 21H2
  - Installed on    ā€Ž2020-ā€Ž08-ā€Ž27
  - OS build    19044.1826
  - Experience  Windows Feature Experience Pack 120.2212.4180.0
- IDE: 
  - Version: 1.69.2 (user setup)
  - Commit: 3b889b090b5ad5793f524b5d1d39fda662b96a2a
  - Date: 2022-07-18T16:12:52.460Z
  - Electron: 18.3.5
  - Chromium: 100.0.4896.160
  - Node.js: 16.13.2
  - V8: 10.0.139.17-electron.0
  - OS: Windows_NT x64 10.0.19044
- Extension:
  - Tailwind CSS IntelliSense v0.8.6

### Which package is the issue about?

Svelte for VS Code extension

### Additional Information, eg. Screenshots

I am making an educated guess that Svelte for VS Code is the source of the error message. Disabling, the error disappears. Enabling, it returns.

Most importantly, the steps in the error message do not solve the issue. I went so far as to follow the steps to install and configure Stylelint, to no avail.
rogadev commented 2 years ago

Just to show that styles are, in fact, being applied:

image image

image image

jasonlyu123 commented 2 years ago

Can you provide a reproduction in a repository form? Not sure what you tried but I didn't see the error following the guide of tailwindcss. Do you use svelte-kit, vite template or rollup template?

As for stylelint, We have two sources for CSS diagnostic. One is from the svelte compiler and the other is vscode-css-languageservice. Stylelint can help to replace the latter. But your problem is with the former.

rogadev commented 2 years ago

I use Vite. I've made the repo public, you can find it here. You can find the component in question in src/lib/components/Navbar.svelte.

I agree, I believe the problem is with the former as well. I really hope I'm just missing some silly config setting. Surely other people use these modifiers in the same way... It's more than a little suspicious that (it seems) no one else online has have run into this problem. šŸ¤·ā€ā™‚ļø Please let me know if you find anything. I greatly appreciate your time.

jasonlyu123 commented 2 years ago

Looks like it's https://github.com/sveltejs/language-tools/issues/1394. You probably open the editor in the repo root where the process.cwd is not the same as your build. So postcss and tailwind can't find the config file. We can probably add the solution for that issue to the tailwind CSS troubleshooting docs.

rogadev commented 2 years ago

I updated postcss.config.cjs as shown in #1394 but the same problem occurs.

// postcss.config.cjs
const autoprefixer = require('autoprefixer')
const path = require('path')
const tailwindcss = require('tailwindcss')

module.exports = {
  plugins: [
    tailwindcss(path.resolve(__dirname, './tailwind.config.cjs')),
    autoprefixer,
  ],
}

image

rogadev commented 2 years ago

Okay well this is interesting...

When you create a Svelte project it wants you to put it in a folder. So I did that (svelte/). Then built my project from there.

I just now pulled it out of the svelte folder to live in the root of my repo. Like magic, the error message has gone. I tried this because you mentioned "You probably open the editor in the repo root where the process.cwd is not the same as your build." Can you explain a bit more about that?

rogadev commented 2 years ago

Here's a short video that explains why I feel this is an issue, not just a documentation problem: https://youtu.be/8ZXwklVjKzg

TL:DNR - What if I wanted several svelte kit projects inside the same repo? None of them could use Tailwind CSS this way without getting errors that aren't really errors? Is this a Svelte problem or a Tailwind problem?

jasonlyu123 commented 2 years ago

The original author of that issue said it would be fine to not pass posscss.config.cjs path to svelte-preprocess. But that doesn't work for me. I only manage to make it work when the config path is passed into the svelte-preprocess as an option. If you set it properly it should also work in monorepo.

import preprocess from 'svelte-preprocess';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url'

const __dirname = dirname(fileURLToPath(import.meta.url));

const config = {
    // Consult https://github.com/sveltejs/svelte-preprocess
    // for more information about preprocessors
    preprocess: preprocess({
        postcss: {
            configFilePath: join(__dirname, 'postcss.config.cjs')
        }
    }),

        // ... your other options
};

export default config;

I tried this because you mentioned "You probably open the editor in the repo root where the process.cwd is not the same as your build." Can you explain a bit more about that?

When VSCode is opened with a directory the process for it and its child process default to set its working directory to that directory. This means all the relative path is resolved from that path. Tailwind and postcss assume that it'll always be opened in a process where the config file is in the root of the process working directory. But it's not the case for us to run the preprocess. So they can't find the config file.

We could maybe change the cwd with process.chdir But since the preprocess is asynchrony I really don't know if it would cause any problem. So I would say maybe it's better to document it or even ask if postcss load config and tailwind plugin if they could factor that in.