Files
volar-docs/docs/configuration-and-projects.md
2025-11-09 22:22:52 -06:00

8.2 KiB
Raw Blame History

Advanced Configuration & Project Shapes

Docs IndexRepo READMEGetting StartedPerformance Guide

Volar can power everything from tiny single-file experiments to massive monorepos with multiple editors attached. This guide documents every configuration option, project topology, and editor integration knob so you can tune Volar for any workspace.

Configuration Surfaces

Surface Who controls it Purpose
vueCompilerOptions in tsconfig.json / jsconfig.json Project authors Vue-specific compiler tweaks (reactivity transform, macros, experimental features).
Volar client settings (VS Code “Volar” section, Neovim config, etc.) End users Editor integration options (Take Over Mode, diagnostic toggles, traces).
server.configurations (volarJsonYaml in our example) Language server authors Custom feature flags for your own plugins/services.
CLI flags/environment variables Tooling authors Overrides for headless usage (e.g., VOLAR_TRACE=protocol for logging).

Volar Client Settings (VS Code)

Common keys in settings.json:

{
  "volar.takeOverMode.enabled": true,
  "volar.tsPlugin": true,
  "volar.vueserver.log": "verbose",
  "volar.diagnostics.onChange": true,
  "volar.autoCompleteRefs": true
}
  • takeOverMode.enabled: Replace VS Codes TypeScript LS with Volars integrated server for .ts/.js files (required for advanced template-inferred types). When true, ensure only one TS server runs to avoid duplicate diagnostics.
  • tsPlugin: Enables Volars TypeScript plugin so tsserver understands .vue.
  • diagnostics.onChange: Live diagnostics while typing vs on save.
  • vueserver.log: off | error | warn | info | verbose use verbose for deep debugging.

vueCompilerOptions

tsconfig.json / jsconfig.json supports:

{
  "compilerOptions": { /* TS options */ },
  "vueCompilerOptions": {
    "target": 3, // Vue compiler target
    "plugins": ["@vue-macros/volar"],
    "experimentalCompatMode": 2,
    "data": {
      "useDefineModel": true
    }
  }
}

Consult the official @vue/language-core docs for every vueCompilerOptions flag; key ones include:

  • target: Vue version (2, 3, 3.3, etc.) affects template compilation.
  • plugins: list of compiler plugins (macros, transform experiments).
  • experimentalCompatMode: compatibility with legacy APIs.
  • data.useDefineModel: toggles <script setup> defineModel() support.

Custom Configuration via server.configurations

Language servers can watch client settings:

const config = await server.configurations.get<YourSchema>('yourSection');
server.configurations.onDidChange(applyConfig);

Define a JSON schema and share it with users:

{
  "yourSection": {
    "schemaBaseUrl": "./schemas",
    "diagnostics": {
      "severity": "warning",
      "rules": {
        "missing-prop": "error",
        "unused-slot": "hint"
      }
    }
  }
}

Project Topologies

Single tsconfig Project

  • Standard Vue CLI / Vite projects.
  • Volar loads the root tsconfig.json (or jsconfig.json) and watches the file tree beneath it.
  • Keep include/exclude synchronized with your actual files to avoid invisible components.

Multi-Root Workspace (VS Code)

  • Each folder has its own tsconfig.json.
  • Volar runs a separate project per folder; cross-folder references use TypeScript project references if configured.
  • Use .code-workspace files to ensure consistent settings per folder:
{
  "folders": [{ "path": "packages/app" }, { "path": "packages/admin" }],
  "settings": {
    "volar.takeOverMode.enabled": true
  }
}

Monorepo with Many tsconfigs

Patterns:

  1. Project References preferred for TypeScript-heavy repos.
    • Root tsconfig.json lists references to each package.
    • Run tsc --build to validate; Volar mirrors the structure for editor flows.
  2. Workspace Globs if you have dozens of packages, create a script to generate a “super tsconfig” that includes every tsconfig.*.json.
  3. Per-package configs configure the LS to watch each package (Neovim volar plugin allows multiple root patterns).

Best Practices:

  • Keep tsconfig.json names consistent (use tsconfig.app.json, tsconfig.lib.json).
  • Enable "composite": true for referenced projects so TS + Volar can resolve type information quickly.
  • Avoid circular references; Volar mirrors TypeScripts behavior and will emit similar diagnostics if references loop.

Custom Workspaces (Outside TS)

If youre building an LSP that doesnt rely on tsconfig, manage workspaces manually:

server.workspaceFolders.onDidChange(({ added, removed }) => {
  for (const folder of added) loadProject(folder);
  for (const folder of removed) unloadProject(folder);
});
  • loadProject can build an in-memory graph (files, schema lookups, etc.) tailored to your tooling.
  • Always respect server.initializeParams.workspaceFolders on startup.

Take Over Mode vs Non-Take Over Mode

Mode Pros Cons When to Use
Take Over Mode enabled (volar.takeOverMode.enabled = true) One TypeScript server handles .ts/.js/.vue so template types flow into scripts seamlessly. Requires disabling built-in TS server; some lightweight editors dont support it. Default for VS Code users building Vue apps with TS.
Take Over Mode disabled Built-in TS handles .ts/.js, Volar handles .vue. Script + template types are disconnected; editing .ts may not reflect template data. Pure JavaScript projects, or when the host editor cant relinquish control of tsserver.

Neovim / Sublime / Other Editors: expose a setting for users to choose. Document the trade-offs clearly (e.g., “Enable Take Over Mode if you want <script setup> types to flow into .ts files, but note that TypeScript diagnostics now come from Volars server”).

Settings Synchronization

VS Code

  • Use workspace.getConfiguration('volar') in extensions to read settings.
  • Volar automatically watches DidChangeConfiguration and exposes it via server.configurations.

Neovim

  • Most LSP clients support the workspace/didChangeConfiguration notification. Ensure your plugin forwards user settings (Lua table) to Volar.

CLI / Headless

  • For custom CLIs, supply configuration as JSON via connection.initializeParams.initializationOptions.
  • Example:
startLanguageServer(async (params) => ({
  languageService: createService(params.initializationOptions),
}));

Feature Toggles & Profiles

Consider offering profiles for different workflows:

Profile Settings
“Strict typing” diagnostics.severity = error, enable template type checks, run takeOverMode.
“Draft mode” diagnostics.onChange = false, take over mode off, minimal info.
“Docs playground” Disable heavy TS features, turn on workspace.diagnostics for quick summary output.

Expose these as configuration “presets” so teams can switch quickly (e.g., volar.profile = "strict").

Practical Tips

  1. Document defaults when adding server.configurations keys, publish a table showing default values and range of allowed inputs.
  2. Validate settings run user-provided config through a JSON schema; reject invalid values and emit telemetry/log entries.
  3. Version config changes support configVersion so older clients can detect incompatible settings and fall back gracefully.
  4. Surface config errors use connection.window.showWarningMessage to notify users when configuration fails to apply (missing schema files, invalid globs, etc.).
  5. Per-folder overrides respect the scopeUri parameter in server.configurations.get(section, scopeUri) so multi-root workspaces can set different options per folder.

With these patterns, Volar can scale from simple single-project setups to sprawling monorepos, while giving both maintainers and end-users predictable levers to tune behavior. Always document the knobs you expose, and test configuration changes across VS Code, Neovim, and CLI flows to ensure settings propagate consistently.