monaco-languageclient icon indicating copy to clipboard operation
monaco-languageclient copied to clipboard

How to integrate with Angular?

Open lcnandre opened this issue 6 years ago • 20 comments

Hello.

I'm currently trying to put together monaco-languageclient along with vscode-ws-jsonrpc on an Angular 6.x project using ngx-monaco-editor component but without much luck.

Here's how my code looks like:

import { Component, Input } from '@angular/core';
import {
  BaseLanguageClient,
  CloseAction,
  ErrorAction,
  MonacoServices,
  MonacoLanguageClient,
  createConnection,
} from 'monaco-languageclient';
import { listen } from 'vscode-ws-jsonrpc';
import { finalize } from 'rxjs/operators';
const ReconnectingWebSocket = require('reconnecting-websocket');

@Component({
  selector: 'script-csharp',
  templateUrl: './script-csharp.component.html',
  styleUrls: ['./script-csharp.component.css'],
})
export class ScriptCsharpComponent {
  file: NgxEditorModel = {
    uri: 'File.cs',
    language: 'csharp',
    value: '',
  };

  config: any = {
    theme: 'vs-dark',
    language: 'csharp',
    lineNumbers: 'on',
    glyphMargin: true,
    lightbulb: {
      enabled: true,
    },
  };

  onMonacoInit(editor: any) {
    const url = `ws://example.com`;
    const webSocket = this.createWebSocket(url);

    MonacoServices.install(editor);

    listen({
      webSocket,
      onConnection: connection => {
        const languageClient = this.createLanguageClient(connection);
        const disposable = languageClient.start();
        connection.onClose(() => disposable.dispose());
      },
    });
  }

  private createWebSocket(url: string) {
    return new ReconnectingWebSocket(url, undefined, {
      maxReconnectionDelay: 10000,
      minReconnectionDelay: 1000,
      reconnectionDelayGrowFactor: 1.3,
      connectionTimeout: 10000,
      maxRetries: Infinity,
      debug: false,
    });
  }

  private createLanguageClient(connection: any): BaseLanguageClient {
    return new MonacoLanguageClient({
      name: 'C# Client',
      clientOptions: {
        documentSelector: ['csharp'],
        errorHandler: {
          error: () => ErrorAction.Continue,
          closed: () => CloseAction.DoNotRestart,
        },
      },
      connectionProvider: {
        get: (errorHandler, closeHander) => {
          return Promise.resolve(
            createConnection(connection, errorHandler, closeHander)
          );
        },
      },
    });
  }
}

And here's a list of the major erros I'm getting:

ERROR in node_modules/monaco-languageclient/lib/monaco-converter.d.ts(1,23): error TS2688: Cannot find type definition file for 'monaco-editor-core/monaco'.

node_modules/monaco-languageclient/lib/monaco-converter.d.ts(98,63): error TS2694: Namespace 'monaco.languages' has no exported member 'DocumentSymbol'.


node_modules/vscode-base-languageclient/lib/client.d.ts(1,884): error TS2307: Cannot find module 'vscode'.


node_modules/vscode-ws-jsonrpc/lib/index.d.ts(2,1): error TS2308: Module 'vscode-jsonrpc' has already exported a member named 'ErrorCodes'. Consider explicitly re-exporting to resolve the ambiguity.

I'm stuck with this for a week now and would apreciate any kind of help.

lcnandre avatar Jan 18 '19 18:01 lcnandre

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Mar 19 '19 18:03 stale[bot]

Hello I have just faced with the same problem. Have you tried exclude ngx-monaco-editor and add monaco-editor-core to avoid conflicts?

alexander-makarevich avatar Aug 28 '19 11:08 alexander-makarevich

@alexander-makarevich , in your tsconfig.json add "skipLibCheck": true.

Louis-7 avatar Dec 24 '19 09:12 Louis-7

I've updated my example to show how to integrate monaco-languaeclient with Angular

Louis-7 avatar Dec 25 '19 03:12 Louis-7

