TypeFox / monaco-languageclient

Repo hosts npm packages for monaco-languageclient, vscode-ws-jsonrpc, monaco-editor-wrapper, @typefox/monaco-editor-react and monaco-languageclient-examples
https://www.npmjs.com/package/monaco-languageclient
MIT License
1.06k stars 179 forks source link
language-server language-server-protocol lsp monaco monaco-editor vscode

Monaco Language Client, VSCode WebSocket Json RPC, Monaco-Editor-Wrapper, Monaco-Editor-React and examples

Github Pages monaco-languageclient PRs Welcome Gitpod - Code Now
monaco-languageclient Version monaco-languageclient Downloads vscode-ws-jsonrpc Version vscode-ws-jsonrpc Downloads monaco-editor-wrapper Version monaco-editor-wrapper Downloads monaco-editor-react Version monaco-editor-react Downloads

This repository now host multiple npm packages under one roof:

The examples not requiring a backend are now available via GitHub Pages.

Changelogs, project history and compatibility

CHANGELOGs for each project are available from the linked location:

Important Project changes and notes about the project's history are found here.

You find the monaco-editor, vscode, @codingame/monaco-vscode-api and @codingame/monaco-vscode-editor-api compatibility table here.

This article describes the initial motivation for starting monaco-languageclient.

Getting started

On your local machine you can prepare your dev environment as follows. At first it is advised to build everything. Or, use a fresh dev environment in Gitpod by pressing the code now badge above. Locally, from a terminal do:

git clone https://github.com/TypeFox/monaco-languageclient.git
cd monaco-languageclient
npm i
# Cleans-up, compiles and builds everything
npm run build

Vite dev server

Start the Vite dev server. It serves all client code at localhost. You can go to the index.html and navigate to all client examples from there. You can edit the client example code directly (TypeScript) and Vite ensures it automatically made available:

npm run dev
# OR: this clears the cache and has debug output
npm run dev:debug

As this is a npm workspace the main package.json contains script entries applicable to the whole workspace like watch, build and lint, but it also contains shortcuts for launching scripts from the childe packages like npm run build:examples.

If you want to change the libries and see this reflected directly, then you need to run the watch command that compiles all TypeScript files form both libraries and the examples:

npm run watch

Usage

Please look at the respective section in the packages:

Examples Overview

The examples demonstrate mutliple things:

Main Examples

JSON Language client and language server example (Location)

The json-server runs an external Node.js Express app where web sockets are used to enable communication between the language server process and the client web application (see JSON Language Server). The json-client contains the monaco-editor-wrapper app which connects to the language server and therefore requires the node server app to be run in parallel.

Python Language client and pyright language server example (Location)

The python-server runs an external Node.js Express app where web sockets are used to enable communication between the language server process and the client web application (see Pyright Language Server). The python-client contains the monaco-editor-wrapper app which connects to the language server and therefore requires the node server app to be run in parallel. It is also possible to use a @typefox/monaco-editor-react app to connect to the server.

Groovy Language client and language server example (Location)

The groovy-server runs an external Java app where web sockets are used to enable communication between the language server process and the client web application (Groovy Language Server). The groovy-client contains the monaco-editor-wrapper app which connects to the language server and therefore requires the node server app to be run in parallel.

Java Language client and language server example (Location)

The java-server runs an external Java app where web sockets are used to enable communication between the language server process and the client web application (Java Language Server). The java-client contains the monaco-editor-wrapper app which connects to the language server and therefore requires the node server app to be run in parallel.

