Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions docs/internal/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ svelte-check |
As briefly touched already, this is a language-server adhering to the [Language Server Protocol (LSP)](https://microsoft.github.io/language-server-protocol).
The protocol defines the communication between an editor or IDE and a language server that provides language features like auto complete, go to definition, find all references etc.

Our `language-server` can roughly be splitted into [four areas](/packages/language-server/src/plugins):
Our `language-server` can roughly be split into [four areas](/packages/language-server/src/plugins):

- CSS: Provides intellisense for the things inside `<style>`. Internally it mostly forwards stuff to the `vscode-css-languageservice`.
- HTML: Provides intellisense for basic HTML tags like `div`, `a` etc. Internally it mostly forwards stuff to the `vscode-html-languageservice`. Svelte-specific template syntax is _NOT_ handled here.
- CSS: Provides IntelliSense for the things inside `<style>`. Internally it mostly forwards stuff to the `vscode-css-languageservice`.
- HTML: Provides IntelliSense for basic HTML tags like `div`, `a` etc. Internally it mostly forwards stuff to the `vscode-html-languageservice`. Svelte-specific template syntax is _NOT_ handled here.
- Svelte: Provides the diagnostics of the Svelte compiler. If you use preprocessors, those are invoked beforehand - that's why we need the `svelte.config.js` to know how to preprocess your files. It also does the formatting through `prettier-plugin-svelte` and other cross-cutting concerns like the "Extract Component" refactoring.
- TypeScript/JavaScript: Provides intellisense for all JS/TS related stuff. This not only includes code inside `<script>` but also inside the template the moment you use any of the Svelte specifics like bindings or template syntax. `svelte2tsx` is used in here, and only here.
- TypeScript/JavaScript: Provides IntelliSense for all JS/TS related stuff. This not only includes code inside `<script>` but also inside the template the moment you use any of the Svelte specifics like bindings or template syntax. `svelte2tsx` is used in here, and only here.

The last area, TS/JS, is where most of the work is done. Svelte is a mix of JavaScript/TypeScript inside `script` and more of it within Svelte's template syntax. To get a holistic view of the file, we need to account for both.
This is also the reason why preprocessors such as `svelte-preprocess` cannot do type checking because it produces wrong diagnostics. To preprocess the script content, it only gets the content from the script. Think of this situation:
Expand All @@ -46,11 +46,15 @@ To get that holistic view, we need `svelte2tsx`.
To get a holistic view of Svelte files, we have two options:

1. Write a language service ourselves which is capable of doing things like auto complete, go to definition, rename etc.
2. Convert the Svelte code to something an existing language service can process which then does auto complete, go to defintion, rename etc for us.
2. Convert the Svelte code to something an existing language service can process which then does auto complete, go to definition, rename etc for us.

We chose the second option because TypeScript provides a language service which can do all the heavy lifting for us: We give it some files and then invoke methods like `getQuickInfoAtPosition` for hover info. These files need to be in a format the language service can understand: A form of JavaScript or TypeScript. `svelte2tsx` is the package which does this transformation: Pass in Svelte code and get back JSX or TSX code, depending on whether or not you use TS in Svelte. `svelte2tsx` uses some [ambient definitions](/packages/svelte2tsx/svelte-shims.d.ts) which are loaded by the language server, to do some of the transformations. It also provides [JSX definitions](/packages/svelte2tsx/svelte-jsx.d.ts) which are recognized by the TypeScript compiler and define intrinsic elements, attributes and events - so if you ever get an error that a DOM attribute is not assignable to a DOM element, it's likely a missing declaration in there.
We chose the second option because TypeScript provides a language service which can do all the heavy lifting for us: We give it some files and then invoke methods like `getQuickInfoAtPosition` for hover info. These files need to be in a format the language service can understand: A form of JavaScript or TypeScript. `svelte2tsx` is the package which does this transformation: Pass in Svelte code and get back JSX or TSX code, depending on whether or not you use TS in Svelte.

The code generated by `svelte2tsx` is not runnable in any way and does not actually exist at runtime when you run your app, it purely exists for the intellisense. The code also returns source mappings so we know which position in the original code corresponds to which generated position.
`svelte2tsx` uses some [ambient definitions](/packages/svelte2tsx/svelte-shims.d.ts) which are loaded by the language server to do some of the transformations. It also provides [JSX definitions](/packages/svelte2tsx/svelte-jsx.d.ts) which are recognized by the TypeScript compiler and define intrinsic elements, attributes and events - so if you ever get an error that a DOM attribute is not assignable to a DOM element, it's likely a missing declaration in there.

The code generated by `svelte2tsx` is not runnable in any way and does not actually exist at runtime when you run your app, it purely exists for the IntelliSense.

The code also returns source mappings so we know which position in the original code corresponds to which generated position.

### Integration of svelte2tsx into the language-server

Expand Down