I've updated my example to show how to integrate monaco-languaeclient with Angular

can you please update your repo? I'm stuck with error: An unhandled exception occurred: context.getProjectMetadata is not a function/ https://github.com/manfredsteyer/ngx-build-plus/issues/164

Androsid avatar Mar 11 '20 08:03 Androsid

@Androsid , can provide more details? Are you using Angular 9? Maybe you should raise another issue to track it.

Louis-7 avatar Mar 11 '20 08:03 Louis-7

@Androsid , can provide more details? Are you using Angular 9? Maybe you should raise another issue to track it.

yes. i'm using angular 9 in my project, but in your project I did not raise the versions. "skipLibCheck": true does not fix my problem

I just Install from the repository: git clone https://github.com/Louis-7/angular-monaco-languageclient.git

Install dependencies: npm install

and start your project with npm start

Androsid avatar Mar 11 '20 10:03 Androsid

@lcnandre Could you please share some details about csharp LSP implementation.

sreekarsudireddy avatar Mar 12 '20 18:03 sreekarsudireddy

Has anyone successfully integrated this in React?

vardanbansal-harness avatar Jun 02 '20 10:06 vardanbansal-harness

Successfully integrated this with Angular 10.

Steps:

  • Used this to load Monaco Editor Core 0.30.1 - https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-amd.md. Added node_modules/monaco-editor-core to assets in angular.json for building this as an asset on server.
  • Added monaco-languageclient 0.17.3 and other dependencies highlighted in example package.json
  • Used https://www.npmjs.com/package/@angular-builders/custom-webpack 10.0.0 to provide an extra webpack config for adding resolve alias by referring to example in monaco-languageclient library. Use required version of angular-builder by referring to your project's Angular version.

Rest used the client.ts example in the example folder.

kalraDikshit avatar Mar 08 '22 13:03 kalraDikshit

@kalraDikshit I'm trying to integrate it with Angular 11. Can you share your repository?

bguo3 avatar Mar 11 '22 01:03 bguo3

@kalraDikshit sorry, just to clarify, did you use the browser example or the regular example? I'm a bit confused to what the difference is between the 2.

rogerfar avatar Mar 24 '22 18:03 rogerfar

I have this part of code in my Angular app:

public onEditorInit(editor: any): void {
    // install Monaco language client services
    MonacoServices.install(editor);

    // create the web socket
    const url = this.createUrl('localhost', 3000, '/');
    const webSocket = new WebSocket(url);

    webSocket.onopen = () => {
      const socket = toSocket(webSocket);
      const reader = new WebSocketMessageReader(socket);
      const writer = new WebSocketMessageWriter(socket);
      const languageClient = this.createLanguageClient({
        reader,
        writer
      });
      languageClient.start();
      reader.onClose(() => languageClient.stop());
    };
  }

  private createUrl (hostname: string, port: number, path: string): string {
    const protocol = location.protocol === 'https:' ? 'wss' : 'ws';
    return `${protocol}://${hostname}:${port}${path}`;
}

  private createLanguageClient (transports: MessageTransports): MonacoLanguageClient {
    return new MonacoLanguageClient({
      name: 'Sample Language Client',
      clientOptions: {
        // use a language id as a document selector
        documentSelector: ['typescript'],
        // disable the default error handler
        errorHandler: {
          error: () => ({ action: ErrorAction.Continue }),
          closed: () => ({ action: CloseAction.DoNotRestart })
        }
      },
      // create a language client connection from the JSON RPC connection on demand
      connectionProvider: {
        get: () => {
          return Promise.resolve(transports);
        }
      }
    });
  }

When I run application I get this list of errors:

ERROR in node_modules/vscode/dist/services.d.ts:11790:5 - error TS1131: Property or signature expected.

11790 get hasSaveParticipants(): boolean; ~~~ node_modules/vscode/dist/services.d.ts:11790:9 - error TS1005: ';' expected.

