withastro / compiler

The Astro compiler. Written in Go. Distributed as WASM.
Other
473 stars 60 forks source link

🐛 BUG: Comments parsing inside JSX #956

Open ArmandPhilippot opened 6 months ago

ArmandPhilippot commented 6 months ago

Describe the Bug

First of all, I am not sure if this issue belong to the language-tools, the compiler or the astro repository. So sorry if I picked the wrong repo.

System info

Astro                    v4.2.6
Node                     v18.17.1
System                   Linux (x64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             none

I have the same issue using Node v21.5.0.

The issue

I can write comments inside JSX like this:

{/* This comment is working */}
<Card
  href="https://docs.astro.build/"
  title="Documentation"
  body="Learn how Astro works and explore the official API docs."
/>

However, if I want to use a comment between the props, it does not work:

<Card
  href="https://astro.build/integrations/"
  {/* This one does not work */}
  title="Integrations"
  body="Supercharge your project with new frameworks and libraries."
/>

On the same line, it does not work neither:

<Card
  href="https://astro.build/integrations/"
  title="Integrations" {/* This one does not work neither */}
  body="Supercharge your project with new frameworks and libraries."
/>

With these examples, I got Unterminated string literal. ts(1002).

If I try to put a comment in a ternary like this:

{
  showThemes ? (
    <Card
      href="https://astro.build/themes/"
      title="Themes"
      // This one does not work neither.
      body="Explore a galaxy of community-built starter themes."
    />
  ) : null
}

Then I see:

Type '{ href: string; title: string; This: true; is: true; a: true; comment: true; body: string; }' is not assignable to type 'IntrinsicAttributes & Props'.
  Property 'This' does not exist on type 'IntrinsicAttributes & Props'.ts(2322)

The same error happens if I use the following format: /* This is a comment */.

In another project using ESlint, it is not Typescript who is complaining but ESlint:

Parsing error: Unknown token at 782, expected: "*", actual: "/* eslint-"eslint

And Prettier does not work neither, it complains with SyntaxError: Unexpected token.

My expectations

I expect to be able to use comments this way since this pattern is commonly used to disable a linter like ESlint:

{ data ? (
    <Card
        href="https://astro.build/chat/"
        title="Community"
        body="Come say hi to our amazing Discord community. ❤️"
        /* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition  */
        slot={data ? 'data' : undefined}
    />
    ) : null
}

Steps to Reproduce

I created a project in Stackblitz ( https://stackblitz.com/edit/astro-comments-parsing-bug?file=src%2Fpages%2Findex.astro ) but the parser does not work (I have a warning in the console No parser for file type: astro) so you can download it and open the project in VS Code or you can follow the instructions below.

  1. npm create astro@latest -- --template basics
  2. Choose a path to install then answer Yes for all (and keep Strict for Typescript)
  3. Open VS Code, and install Astro VS Code Extension if needed.
  4. Update the content of ./src/pages/index.astro with:
---
import Layout from "../layouts/Layout.astro";
import Card from "../components/Card.astro";
---

<Layout title="Welcome to Astro.">
  <main>
    <Card
      href="https://astro.build/integrations/"
      {/* This comment does not work */}
      title="Integrations"
      body="Supercharge your project with new frameworks and libraries."
    />
  </main>
</Layout>

<style>
  main {
    margin: auto;
    padding: 1rem;
    width: 800px;
    max-width: calc(100% - 2rem);
    color: white;
    font-size: 20px;
    line-height: 1.6;
  }
</style>
  1. Then we got parsing errors.
Princesseuh commented 5 months ago

Not 100% sure about the Prettier part, but this is a compiler issue!

natemoo-re commented 5 months ago

Confirmed as a compiler issue! We have some logic to handle these cases, but it looks like it's not being applied 100% of the time. We'll take a look at this when we have some bandwidth to.

Thanks for opening an issue!

ArmandPhilippot commented 5 months ago

If it helps anyone, for my use case I found a workaround:

{ data ? (
    <Card
        href="https://astro.build/chat/"
        title="Community"
        body="Come say hi to our amazing Discord community. ❤️"
        slot={
             /* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition  */
            data ? 'data' : undefined
        }
    />
    ) : null
}

I have not tested, but I guess the following should also work:

<Card
    href="https://astro.build/integrations/"
    title={
        /* This comment should work */
        `Integrations`
    }
    body="Supercharge your project with new frameworks and libraries."
/>

It is not ideal... but in the meantime, it's not so bad.