prettier-plugin-svelte: "Crash" when used with prettier and eslint

Please see https://github.com/sveltejs/svelte/issues/3550 for details, though is closed there. I copied the original bug report here, thanks

Describe the bug With this template where we want ESLint to co exist with prettier I have 2 problems when the plugins are nebale with this config

As described in the prettier docs this enable ESLint to call prettier

  1. Lint crashes in the svlte compile - see stack trace
  2. Prettier fails to format on save the App.svelte file - and error flashes up in the status bar

Logs see stack trace

To Reproduce Uncommented the line aboveand comment the one above it

  1. Run npm run lint from the command line
  2. edit the App.svelte and save the file

Expected behavior

  1. no error and llinter succeeds
  2. File is reformated via prettier

Stacktraces

Stack trace

$ npm run lint

svelte-project@1.0.0 lint C:\projects\svelte-code-cypress-project eslint src/*

ParseError: Expected } 1 | export let name 2 |

3 | {name;name=0} | ^ Occurred while linting C:\projects\svelte-code-cypress-project\src\App.svelte:3 at error$1 (C:\projects\svelte-code-cypress-project\node_modules\svelte\compiler.js:13329:20) at Parser$2.error (C:\projects\svelte-code-cypress-project\node_modules\svelte\compiler.js:13405:10) at Parser$2.eat (C:\projects\svelte-code-cypress-project\node_modules\svelte\compiler.js:13419:19) at mustache (C:\projects\svelte-code-cypress-project\node_modules\svelte\compiler.js:13220:17) at new Parser$2 (C:\projects\svelte-code-cypress-project\node_modules\svelte\compiler.js:13364:22) at Object.parse$1 [as parse] (C:\projects\svelte-code-cypress-project\node_modules\svelte\compiler.js:13495:21) at Object.parse (C:\projects\svelte-code-cypress-project\node_modules\prettier-plugin-svelte\plugin.js:669:51) at Object.parse$2 [as parse] (C:\projects\svelte-code-cypress-project\node_modules\prettier\index.js:10629:19) at coreFormat (C:\projects\svelte-code-cypress-project\node_modules\prettier\index.js:13888:23) at format (C:\projects\svelte-code-cypress-project\node_modules\prettier\index.js:14146:73) npm ERR! code ELIFECYCLE npm ERR! errno 2 npm ERR! svelte-project@1.0.0 lint: eslint src/* npm ERR! Exit status 2 npm ERR! npm ERR! Failed at the svelte-project@1.0.0 lint script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\steve\AppData\Roaming\npm-cache_logs\2019-09-11T17_00_42_583Z-debug.log

Information about your Svelte project:

  • Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, IE 10) Not relevant - build error

  • Your operating system: (e.x. OS X 10, Ubuntu Linux 19.10, Windows XP, etc) Windows 10 latest 1903

  • Svelte version (Please check you can reproduce the issue with the latest release!) 3.12.1

  • Whether your project uses Webpack or Rollup Roll up

Severity How severe an issue is this bug to you? Is this annoying, blocking some users, blocking an upgrade or blocking your usage of Svelte entirely?

Serious - can’t lint or run prettier on svelte files

Additional context Add any other context about the problem here.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 15
  • Comments: 17 (6 by maintainers)

Commits related to this issue

Most upvoted comments

I think that I’m facing the same issue. I’m linting with eslint taking advantage of the prettier/recommended rules set. After adding eslint-plugin-svelte3 everything was still working as it should. As soon as I added prettier-plugin-svelte it stopped. This snippet:

<script>
  export let name
</script>

… is causing eslint to fail with:

npx eslint --fix ./src/**/*.{js,svelte}
Expected }
  1 | export let name
  2 | 
> 3 | {name;name=0}
    |     ^
Occurred while linting /home/boojum/code/playground/parcel-svelte/src/containers/App/App.svelte:3

Repo with the minimal setup required to reproduce is here. To reproduce, simply run npx eslint --fix ./src/**/*.{js,svelte} - it will fail with the above error. Then uninstal prettier-plugin-svelte and run eslint again - no problems at all.

As stated in the newest Prettier docs, using packages like eslint-plugin-prettier is no longer recommended. Instead, use a preset configuration which turns off all Eslint rules which conflict with prettier and then just format first with prettier and run the linter afterwards.

EDIT: In the TypeScript roadmap they already mention separation of the Svelte core from tooling and taking inspiration from Vue, and UnwrittenFun seems involved in this. So focusing on eslint-plugin-prettier now might be missing the bigger picture.


Thought I’d share my findings so far. Perhaps someone knows more and/or would like to join the search for a solution! I haven’t worked with eslint plugins before, I’m just digging in node_modules trying to trace the plugin call order.

We have eslint calling eslint-plugin-svelte3 which has preprocess, postprocess functions (see Working with Plugins in ESLint’s developer guide). preprocess receives the whole file and calls svelte3/compiler to generate an AST, and returns a shorter string of pure JS extracted from the script part. This is then forwarded eslint-plugin-prettier -> prettier -> prettier-plugin-svelte where the latter is expecting a .svelte file and crashes.

The maintainers of eslint-plugin-svelte3 (which is the official plugin maintained by the Svelte team) have pointed at this plugin (prettier-plugin-svelte) and didn’t seem very interested in discussing another approach. But I believe it’s the eslint plugin that’s not behaving as expected in the big picture. I haven’t used Vue before but I looked into their solution for eslint/prettier because the .vue file structure looks very similar to Svelte’s: JSX and script + style + template. What Vue does, is that eslint first calls vue-eslint-parser (see ESLint’s Working with Custom Parsers), then eslint-plugin-vue: preprocess which simply returns the entire input, thus the whole .vue file is then sent to their Prettier plugin.

Next step is to determine how hard it would be to move the svelte3/compiler AST stuff to a separate parser library, and have the plugin be much simpler, just like eslint-plugin-vue which mostly contains lots of rule definitions and only 70 lines for the actual processors. The Vue parser & plugin seem to be written by eslint maintainers though, so in the worst case this approach requires support from the main eslint lib. Also I could only see vue-eslint-parser being called for files imported by the main .vue file, so it’s still unclear where the main file’s AST is built.

TL;DR: lots of intrigue simply because I don’t know how any of this works… 😆

As stated in the newest Prettier docs, using packages like eslint-plugin-prettier is no longer recommended…

@dummdidumm But only eslint plugins provide “realtime” linting inside the IDE, or not? In my workflow I’m gettung linting errors etc. highlighted while i’m typing. With the plugin I also get prettier “errors” highlighted while typing. It’s a thing of preference, but I prefer it this way instead of constantly getting my code reformatted on save e.g.

I’m getting this error, too. It would be really annoying to use Prettier separately because every single non-svelte project has Prettier integrated with ESLint. So Svelte projects are the only projects requiring me to setup extra tooling.

https://stackoverflow.com/questions/66804739/using-prettier-plugins-with-eslint-plugin-prettier?noredirect=1#comment118107753_66804739

Me too!

I faced with the same issue. Any update on this?