sveltejs / prettier-plugin-svelte

Format your svelte components using prettier.
MIT License
740 stars 97 forks source link

Error when parsing dynamic attributes expressions #110

Closed eriandev closed 4 years ago

eriandev commented 4 years ago

I have the following code:

<script>
    import Typewritter from './Typewritter.svelte'
    const texts = ['text1', 'text2']
</script>

<div class="parallax-cover">
    <h1>Random Title</h1>
    <Typewritter {texts} />     <!-- This will be formatted -->
</div>

I use the npm run format command and the result is:

<script>
    import Typewritter from './Typewritter.svelte'
    const texts = ['text1', 'text2']
</script>

<div class="parallax-cover">
    <h1>Random Title</h1>
    <Typewritter texts="texts" />   <!-- The expected result was texts="{texts}" -->
</div>

This changes the expected result, because you are assigning the text string "texts", not the variable texts.

Additional information

"scripts": {
        "start": "sirv public",
        "autobuild": "rollup -c -w",
        "dev": "run-p watch:tailwind autobuild",
        "build": "npm run build:tailwind && rollup -c",
        "format": "prettier --write \"{,!(public)/**/}*.{js,json,svelte}\"",
        "watch:tailwind": "postcss src/tailwind.css -o public/global.css -w",
        "build:tailwind": "cross-env NODE_ENV=production postcss src/tailwind.css -o public/global.css"
    },
"dependencies": {
        "sirv-cli": "^1.0.3"
    },
    "devDependencies": {
        "@fullhuman/postcss-purgecss": "^2.3.0",
        "@rollup/plugin-commonjs": "^14.0.0",
        "@rollup/plugin-node-resolve": "^8.4.0",
        "cross-env": "^7.0.2",
        "cssnano": "^4.1.10",
        "npm-run-all": "^4.1.5",
        "postcss-cli": "^7.1.1",
        "prettier": "^2.0.5",
        "prettier-plugin-svelte": "^1.1.0",
        "rollup": "^2.21.0",
        "rollup-plugin-livereload": "^1.3.0",
        "rollup-plugin-svelte": "^5.2.3",
        "rollup-plugin-terser": "^6.1.0",
        "svelte": "^3.24.0",
        "svelte-preprocess": "^4.0.8",
        "tailwindcss": "^1.5.1"
    }
ehrencrona commented 4 years ago

I could not reproduce this behavior. When I try formatting the above code, {texts} is preserved (prettier-plugin-svelte@1.1.0 and prettier@2.0.5).

eriandev commented 4 years ago

Maybe something in my .prettierrc file?

{
    "tabWidth": 4,
    "useTabs": false,
    "semi": false,
    "singleQuote": true,
    "trailingComma": "es5",
    "plugins": ["prettier-plugin-svelte"],
    "svelteSortOrder" : "scripts-markup-styles",
    "svelteStrictMode": true,
    "svelteBracketNewLine": false,
    "svelteAllowShorthand": false
}

issue prettier-svelte-plugin

jesseskinner commented 4 years ago

This took me a while to figure out, but turns out it's due to the option you have in .prettierrc:

{
    "svelteAllowShorthand": false
}

I think you have discovered a bug, as I would expect prettier-plugin-svelte to rewrite the code to avoid using the shorthand when that setting is set to false, rather than turning it into a string attribute:

<script>
    import Typewritter from './Typewritter.svelte'
    const texts = ['text1', 'text2']
</script>

<div class="parallax-cover">
    <h1>Random Title</h1>
    <Typewritter texts="{texts}" />     <!-- I would expect this output -->
</div>

So I think it's just missing the curly braces inside the quotes. But in the meantime, you could set svelteAllowShorthand to true to fix your issue.

jesseskinner commented 4 years ago

I've added a pull request which fixes this issue, #119.

autoferrit commented 4 years ago

I just updated, and restarted vscode to use this new version, and I am still having this issue. With this file:

<script>
  import List from '../../components/Articles/List.svelte';

  export let articles;
</script>

<svelte:head>
  <title>Articles</title>
