prettier-plugin-organize-imports
prettier-plugin-organize-imports copied to clipboard
[Feature request] Add Svelte support
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?
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 🙏
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.
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
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.
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
).
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 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.
Reply from the Svelte Language Tools team: https://github.com/sveltejs/language-tools/issues/1649#issuecomment-1252339174
You can try to use @volar-examples/svelte-typescript.
@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.
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 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 Sorry for delay, can you try v1.0.4-patch.1?
@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)
Any progress on this? Looking forward to it :)
Would love svelte support as well :)
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.