mirror of
https://github.com/LukeHagar/volar-docs.git
synced 2025-12-06 04:22:01 +00:00
Saving inital Docs POC
This commit is contained in:
94
docs/monaco-playground.md
Normal file
94
docs/monaco-playground.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Building a Volar-Powered Monaco Playground
|
||||
|
||||
> [Docs Index](README.md) • [Repo README](../README.md) • [Volar Kit & Editor](volar-kit-and-editor.md) • [Live Examples](live-examples.md)
|
||||
|
||||
This guide walks through wiring Volar’s language service into a browser-based playground (Vue SFC REPL, documentation site, or sandbox) using `@volar/monaco`.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Monaco Editor (main thread)
|
||||
│
|
||||
├─ Worker (language service)
|
||||
│ ├─ TypeScript runtime
|
||||
│ ├─ Volar language service
|
||||
│ └─ Virtual file system (in-memory / IndexedDB)
|
||||
└─ UI (tabs, preview)
|
||||
```
|
||||
|
||||
## Step 1: Install Dependencies
|
||||
|
||||
```bash
|
||||
npm install monaco-editor @volar/monaco typescript
|
||||
```
|
||||
|
||||
## Step 2: Worker Setup
|
||||
|
||||
```ts
|
||||
// volar.worker.ts
|
||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import { setupLanguageServiceForMonaco } from '@volar/monaco';
|
||||
|
||||
setupLanguageServiceForMonaco(monaco, {
|
||||
loadTypescript: () => import('typescript/lib/typescript.js'),
|
||||
loadLanguageService: () => import('./volar-service-entry'),
|
||||
});
|
||||
```
|
||||
|
||||
`volar-service-entry` exports `createLanguageService(env)` that mirrors your server’s factory.
|
||||
|
||||
## Step 3: Main Thread Wiring
|
||||
|
||||
```ts
|
||||
import * as monaco from 'monaco-editor';
|
||||
|
||||
monaco.languages.register({ id: 'vue' });
|
||||
monaco.languages.onLanguage('vue', () => {
|
||||
new Worker(new URL('./volar.worker.ts', import.meta.url), { type: 'module' });
|
||||
});
|
||||
|
||||
const model = monaco.editor.createModel('<template>hi</template>', 'vue', monaco.Uri.parse('file:///App.vue'));
|
||||
monaco.editor.create(document.getElementById('editor')!, { model });
|
||||
```
|
||||
|
||||
## Step 4: Virtual File System
|
||||
|
||||
Track files and sync them with the language service host:
|
||||
|
||||
```ts
|
||||
const files = new Map<string, string>();
|
||||
|
||||
function syncModel(model: monaco.editor.ITextModel) {
|
||||
const uri = model.uri.toString();
|
||||
files.set(uri, model.getValue());
|
||||
languageServiceHost.writeFile(uri, model.getValue());
|
||||
}
|
||||
|
||||
monaco.editor.onDidCreateModel((model) => {
|
||||
syncModel(model);
|
||||
model.onDidChangeContent(() => syncModel(model));
|
||||
});
|
||||
```
|
||||
|
||||
Persist files using `localStorage`, IndexedDB, or encoded URLs so sessions can be shared.
|
||||
|
||||
## Step 5: Preview / Output Integration
|
||||
|
||||
- Render an iframe or use the Vue runtime to preview components.
|
||||
- Listen for diagnostics via Monaco markers and show a summary list.
|
||||
- Capture console output from the preview iframe for debugging.
|
||||
|
||||
## Performance Tips
|
||||
|
||||
1. Lazy-load worker bundle when a Vue file is opened.
|
||||
2. Debounce file sync to avoid flooding the worker.
|
||||
3. Reuse the same TypeScript module across workers (via CDN) to reduce bundle size.
|
||||
4. For large projects, load files on demand instead of preloading entire repos.
|
||||
|
||||
## Example Projects
|
||||
|
||||
- [Vue SFC Playground](https://github.com/vuejs/repl)
|
||||
- [StackBlitz Vue starter](https://stackblitz.com/edit/vue)
|
||||
- [CodeSandbox Projects](https://codesandbox.io/p/dashboard)
|
||||
|
||||
By reusing your existing Volar language-service factory in the browser, you guarantee parity between editor IntelliSense and playground experiences.
|
||||
Reference in New Issue
Block a user