</svelte:head>

<h1>Recent articles</h1>

<List {articles} />

The last component, gets formatted as this

<List articles="{articles}" />

.prettierrc.json, I also tried putting the rules in the overrides, but didn't change it.

{
  "plugins": ["prettier-plugin-svelte"],
  "printWidth": 88,
  "semi": true,
  "singleQuote": true,
  "svelteAllowShorthand": true,
  "svelteBracketNewLine": true,
  "svelteSortOrder": "scripts-markup-styles",
  "svelteStrictMode": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false,
  "overrides": [
    {
      "files": "*.svelte",
      "options": {
        "parser": "svelte",
        "svelteBracketNewLine": true,
        "svelteAllowShorthand": true,
        "singleQuote": true
      }
    }
  ]
}

package.json (relevant parts)

{
  "dependencies": {
    "@fullhuman/postcss-purgecss": "^2.3.0",
    "compression": "^1.7.4",
    "helmet": "^4.1.0",
    "sirv": "^1.0.6"
  },
  "devDependencies": {
    "@babel/core": "^7.11.4",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/plugin-transform-runtime": "^7.11.0",
    "@babel/preset-env": "^7.11.0",
    "@babel/runtime": "^7.11.2",
    "@rollup/plugin-babel": "^5.2.0",
    "@rollup/plugin-commonjs": "^15.0.0",
    "@rollup/plugin-json": "^4.1.0",
    "@rollup/plugin-node-resolve": "^9.0.0",
    "@rollup/plugin-replace": "^2.3.3",
    "@tailwindcss/ui": "^0.5.0",
    "@types/compression": "^1.7.0",
    "@types/express": "^4.17.7",
    "@types/marked": "^1.1.0",
    "class-validator": "^0.12.2",
    "cssnano": "^4.1.10",
    "cypress": "^5.0.0",
    "eslint": "^7.7.0",
    "eslint-config-airbnb-base": "^14.2.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-cypress": "^2.11.1",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-svelte3": "^2.7.3",
    "express": "^4.17.1",
    "gray-matter": "^4.0.2",
    "highlight.js": "^10.1.2",
    "husky": "^4.2.5",
    "lint-staged": "^10.2.13",
    "marked": "^1.1.1",
    "npm-run-all": "^4.1.5",
    "postcss-cli": "^7.1.1",
    "postcss-import": "^12.0.1",
    "postcss-load-config": "^2.1.0",
    "postcss-preset-env": "^6.7.0",
    "prettier": "^2.1.1",
    "prettier-plugin-svelte": "^1.2.0",
    "rollup": "^2.26.8",
    "rollup-plugin-svelte": "^6.0.0",
    "rollup-plugin-terser": "^7.0.1",
    "sapper": "^0.28.3",
    "svelte": "^3.24.1",
    "svelte-check": "^1.0.31",
    "svelte-fa": "^2.1.1",
    "svelte-preprocess": "^4.2.0"
  },
}

Perhaps there is some wrong configuration? or I have a conflicting package? Here are my workspace settings:

{
  "settings": {
    "[svelte]": {
      "editor.defaultFormatter": "svelte.svelte-vscode",
      "editor.tabSize": 2
    },
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true,
    "eslint.enable": true,
    "eslint.validate": ["javascript", "svelte"],
    "prettier.quoteProps": "consistent",
    "prettier.singleQuote": true
  }
}
jesseskinner commented 4 years ago

@autoferrit this is correct, isn't it? svelteStrictMode: true enforces an HTML-compatible syntax.

dummdidumm commented 4 years ago

I also so nothing wrong with the output. svelteStrictMode: true -> add the ". You pasted the output as <List articles="{articles}" /> which is correct. Before this fix it was <List articles="articles" />.

autoferrit commented 4 years ago

Ah. So then it is having svelteStrictMode: true that enforces expanding those to not be shorthand. If I change that to false, what are the effects other than what the Readme mentions of self-closed tags, quotes in attributes?

dummdidumm commented 4 years ago

I updated the docs a little. Yes, it overrules allowShortHand.