Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Crash" when used with prettier and eslint #57

Open
SteveALee opened this issue Sep 11, 2019 · 17 comments
Open

"Crash" when used with prettier and eslint #57

SteveALee opened this issue Sep 11, 2019 · 17 comments

Comments

@SteveALee
Copy link

Please see sveltejs/svelte#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.

@btamas
Copy link

btamas commented Nov 15, 2019

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

@jzillmann
Copy link

Me too!

@toerndev
Copy link
Contributor

toerndev commented Feb 2, 2020

It seems like prettier-plugin-svelte isn't compatible with eslint-plugin-svelte3 via eslint-plugin-prettier, however meanwhile we can still extend eslint-config-prettier and call prettier separately from eslint i.e. directly from the editor.
For those using vim and w0rp/ale, this works with let g_ale_linter_aliases = { 'svelte': ['javascript'] } and let g:ale_fixers = { ..., 'svelte': ['eslint', 'prettier'] } (eslint as both linter and fixer to get both warnings and fixes). Also with w0rp/ale it replaces the buffer with any log output from prettier on syntax error (!), so open node_modules/prettier-plugin-svelte/plugin.js and comment out the console.log line.

@maxwell-k
Copy link

I have the same problem, which means I am not using eslint-plugin-prettier although I would like to. I am also using vim and ALE but have a slightly different workaround; I don't get fixes from eslint, but for me this is perhaps simpler:

let b:ale_linter_aliases = {'svelte': 'javascript'}
let b:ale_linters = ['eslint',]
let b:ale_fixers = ['prettier',]

I haven't got as far as figuring out where to start with a fix for the underlying issue.

@toerndev
Copy link
Contributor

toerndev commented Feb 4, 2020

Did some debugging, seems like eslint-plugin-svelte3 only extracts JS from the <script> part and returns this (through eslint-plugin-prettier) for prettier to parse, meanwhile prettier-plugin-svelte expects a whole .svelte file to break down into an AST, and crashes.

I'm trying to get this confirmed in the Prettier community but it seems to me like the eslint plugin is at fault here for not sending the whole file, which Prettier is capable of parsing (with the plugin). The JSX in the template part of .svelte files should also be formatted by Prettier, and if we look at eslint-plugin-react it indeed sends the whole .jsx file through eslint-plugin-prettier.

I'd like to ask the Svelte community why they say that prettier-plugin-svelte is wrong (see issue #3550 linked above) + that we should disable eslint-plugin-prettier when using their eslint plugin. Is it a misunderstanding, or was it just too difficult to implement the eslint plugin differently at the time...?

@SteveALee
Copy link
Author

@torndev I found the same and worked around this in VS Code -

see https://github.com/SteveALee/svelte-code-cypress-project/blob/master/README.md

I created a bug with more details here sveltejs/svelte#3550 but seems it was the wrong place.

Also jamesbirtles/svelte-vscode#74

Also see

@toerndev
Copy link
Contributor

toerndev commented Feb 4, 2020

@SteveALee Yeah the answer to sveltejs/svelte#3550 is what's making me confused. It would seem like exactly the right place to resolve the problem. Maybe we can try to get it reopened.

@toerndev
Copy link
Contributor

toerndev commented Feb 17, 2020

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... 😆

@boojum
Copy link

boojum commented Apr 20, 2020

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.

krishnagopinath added a commit to krishnagopinath/sturgis that referenced this issue May 4, 2020
* Setup svelte project
* pull out eslint + prettier integration and use prettier directly: sveltejs/prettier-plugin-svelte#57
@dummdidumm
Copy link
Member

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.

@dionysiusmarquis
Copy link

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.

@Nick-Mazuk
Copy link

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

@dummdidumm
Copy link
Member

dummdidumm commented Mar 31, 2021

The problem is neither eslint-plugin-svelte3 nor prettier-plugin-svelte, it's eslint-plugin-prettier not making them play nice together. The problem is that eslint-plugin-svelte3 needs to extract the JS parts of the Svelte file, because ESLint can only run on that. This means that something like export let foo is passed to prettier-plugin-svelte, which then throws, because that is invalid Svelte code. Looking at the code it seems that enhancing this line with svelte may be enough (maybe that list should also be made enhancable through configuration on their side). I suggest you try that out and see if my hunch is correct. I suggest you also open an issue on their side with a reproduction so they can look into it.

@dclasen-qd
Copy link

@dummdidumm I tried your suggestion and it seems to resolve the crash issue. However the linter still reports false positive errors for prettier/prettier:

<script lang="ts">
    interface Foo {
      baz: string[];
      foo: boolean;
    }

    export let properties: Foo
</script>

{#if properties.foo}
    {#each properties.baz as bar}
      <p>
        {bar}
      </p>
    {/each}
{/if}
Foo.svelte
  11:12  error  Insert `··`  prettier/prettier

That is the line: {#each properties.baz as bar} where eslint/prettier wants to fix it with extra whitepaces between the #each and properties.baz which does not help to get rid of the error. It will just keep complaining and --fix will just keep adding more whitespaces as prettier is still not running on the source but the transpiled code given from the eslint-plugin-svelte3.

@JounQin
Copy link

JounQin commented Jun 27, 2022

@JounQin
Copy link

JounQin commented Aug 11, 2022

I think this can be closed in favor of prettier/eslint-plugin-prettier#483

@piyushere
Copy link

I think this can be closed in favor of prettier/eslint-plugin-prettier#483

I don't think so, I am still getting this error with the eslint-plugin-prettier@4.2.1 and the official eslint-plugin-svelte3:
image
which doesn't make any sense.

I have not tried this with the recommended eslint-plugin-svelte package yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests