Svelte Language Tools

repository·master·Indexed 23 days ago

https://github.com/sveltejs/language-tools

LSP implementation for Svelte that enables advanced editor features like autocompletion, diagnostics, and error checking. It serves as the engine for the official Svelte VS Code extension and includes the svelte-check CLI for project-wide diagnostics. Provides detailed configuration options for Svelte, TypeScript, CSS, and HTML plugins, as well as support for @component docstrings and Prettier formatting.

Tokens
33.3K
Snippets
63
Records
168
Agent score
81%

What's inside @svelte/language-tools

  1. Features of Svelte for VS Code

    master

    The extension provides several developer experience features within .svelte files:

    • Intellisense & Navigation: Autocompletions, Hover info, Go to definition, and Symbols in the outline panel.
    • Code Editing: Formatting (via prettier-plugin-svelte), Emmet support, and Code Actions.
    • Diagnostics: Error and warning messages.
    • Specialized Commands:
      • Svelte: Show Compiled Code: Preview the compiled code in DOM mode.
      • Svelte: Extract Component: Extract template content into a new component.
    • Styling: CSS Color highlighting and color picker.
    • TypeScript Integration: When svelte.enable-ts-plugin is enabled, it provides intellisense for interacting with Svelte files from within JavaScript and TypeScript files.
  2. Understand TextMate grammar constraints

    master

    VS Code uses TextMate grammars for syntax highlighting, which rely heavily on regular expressions (including lookarounds and references). Key behaviors to note:

    • Greediness: TextMate is a greedy grammar and does not backtrack once a match is found.
    • Nesting: Grammars can be nested, but child matches can exceed the boundaries of their parent match.
  3. How Svelte Language Tools work together

    master

    The language-tools ecosystem consists of several interconnected packages that provide IDE features and code validation for Svelte:

    • svelte-vscode: The Svelte for VSCode extension. It provides syntax highlighting and connects to the language server.
    • language-server: An LSP-compliant server that provides IntelliSense (autocomplete, go to definition, etc.). It coordinates several specialized services:
      • CSS: IntelliSense for <style> blocks.
      • HTML: IntelliSense for basic HTML tags.
      • Svelte: Diagnostics from the Svelte compiler, formatting via prettier-plugin-svelte, and refactorings like "Extract Component".
      • TypeScript/JavaScript: Holistic IntelliSense for both <script> and template syntax.
    • svelte2tsx: A transformation engine used by the language server to convert Svelte code into a format the TypeScript language service can understand.
    • svelte-check: A CLI tool used to run diagnostics on Svelte code by spinning up the language server.
  4. How svelte2tsx provides IntelliSense

    master

    To provide accurate IntelliSense (like hover info or autocomplete) across both the <script> and the Svelte template, the language server uses svelte2tsx.

    Instead of writing a custom language service from scratch, svelte2tsx transforms Svelte code into a valid JavaScript or TypeScript representation. This allows the existing TypeScript language service to perform the heavy lifting (e.g., getQuickInfoAtPosition).

    Key details:

    • The generated code is purely for IntelliSense and is not runnable at runtime.
    • It uses source mappings to map positions in the generated code back to the original Svelte file.
    • It uses ambient definitions and type definitions (like svelte-jsx-v4.d.ts) to define intrinsic elements, attributes, and events. If you encounter errors stating a DOM attribute is not assignable to a DOM element, it is likely due to these declarations.
  5. How the TypeScript Svelte plugin works

    master

    The typescript-svelte-plugin provides Svelte support within TS/JS files by performing three main architectural tasks:

    1. Module Resolution Patching: It patches TypeScript's module resolution algorithm to recognize .svelte files (which are not natively supported) and resolve them to valid TS/JS file types.
    2. Code Transformation via svelte2tsx: It patches the readFile method of TypeScript's project service. When a .svelte file is read, the plugin uses svelte2tsx to transform the Svelte code into TS/JS code before returning it to TypeScript. It also patches ScriptInfo methods to ensure position transformations (offsets to positions and vice versa) work correctly between the original Svelte code and the generated TS/JS code.
    3. Language Service Enhancement: It patches language service methods to apply custom logic, primarily focusing on mapping positions from the generated code back to the original Svelte source code.

    Note: This implementation relies on patching internal TypeScript methods, which is necessary for current Svelte support but may be sensitive to TypeScript updates.

  6. Configure PostCSS with a custom config path

    master

    If your svelte.config.js is not located in the workspace root (e.g., it is inside a /frontend directory), you must explicitly provide the path to your PostCSS configuration file because relative paths are resolved relative to the node process working directory.

    import sveltePreprocess from 'svelte-preprocess';
    import { dirname, join } from 'path';
    import { fileURLToPath } from 'url';
    
    const __dirname = dirname(fileURLToPath(import.meta.url));
    
    export default {
        preprocess: sveltePreprocess({
            postcss: {
                configFilePath: join(__dirname, 'postcss.config.cjs')
            }
        })
    };
  7. Install and configure the typescript-svelte-plugin manually

    master

    The typescript-svelte-plugin provides intellisense (Rename, Find Usages, Go To Definition, and Diagnostics) when interacting with Svelte files from within .ts or .js files.

    If you are not using the Svelte for VS Code extension (which includes this plugin automatically), you must install it manually and update your TypeScript or JavaScript configuration.

    1. Install the package

    npm install --save-dev typescript-svelte-plugin

    2. Update tsconfig.json or jsconfig.json

    Add the plugin to the plugins array within compilerOptions.

    {
        "compilerOptions": {
            "plugins": [{
                "name": "typescript-svelte-plugin",
                "enabled": true,
                "assumeIsSvelteProject": false
            }]
        }
    }
  8. Configure TypeScript 7 support for svelte-check

    master

    TypeScript 7 support currently requires the --tsgo or --tsgo-experimental-api flag. You must have both TypeScript 7 and TypeScript 6 installed. You can manage both versions using an npm alias:

    npm install --save-dev typescript@~6 @typescript/native@npm:typescript@7
    npm install --save-dev typescript@~6 @typescript/native@npm:typescript@7
  9. Set up TypeScript support in Svelte

    master

    To use TypeScript in Svelte components, add the lang="ts" attribute to your <script> tags.

    If you are adding TypeScript to an existing project, you may need to configure a preprocessor in svelte.config.js.

    ESM-style (for SvelteKit or projects with "type": "module" in package.json):

    import sveltePreprocess from 'svelte-preprocess';
    
    export default {
        preprocess: sveltePreprocess()
    };

    CJS-style:

    const sveltePreprocess = require('svelte-preprocess');
    
    module.exports = {
        preprocess: sveltePreprocess()
    };

    After updating your configuration, you must restart the Svelte Language Server in your editor (e.g., via the VS Code Command Palette: Svelte: Restart Language Server) to apply the changes.

    <script lang="ts">
        export let name: string;
    </script>
  10. Test Svelte syntax grammars with snapshots

    master

    To ensure grammar changes do not break existing syntax highlighting, use the textmate-grammar-test utility. If you modify the Svelte grammar file, you should first add new test cases to the test/sample directory.

    Run the test suite to check if updates affect existing cases, or use the --updateSnapshot flag to update existing snapshots to match your new changes.