11790 get hasSaveParticipants(): boolean; ~~~~~~~~~~~~~~~~~~~ node_modules/vscode/dist/services.d.ts:11790:30 - error TS1005: ';' expected.

11790 get hasSaveParticipants(): boolean; ~ node_modules/vscode/dist/services.d.ts:11794:35 - error TS1005: ',' expected.

11794 addSaveParticipant(participant: IStoredFileWorkingCopySaveParticipant): IDisposable; ~ node_modules/vscode/dist/services.d.ts:11794:75 - error TS1005: ';' expected.

11794 addSaveParticipant(participant: IStoredFileWorkingCopySaveParticipant): IDisposable; ~ node_modules/vscode/dist/services.d.ts:11798:36 - error TS1005: ',' expected.

11798 runSaveParticipants(workingCopy: IStoredFileWorkingCopy<IStoredFileWorkingCopyModel>, context: { ~ node_modules/vscode/dist/services.d.ts:11798:89 - error TS1109: Expression expected.

11798 runSaveParticipants(workingCopy: IStoredFileWorkingCopy<IStoredFileWorkingCopyModel>, context: { ~ node_modules/vscode/dist/services.d.ts:11798:98 - error TS1005: ',' expected.

11798 runSaveParticipants(workingCopy: IStoredFileWorkingCopy<IStoredFileWorkingCopyModel>, context: { ~ node_modules/vscode/dist/services.d.ts:11799:27 - error TS1005: ',' expected.

11799 reason: SaveReason; ~ node_modules/vscode/dist/services.d.ts:11800:13 - error TS1005: ',' expected.

11800 }, token: CancellationToken): Promise; ~ node_modules/vscode/dist/services.d.ts:11800:33 - error TS1005: ';' expected.

11800 }, token: CancellationToken): Promise; ~ node_modules/vscode/dist/services.d.ts:11800:48 - error TS1005: '(' expected.

11800 }, token: CancellationToken): Promise; ~ node_modules/vscode/dist/services.d.ts:11807:22 - error TS1005: ',' expected.

11807 create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11807:45 - error TS1011: An element access expression should take an argument.

11807 create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>;

node_modules/vscode/dist/services.d.ts:11807:53 - error TS1005: ',' expected.

11807 create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11807:83 - error TS1109: Expression expected.

11807 create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11807:112 - error TS1005: ';' expected.

11807 create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11807:155 - error TS1005: '(' expected.