Langium examples (here client and server communicate via vscode-languageserver-protocol/browser instead of a web socket used in the three examples above

Cpp / Clangd (Location)

It contains both the language client and the langauge server (web worker). The clangd language server is compiled to wasm so it can be executed in the browser. Heads up: This is a prototype and still evolving.

Application Playground (Location)

This example uses the view service provider from @codingame/monaco-vscode-editor-api to build an application that utilizes more vscode features. Heads up: This is a prototype and still evolving.

Langium grammar DSL (Location)

It contains both the language client and the langauge server (web worker). Here you can chose beforehand if the wrapper should be started in classic or extended mode.

Statemachine DSL (created with Langium) (Location)

It contains both the language client and the langauge server (web worker). It is also possible to use a @typefox/monaco-editor-react app to connect to the server.

bare monaco-languageclient (Location)

It demostrate how the JSON Language client and language server example can be realised without monaco-editor-wrapper. You find the implementation here.

Browser example (Location)

It demonstrates how a monaco-editor-wrapper can be combined with a language service written in JavaScript. This example can now be considered legacy as the web worker option eases client side language server implementation and separation, but it still shows a valid way to achieve the desired outcome.

Purely monaco-editor related examples

See Typescript Language support.

Server processes

JSON Language Server

For the json-client, react-client or the client-webpack examples you need to ensure the json-server example is running:

# start the express server with the language server running in the same process.
npm run start:example:server:json
Pyright Language Server

For the python-client example you need to ensure the python-server example is running:

# start the express server with the language server running as external node process.
npm run start:example:server:python
Groovy Language Server

For the groovy-client example you need to ensure the groovy-server example is running. You require docker-compose which does not require any manual setup (OpenJDK / Gradle). From the project root run docker-compose -f ./packages/examples/resources/groovy/docker-compose.yml up -d. First start up will take longer as the container is downloaded from GitHub's container registry. Use docker-compose -f ./packages/examples/resources/groovy/docker-compose.yml down to stop it.

Java Language Server

For the java-client example you need to ensure the java-server example is running. You require docker-compose which does not require any manual setup (OpenJDK / Eclipse JDT LS). From the project root run docker-compose -f ./packages/examples/resources/eclipse.jdt.ls/docker-compose.yml up -d. First start up will take longer as the container is downloaded from GitHub's container registry. Use docker-compose -f ./packages/examples/resources/eclipse.jdt.ls/docker-compose.yml down to stop it.

Verification Examples & Usage

None of the verification examples is part of the npm workspace. Some bring substantial amount of npm dependencies that pollute the main node_modules dependencies and therefore these examples need to be build and started independently. All verifaction examples re-uses the code form the json client example and therefore require the json server to be started.

VSCode integration

You can as well run vscode tasks to start and debug the server in different modes and the client.

Featured projects

Troubleshooting

General

Whenever you used monaco-editor, vscode, monaco-languageclient, monaco-editor-wrapper or @typefox/monaco-editor-react ensure they are imported before you do any monaco-editor or vscode api related intialization work or start using it. Please check the our python language client example to see how it should be done.

Dependency issues: monaco-editor / @codingame/monaco-vscode-api / @codingame/monaco-vscode-editor-api

If you have mutiple, possibly hundreds of compile errors resulting from missing functions deep in monaco-editor or vscode then it is very likely your package-lock.json or node_modules are dirty. Remove both and do a fresh npm install. Always npm list monaco-editor is very useful. If you see different or errornous versions, then this is an indicator something is wrong.

Volta

There are Volta instructions in the package.json files. When you have Volta available it will ensure the exactly specified node and npm versions are used.

Vite dev server troubleshooting

When you are using vite for development please be aware of this recommendation.

If you see the problem Assertion failed (There is already an extension with this id) you likely have mismatching dependencies defined for vscode / @codingame/monaco-vscode-api. You should fix this or add the following entry to your vite config:

resolve: {
  dedupe: ['vscode']
}

SSR frameworks

Important: Due to its reliance on monaco-editor and @codingame/monaco-vscode-api this stack will very likely not work with Server-Side Rendering (SSR) frameworks. They client code has to be run in a browser environment.

Serve all files required

@codingame/monaco-vscode-api requires json and other files to be served. In your project's web-server configuration you have to ensure you don't prevent this.

Bad Polyfills

buffer

If you see an error similar to the one below:

Uncaught Error: Unexpected non—whitespace character after JSON at position 2

SyntaxError: Unexpected non—whitespace character after JSON at position 2
    at JSON. parse («anonymous>)

It is very likely you have an old version of buffer interfering (see #538 and #546). You can enforce a current version by adding a resolution as shown below to your projects' package.json.

"resolutions": {
  "buffer": "~6.0.3",
}

monaco-editor and react

We recommend you now use typefox/monaco-editor-react.

But if you need to use @monaco-editor/react, then add the monaco-editor import at the top of your editor component file source:

import * as monaco from "monaco-editor";
import { loader } from "@monaco-editor/react";

loader.config({ monaco });

pnpm

If you use pnpm, you have to add vscode / @codingame/monaco-vscode-api as direct dependency (you find the compatibility table here, otherwise the installation will fail.

"vscode": "npm:@codingame/monaco-vscode-api@~11.1.1"

Licenses