IanVS / prettier-plugin-sort-imports

An opinionated but flexible prettier plugin to sort import statements
Apache License 2.0
951 stars 21 forks source link

[V4] Dollar sign ($) in Vue SFC script setup throws `SyntaxError` #100

Closed istiak-tridip closed 1 year ago

istiak-tridip commented 1 year ago

Your Environment

Describe the bug

Using a dollar sign $ inside the vue SFC script setup throws an exception and doesn't format the file.

To Reproduce

Try to format a Vue SFC file with a single quoted $ inside <script lang="ts" setup>

Screenshots, code sample, etc

ExampleOne.vue

<script lang="ts" setup>
const dollarSign = '$';
</script>

<template>
  <div>
    {{ dollarSign }}
  </div>
</template>

Configuration File (cat .prettierrc, prettier.config.js, .prettier.js)

module.exports = {
    singleQuote: true,
    pluginSearchDirs: false,
    plugins: ["@ianvs/prettier-plugin-sort-imports"],
};

Error log

❯ npx prettier --write *.vue
ExampleOne.vue
[error] ExampleOne.vue: SyntaxError: Unexpected closing tag "script". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (12:1)
[error]   10 | ;
[error]   11 |
[error] > 12 | </script>
[error]      | ^^^^^^^^^
[error]   13 |
[error]   14 | <template>
[error]   15 |   <div>
IanVS commented 1 year ago

Whoa what a strange bug! Thanks for reporting and providing a minimal example. I'll try to figure out what's going on. Do you know if @vue/compiler-sfc treats dollar signs in some special way? Oh, and what version of @vue/compiler-sfc do you have installed?

istiak-tridip commented 1 year ago

I'm using "@vue/compiler-sfc": "^3.3.4". While exploring this I found another issue that I think is related to this. $ sign is being remove from template literals even if escaped (this const foo = `\$${value}` turns into this const foo = `\${value}`)

Unformatted Code:

<script lang="ts" setup>
const value = 500;
const prefixedValue = `\$${value}`;
</script>

<template>
  <div>
    {{ prefixedValue }}
  </div>
</template>

Formatted Code:

<script lang="ts" setup>
const value = 500;
const prefixedValue = `\${value}`;
</script>

<template>
  <div>
    {{ prefixedValue }}
  </div>
</template>
IanVS commented 1 year ago

I don't have time to dig in too deep just now, but I did find https://github.com/vuejs/core/commit/88a4504e8215392e277f07db41ab9f46fc68b4d3 that looks slightly suspicious, but iiuc that should only apply to imports in scripts. I wonder if they have some other regex adjustments for $ that are causing this issue, though.

I assume you don't have any issue with this in your actual vue project. Maybe you could try reproducing with parse from @vue/compiler-sfc directly? This is where we use it, I don't think we're doing anything crazy with it... https://github.com/IanVS/prettier-plugin-sort-imports/blob/8a4b651e23c5a0e721384b21bf8ba510e3200dfd/src/preprocessors/vue.ts#L11-L12

istiak-tridip commented 1 year ago

Hey @IanVS, I found the cause and created a pull request. See #101.

IanVS commented 1 year ago

Thanks, the fix has been released in 4.0.1. 🙌