11807 create(operations: ICreateFileOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11817:28 - error TS1005: ',' expected.

11817 createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11817:47 - error TS1011: An element access expression should take an argument.

11817 createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>;

node_modules/vscode/dist/services.d.ts:11817:55 - error TS1005: ',' expected.

11817 createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11817:85 - error TS1109: Expression expected.

11817 createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11817:114 - error TS1005: ';' expected.

11817 createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11817:157 - error TS1005: '(' expected.

11817 createFolder(operations: ICreateOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11825:20 - error TS1005: ',' expected.

11825 move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11825:37 - error TS1011: An element access expression should take an argument.

11825 move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>;

node_modules/vscode/dist/services.d.ts:11825:45 - error TS1005: ',' expected.

11825 move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11825:75 - error TS1109: Expression expected.

11825 move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11825:104 - error TS1005: ';' expected.

11825 move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11825:147 - error TS1005: '(' expected.

11825 move(operations: IMoveOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11833:20 - error TS1005: ',' expected.

11833 copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11833:37 - error TS1011: An element access expression should take an argument.

11833 copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>;

node_modules/vscode/dist/services.d.ts:11833:45 - error TS1005: ',' expected.

11833 copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11833:75 - error TS1109: Expression expected.

11833 copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11833:104 - error TS1005: ';' expected.

11833 copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11833:147 - error TS1005: '(' expected.

11833 copy(operations: ICopyOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise<readonly IFileStatWithMetadata[]>; ~ node_modules/vscode/dist/services.d.ts:11841:22 - error TS1005: ')' expected.

11841 delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise; ~ node_modules/vscode/dist/services.d.ts:11841:41 - error TS1011: An element access expression should take an argument.

11841 delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise;

node_modules/vscode/dist/services.d.ts:11841:49 - error TS1005: ';' expected.

11841 delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise; ~ node_modules/vscode/dist/services.d.ts:11841:79 - error TS1109: Expression expected.

11841 delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise; ~ node_modules/vscode/dist/services.d.ts:11841:107 - error TS1005: ';' expected.

11841 delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise; ~ node_modules/vscode/dist/services.d.ts:11841:108 - error TS1128: Declaration or statement expected.

11841 delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise; ~ node_modules/vscode/dist/services.d.ts:11841:123 - error TS1005: '(' expected.

11841 delete(operations: IDeleteOperation[], token: CancellationToken, undoInfo?: IFileOperationUndoRedoInfo): Promise; ~ node_modules/vscode/dist/services.d.ts:11847:41 - error TS1005: ',' expected.

11847 registerWorkingCopyProvider(provider: WorkingCopyProvider): IDisposable; ~ node_modules/vscode/dist/services.d.ts:11847:63 - error TS1005: ';' expected.

11847 registerWorkingCopyProvider(provider: WorkingCopyProvider): IDisposable; ~ node_modules/vscode/dist/services.d.ts:11853:22 - error TS1005: ',' expected.

11853 getDirty(resource: URI): readonly IWorkingCopy[]; ~ node_modules/vscode/dist/services.d.ts:11853:28 - error TS1005: ';' expected.

11853 getDirty(resource: URI): readonly IWorkingCopy[]; ~ node_modules/vscode/dist/services.d.ts:11853:30 - error TS1128: Declaration or statement expected.

11853 getDirty(resource: URI): readonly IWorkingCopy[]; ~~~~~~~~ node_modules/vscode/dist/services.d.ts:11853:52 - error TS1011: An element access expression should take an argument.

11853 getDirty(resource: URI): readonly IWorkingCopy[];

node_modules/vscode/dist/services.d.ts:11854:1 - error TS1128: Declaration or statement expected.

11854 } ~ src/app/client/src/monaco-language-client.ts:80:24 - error TS1005: ';' expected.

80 protected override registerBuiltinFeatures () { ~~~~~~~~~~~~~~~~~~~~~~~

Can someone help with this errors? I do not know what is wrong, am I doing something wrong or there is problem with installed modules?

vm381 avatar Aug 24 '22 15:08 vm381

You seem to use a VERY old version of the library

CGNonofr avatar Aug 24 '22 15:08 CGNonofr

Which is newest one? I installed latest dependencies for monaco-languageclient and vscode-ws-jsonrpc. The code example I took from examples of this repository.

"monaco-languageclient": "^3.0.1",
"vscode-ws-jsonrpc": "^1.0.2",

vm381 avatar Aug 24 '22 15:08 vm381

Then you are using the last version but you use it as it's an old version, where does that code come from? refer to the provided examples

CGNonofr avatar Aug 24 '22 15:08 CGNonofr

I found the code here https://github.com/TypeFox/monaco-languageclient/blob/main/packages/examples/client/src/client.ts

vm381 avatar Aug 24 '22 15:08 vm381

MonacoServices.install doesn't take the editor as parameter, so no, the code doesn't come from there

Btw, you have very weird typescript error in d.ts files, are you using a old typescript?

CGNonofr avatar Aug 24 '22 15:08 CGNonofr

I added that parameter, it gives the same result if I remove it. I use TS 3.9 and Angular 10.

vm381 avatar Aug 24 '22 15:08 vm381

typescript 3.9 is more than 2 years old

CGNonofr avatar Aug 24 '22 15:08 CGNonofr

We plan to add an Angular example here and therefore opened this issue: https://github.com/TypeFox/monaco-languageclient/issues/414

kaisalmen avatar Oct 19 '22 07:10 kaisalmen