prettier-plugin-organize-imports icon indicating copy to clipboard operation
prettier-plugin-organize-imports copied to clipboard

[Feature request] Add Svelte support

Open danielquintero opened this issue 2 years ago • 19 comments

I have used this plugin in Angular, React and Vue projects. Recently we started migrating a codebase to Svelte and I was eager to keep using this plugin for .svelte files... to my surprise there is no support for Svelte and actually I ran into issues where imports were getting removed when using svelte-language-tools + prettier-plugin-organize-imports...

Since there is Vue support for sfc, I think adding support for Svelte should be doable, right?

danielquintero avatar Oct 26 '21 17:10 danielquintero

Hey, yeah it's probably doable but I haven't worked with Svelte yet and even though I'd love to, I currently don't have the time. PRs are welcome 🙏

simonhaenisch avatar Oct 27 '21 08:10 simonhaenisch

Hey @danielquintero I just released a new version where you can enable an option organizeImportsSkipDestructiveCodeActions so that no imports would get removed. Maybe you can try that again in combination with svelte-language-tools and see if it works for you?

BWT if anyone knows a package similar to @volar/vue-typescript (has a drop-in replacement for ts.createLanguageService) but for Svelte, please let me know! In that case adding support would be very straightforward.

simonhaenisch avatar Aug 17 '22 06:08 simonhaenisch

Looked into it a bit more and it does look like organizeImports is implemented by svelte-language-server... I'm just not sure yet how to actually make use of it, i'll try to figure out if I find enough time.

https://github.com/sveltejs/language-tools/blob/936fa6fe7ce2697cf733f97b4b49fbfa2b1427b1/packages/language-server/src/plugins/typescript/features/CodeActionsProvider.ts#L95-L170

simonhaenisch avatar Aug 21 '22 19:08 simonhaenisch

So I've tried ~patching the preprocess hook of~ prettier-plugin-svelte (edit: patching it wasn't actually necessary, just needed to have the plugin installed), and it did somewhat work, giving me "svelte" as the parent parser and "typescript" as the child parser. It doesn't really make much sense to do it this way though, because this will just run the part inside the <script lang="ts"> tag through the TypeScript parser which lacks all the context of the whole .svelte file. To make organizeImports work, we'd have to trick it into thinking the file was a TS file (by appending .ts as an extension). I've done the same with Vue initially, and yeah it ended up being kinda useless because you'll import components and use them in the template but they'll be removed as unused.

I've also tried using typescript-svelte-plugin (by adding it to tsconfig.json as compilerOptions.plugins) which according to some docs should automatically wrap the TypeScript language service, and I was hoping that would allow me to run languageService.organizeImports on a .svelte file, however that didn't work... not sure why, maybe because of programmatic usage of the language service API. I've tried initializing it manually like the following but that didn't work either ("Error: Could not find source file: 'test.svelte'.")... looks wrong anyway.

const sveltePlugin = require('typescript-svelte-plugin');
const tss = require('typescript/lib/tsserverlibrary');
sveltePlugin({ typescript: tss });

languageService = tss.createLanguageService(getLanguageServiceHost(filepath, readFileSync(filepath, 'utf-8')));

So at this point I'm not sure how to make a language service that can take a whole .svelte file, and until there's some package for that or someone has an idea, I don't think I can find the time to figure this out. It would basically need to be @volar/vue-typescript but for Svelte. See https://github.com/johnsoncodehk/volar/blob/master/packages/vue-typescript/src/index.ts if someone wants to use that as a reference implementation.

simonhaenisch avatar Aug 21 '22 21:08 simonhaenisch

Came up with a PR ☝️ however I'm not very confident about it yet... if anyone would be able to test this out on their project, that would be really helpful! Clone the repo, checkout the simple-svelte-support branch, and link it into your project with npm (e. g. run npm link ../path/to/prettier-plugin-organize-imports).

