Repository for NPM module to connect Monaco editor with language servers and NPM module which implements communication between a jsonrpc client and server over WebSocket.
Click here for a detail explanation how to connect the Monaco editor to your language server.
- Monaco Language Client & VSCode WebSocket Json RPC
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
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
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
Since version 2 (see Important Project Changes) of this library we rely on @codingame/monaco-vscode-api to supply the vscode API. It evolved substantially since then and thesedays allows to use many vscode only services with monaco-editor
.
Earlier in 2023 we started to treemend an existing monaco-editor
dependency via a postinstall script. This adds back monaco-editor code that was removed during bundling/threeshaking (treemending). See the detailed explanation here. But, this introduced multiple problems.
With v7 we decided to use readily treemended version of monaco-editor called @codingame/monaco-editor-treemended, but this requires to add overrides
(npm/pnmpm) and resolutions
(yarn) in your project. Setting these ensures that all dependencies to monaco-editor
and vscode
are aligned:
"overrides": {
"monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.83.5 <1.84.0",
"vscode": "npm:@codingame/monaco-vscode-api@>=1.83.5 <1.84.0"
},
"resolutions": {
"monaco-editor": "npm:@codingame/monaco-editor-treemended@>=1.83.5 <1.84.0",
"vscode": "npm:@codingame/monaco-vscode-api@>=1.83.5 <1.84.0"
}
In the following table you can see the effect (Angular clinet example was used to demonstrate it):
No overrides | With overrides |
---|---|
With overrides
or resolutions
configured any child depndencies with a another monaco-editor
version will chnaged to the one you enforce.
This means some extra-configuration work, but removes the need for any postinstall scripts which lead to multiple package manager problems. It is now also very clear what is used and needed. Please see Monaco-editor / @codingame/monaco-vscode-api compatibility table for a complete overview.
The bespoke projects not only supplies the api, but it provides 100+ packages with additional services, default extensions and language packs. By default when initalizing monaco-languageclient
via the required initServices
the folliwing services are always loaded:
- languages and model services (always added by
monaco-languagclient
) - layout, environment, extension, files and quickAccess (always added by
monaco-vscode-api
)
Please check the following link for information about all services supplied by @codingame/monaco-vscode-api.
Please check our examples in the examples overview chapter as they demonstrate the usage (jump-start: python client for services and default extension usage or Langium Statemachine / Locale Loader)
If you use the textmate
or theme
services you are able to load textmate based grammars and theme definitions from vscode:
import getThemeServiceOverride from '@codingame/monaco-vscode-theme-service-override';
import getTextmateServiceOverride from '@codingame/monaco-vscode-textmate-service-override';
Once you those services you can no longer make use of monarch based grammars and themes.
There are a couple of different examples that demonstrate how the monaco-languageclient
can be used.
-
JSON Language client and language server example:
-
The json-server runs a Node.js Express app where web sockets are used to enable communication between the language server process and the client web application. The language server can be started as internal or external process. Use
npm run start:example:server:json
to start the language server (see Server processes). -
The json-client contains the client web app which connects to the language server therefore requires the node server app to be run in parallel.
-
-
Python Language client and pyright language server example:
-
The python-server runs a Node.js Express app where web sockets are used to enable communication between the language server process and the client web application. The language server can be started as internal or external process. Use
npm run start:example:server:python
to start the language server (see Server processes). -
The python-client contains the client web app which connects to the language server therefore requires the node server app to be run in parallel.
-
-
Langium example:
- Statemachine DSL (created with Langium) statemachine-web-worker-language-server example located in ./packages/examples/src/langium contains both the language client and the langauge server (web worker). The web worker example communicate via
vscode-languageserver-protocol/browser
instead of a web socket used in the JSON examples examples.
- Statemachine DSL (created with Langium) statemachine-web-worker-language-server example located in ./packages/examples/src/langium contains both the language client and the langauge server (web worker). The web worker example communicate via
-
The browser example located in ./packages/examples/src/browser demonstrates how a language service written in JavaScript can be used in a Monaco Editor contained in a simple HTML page. This example can now be considered legacy as the web worker option eases client side language server implementation and separation.
-
The react-client example located in ./packages/examples/src/react contains the React client. It does the same as the regular client example but inside a React Functional Component.
-
The angular-client example is now found in its own repository
Important: Apart from the json-server and python-server process all other will be server by the Vite dev server. Some examples share common code to reduce the amount of redundant code.
-
The webpack verification example located in ./packages/verify/webpack demonstrates how bundling can be achieved with webpack. You find the configuration here: webpack.config.js.
-
The vite verification example located in ./packages/verify/vite demonstrates how bundling can be achieved with vite. There is no configuration required.
- ./packages/verify/pnpm is not part of the npm workspace. It allows to test whether
pnpm install
works as expected and it allows to test@codingame/monaco-vscode-api
treemending viapnpm run test:treemending
. - ./packages/verify/yarn is not part of the npm workspace. It allows to test whether
yarn install
works as expected and it allows to test@codingame/monaco-vscode-api
treemending viayarn run test:treemending
.
For the json-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
For the python-client example you need to ensure the paython-server example is running:
# start the express server with the language server running in an external node process.
npm run start:example:server:python
If you want to reach the verification examples from the vite dev server index page you need to run the following additional http-servers beforehand (this is also indicated on the page itself):
# Serve the webpack verification example on http://localhost:8081
npm run start:verify:webpack
# Serve the vite verification example on http://localhost:8082
npm run start:verify:vite
You can as well run vscode tasks to start and debug the server in different modes and the client.
Again, if you use monaco-languageclient make sure you define matching Overrides instructions in your local project to override any mismatching monaco-editor or vscode versions with you dependency tree.
Ensure monaco-editor, vscode and monaco-languageclient are imported before you do any monaco-editor or vscode-api intialization or start using it. Please check the our python language client example to see how it should be done.
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.
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 monaco-editor
or @codingame/monaco-vscode-api
. You should fix this or add the following entry to your vite config:
resolve: {
dedupe: ['monaco-editor', 'vscode']
}
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",
}
Originally monaco-languageclient was dependent on monaco-editor-core, but we changed this with version 1.0.0. If your project requires to use monaco-editor-core and you want to stay compatible with 1.0.0 of monaco-languageclient you can install monaco-editor-core as monaco-editor:
npm install monaco-editor@npm:monaco-editor-core
Or if you are using Webpack you can alternatively add this alias to its config:
resolve: {
alias: {
// This doesn't pull any languages into bundles and works as monaco-editor-core was installed
'monaco-editor$': 'monaco-editor-core$',
'monaco-editor/': 'monaco-editor-core/',
}
}
If you use monaco-editor as dependency, but only want to have the content of monaco-editor-core than just only import:
import * as monaco from 'monaco-editor/esm/vs/editor/edcore.main.js';
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 });
If you use pnpm, you have to add vscode
/ @codingame/monaco-vscode-api
as direct dependency (see the following table), otherwise the installation will fail.
"vscode": "npm:@codingame/monaco-vscode-api@>=1.83.5 <1.84.0"
The following table describes which version of monaco-languageclient and @codingame/monaco-vscode-api are compatible with a specific version of monaco-editor. The listing starts with version 2.0.0 because @codingame/monaco-vscode-api was introduced for the first time.
Important: Please see the following table which monaco-editor
or @codingame/monaco-editor-treemended
(since v7) versions are required to be used you use the correct monaco-editor version.
monaco-languageclient | monaco-vscode-api | monaco-editor-treemended | monaco-editor | release date | comment |
---|---|---|---|---|---|
7.0.0 | 1.83.5 | 1.83.5 | 0.44.0 | 2023-11-02 | Introduction of @codingame/monaco-editor-treemended |
6.6.1 | 1.83.3 | 0.44.0 | 2023-10-20 | ||
6.6.0 | 1.83.2 | 0.44.0 | 2023-10-16 | ||
6.5.3 | 1.82.5 | 0.43.0 | 2023-10-11 | ||
6.5.2 | 1.82.4 | 0.43.0 | 2023-10-07 | ||
6.5.1 | 1.82.3 | 0.43.0 | 2023-10-04 | ||
6.5.0 | 1.82.2 | 0.43.0 | 2023-09-29 | ||
6.4.6 | 1.81.7 | 0.41.0 | 2023-09-05 | ||
6.4.5 | 1.81.5 | 0.41.0 | 2023-08-30 | ||
6.4.4 | 1.81.5 | 0.41.0 | 2023-08-24 | ||
6.4.3 | 1.81.3 | 0.41.0 | 2023-08-22 | ||
6.4.2 | 1.81.2 | 0.41.0 | 2023-08-19 | ||
6.4.1 | 1.81.1 | 0.41.0 | 2023-08-18 | ||
6.4.0 | 1.81.0 | 0.41.0 | 2023-08-10 | ||
6.3.0 | 1.80.2 | 0.40.0 | 2023-08-04 | ||
6.2.0 | 1.79.3 | 0.39.0 | 2023-06-16 | ||
6.1.0 | 1.79.1 | 0.38.0 | 2023-06-12 | ||
6.0.3 | 1.78.8 | 0.37.1 | 2023-05-31 | ||
6.0.2 | 1.78.6 | 0.37.1 | 2023-05-24 | ||
6.0.1 | 1.78.6 | 0.37.1 | 2023-05-12 | ||
6.0.0 | 1.78.5 | 0.37.1 | 2023-05-04 | ||
5.0.1 | 1.76.6 | 0.36.1 | 2023-04-05 | ||
5.0.0 | 1.76.6 | 0.36.1 | 2023-04-04 | ||
4.0.3 | 1.69.13 | 0.34.1 | |||
4.0.1 | 1.69.12 | 0.34.1 | |||
4.0.0 | 1.69.10 | 0.34.0 | |||
3.0.1 | 1.69.9 | 0.34.0 | |||
3.0.0 | 1.69.0 | 0.34.0 | |||
2.1.0 | 1.67.20 | 0.33.0 | monaco-editor and vscode compatible again | ||
2.0.0 - 2.0.2 | 1.68.4 | 0.33.0 | monaco-editor and vscode incompatible |
Revised the treemending
approach. The postinstall step is removed. monaco-languageclient
no longer patches and existing monaco-editor
instead the package @codingame/monaco-editor-treemended
is used. This requires that projects using this lib have to enforce the correct editor by overrides (npm/pnpm) or resolutions (yarn) in the package.json
.
Updated to monaco-editor
0.43.0
and @codingame/monaco-vscode-api
1.82.2
. initServices
does no longer use dynamic imports. All services available from @codingame/monaco-vscode-api or the own service must be passed to userServices
. All examples have been adapted accordingly.
Updated to @codingame/monaco-vscode-api
1.78.5
and therefore retired MonacoServices
. It is replaced by initServices
that makes configuration of services exposed by @codingame/monaco-vscode-api
handy and still allows the definition of own services as outlined here and these can be passed as userServices
in initServices
.
Both libraries no longer export code from other libraries (vscode-jsonrpc
, vscode-languageclient
and vscode-languageserver-protocol
).
All code has been transformed to esm and npm packages are now of type module. cjs bundles are no longer available.
The monaco-converter
has been removed.
@codingame/monaco-vscode-api was created by CGNonofr and this library is now based on it and the old implementation was removed.
We added the independent vscode-ws-jsonrpc as sub-package into this repository.
From release 1.0.0 onward the project switched to npm workspaces. We no longer require yarn, lerna and webpack. Mostly therefore the list of devDependencies
is substantially shorter. All code has been moved to ./packages directory.
As before the library code is just compiled with the TypeScript compiler and the library is now packaged with npm. The need for bundling does no longer exist for the example. The compiled code is either executed by node or the web/client related code/pages are served with vite.js. We added a verification examples for the web client example using webpack.
The default and protected branch is now main
.
CHANGELOG for monaco-languageclient
is found here
CHANGELOG for vscode-ws-jsonrpc
is found here