simonhaenisch avatar Aug 21 '22 22:08 simonhaenisch

See comments on the PR (now closed)... there must be a way to use a piece of svelte language tools programmatically to do import organizing correctly from this plugin, I don't know where to start though (I've skimmed through the source code but couldn't find anything).

simonhaenisch avatar Sep 20 '22 10:09 simonhaenisch

@simonhaenisch FWIW there are only 4 references to organize in the repo: https://github.com/sveltejs/language-tools/search?q=organize&type=code

They are all in the Typescript provider, which makes me think the Svelte provider must extract the Typescript from Svelte along with some metadata about what imports are referenced by the component's HTML section, then the Typescript organizer returns an updated Typescript chunk.

benallfree avatar Sep 20 '22 11:09 benallfree

Reply from the Svelte Language Tools team: https://github.com/sveltejs/language-tools/issues/1649#issuecomment-1252339174

benallfree avatar Sep 20 '22 14:09 benallfree

You can try to use @volar-examples/svelte-typescript.

johnsoncodehk avatar Oct 07 '22 07:10 johnsoncodehk

@johnsoncodehk thanks a lot for this! I just tried it after installing the latest versions (1.0.3), however I have a couple of problems... here's the branch diff: volar-svelte-support

First problem is that createLanguageService doesn't accept a second argument according to the types, see @ts-ignore comment here:

https://github.com/simonhaenisch/prettier-plugin-organize-imports/blob/23c0bcd0d8dd9efac3903e91322e7a947d8ecb08/lib/get-language-service.js#L14-L19

Second problem is that I get the following error when running the test:

Error: Could not find source file: 'file.svelte'.

I can prevent this error by doing

https://github.com/simonhaenisch/prettier-plugin-organize-imports/blob/23c0bcd0d8dd9efac3903e91322e7a947d8ecb08/lib/organize.js#L24-L27

However I've had the same problem before with .vue files and you fixed it in vue-typescript instead, so I assume there's a way to fix this in the svelte language module?

Either way, calling languageService.organizeImports doesn't actually return any changes.

simonhaenisch avatar Oct 10 '22 10:10 simonhaenisch

I will check it later, but just have a quick look, why you don't use @volar-examples/svelte-typescript instead of @volar-examples/svelte-language-core?

johnsoncodehk avatar Oct 10 '22 10:10 johnsoncodehk

@johnsoncodehk not sure why but it's broken, doesn't contain the out/index.js... (see here: https://unpkg.com/browse/@volar-examples/[email protected]/). Maybe forgot to build before publishing?

simonhaenisch avatar Oct 10 '22 11:10 simonhaenisch

@simonhaenisch Sorry for delay, can you try v1.0.4-patch.1?

johnsoncodehk avatar Oct 11 '22 20:10 johnsoncodehk

@johnsoncodehk I just tried with latest (v1.0.8) and the "could not find source file" error is gone, thanks 🙏 But it's still the same problem that languageService.organizeImports(...) just returns undefined.

Maybe you can check my updated implementation at https://github.com/simonhaenisch/prettier-plugin-organize-imports/compare/volar-svelte-support. The changes are pretty minimal, just hooking into the svelte parser from prettier-plugin-svelte, then using createLanguageService method of @volar-examples/svelte-typescript. Could the problem be that the language service host needs to have a different implementation? (just re-using the one for Vue at this point)

simonhaenisch avatar Oct 19 '22 19:10 simonhaenisch

Any progress on this? Looking forward to it :)

Stadly avatar Oct 02 '23 07:10 Stadly

Would love svelte support as well :)

linkurzweg avatar Oct 05 '23 15:10 linkurzweg

sry got stuck and then didn't have time to work on it anymore. Volar tooling has been moved to @vue namespace and had some breaking changes since, which i also didn't have time to catch up with.

I'm happy to accept a contribution for this, I did some initial work in #80.

simonhaenisch avatar Oct 06 '23 10:10 simonhaenisch