Ark*_*sky 3 javascript reactjs
我需要创建一个 React 组件,它集成了 Microsoft 的 Monaco 编辑器和 TypeFox 的 monaco-languageclient。目标是让该组件能够通过语言服务器协议与语言服务器进行通信。
import React, { useEffect, useRef, useState } from 'react'
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import _ from 'lodash'
import { listen } from 'vscode-ws-jsonrpc';
import {
CloseAction,
createConnection,
ErrorAction,
MonacoLanguageClient,
MonacoServices
} from 'monaco-languageclient';
import normalizeUrl from 'normalize-url';
import ReconnectingWebSocket from 'reconnecting-websocket';
function createLanguageClient(connection) {
return new MonacoLanguageClient({
name: "Sample Language Client",
clientOptions: {
// use a language id as a document selector
documentSelector: [ 'json' ],
// disable the default error handler
errorHandler: {
error: () => ErrorAction.Continue,
closed: () => CloseAction.DoNotRestart
}
},
// create a language client connection from the JSON RPC connection on demand
connectionProvider: {
get: (errorHandler, closeHandler) => {
return Promise.resolve(createConnection(connection, errorHandler, closeHandler))
}
}
});
}
function createUrl(path) {
// const protocol = 'ws';
return normalizeUrl("ws://localhost:3000/sampleServer")
// return normalizeUrl(`${protocol}://${location.host}${location.pathname}${path}`);
}
function createWebSocket(url) {
const socketOptions = {
maxReconnectionDelay: 10000,
minReconnectionDelay: 1000,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 10000,
maxRetries: Infinity,
debug: false
};
return new ReconnectingWebSocket(url, undefined, socketOptions);
}
const ReactMonacoEditor = ({ initialText, ...props }) => {
let localRef = useRef(null)
const [ value, setValue ] = useState(initialText)
useEffect(() => {
monaco.languages.register({
id: 'json',
extensions: [ '.json', '.bowerrc', '.jshintrc', '.jscsrc', '.eslintrc', '.babelrc' ],
aliases: [ 'JSON', 'json' ],
mimetypes: [ 'application/json' ],
});
const model = monaco.editor.createModel(value, 'json', monaco.Uri.parse('inmemory://model.json'))
const editor = monaco.editor.create(localRef.current, {
model,
glyphMargin: true,
lightbulb: {
enabled: true
}
});
editor.onDidChangeModelContent(_.debounce(e => {
setValue(editor.getValue())
}, 100))
MonacoServices.install(editor);
// create the web socket
const url = createUrl('/sampleSer ver')
const webSocket = createWebSocket(url);
// listen when the web socket is opened
listen({
webSocket,
onConnection: connection => {
// create and start the language client
const languageClient = createLanguageClient(connection);
const disposable = languageClient.start();
connection.onClose(() => disposable.dispose());
}
});
return () => editor.dispose()
}, [])
return (
<div ref={localRef} style={{ width: 800, height: 600 }}/>
)
}
export default ReactMonacoEditor
Run Code Online (Sandbox Code Playgroud)
包.json
import React, { useEffect, useRef, useState } from 'react'
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import _ from 'lodash'
import { listen } from 'vscode-ws-jsonrpc';
import {
CloseAction,
createConnection,
ErrorAction,
MonacoLanguageClient,
MonacoServices
} from 'monaco-languageclient';
import normalizeUrl from 'normalize-url';
import ReconnectingWebSocket from 'reconnecting-websocket';
function createLanguageClient(connection) {
return new MonacoLanguageClient({
name: "Sample Language Client",
clientOptions: {
// use a language id as a document selector
documentSelector: [ 'json' ],
// disable the default error handler
errorHandler: {
error: () => ErrorAction.Continue,
closed: () => CloseAction.DoNotRestart
}
},
// create a language client connection from the JSON RPC connection on demand
connectionProvider: {
get: (errorHandler, closeHandler) => {
return Promise.resolve(createConnection(connection, errorHandler, closeHandler))
}
}
});
}
function createUrl(path) {
// const protocol = 'ws';
return normalizeUrl("ws://localhost:3000/sampleServer")
// return normalizeUrl(`${protocol}://${location.host}${location.pathname}${path}`);
}
function createWebSocket(url) {
const socketOptions = {
maxReconnectionDelay: 10000,
minReconnectionDelay: 1000,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 10000,
maxRetries: Infinity,
debug: false
};
return new ReconnectingWebSocket(url, undefined, socketOptions);
}
const ReactMonacoEditor = ({ initialText, ...props }) => {
let localRef = useRef(null)
const [ value, setValue ] = useState(initialText)
useEffect(() => {
monaco.languages.register({
id: 'json',
extensions: [ '.json', '.bowerrc', '.jshintrc', '.jscsrc', '.eslintrc', '.babelrc' ],
aliases: [ 'JSON', 'json' ],
mimetypes: [ 'application/json' ],
});
const model = monaco.editor.createModel(value, 'json', monaco.Uri.parse('inmemory://model.json'))
const editor = monaco.editor.create(localRef.current, {
model,
glyphMargin: true,
lightbulb: {
enabled: true
}
});
editor.onDidChangeModelContent(_.debounce(e => {
setValue(editor.getValue())
}, 100))
MonacoServices.install(editor);
// create the web socket
const url = createUrl('/sampleSer ver')
const webSocket = createWebSocket(url);
// listen when the web socket is opened
listen({
webSocket,
onConnection: connection => {
// create and start the language client
const languageClient = createLanguageClient(connection);
const disposable = languageClient.start();
connection.onClose(() => disposable.dispose());
}
});
return () => editor.dispose()
}, [])
return (
<div ref={localRef} style={{ width: 800, height: 600 }}/>
)
}
export default ReactMonacoEditor
Run Code Online (Sandbox Code Playgroud)
我期待组件呈现。相反,我得到
Failed to compile.
./node_modules/vscode-base-languageclient/lib/workspaceFolders.js
Module not found: Can't resolve 'vscode' in '.../node_modules/vscode-base-languageclient/lib'
Waiting for the debugger to disconnect...
Run Code Online (Sandbox Code Playgroud)
不知道如何继续。
小智 7
几个小时以来,我一直在为同样的问题苦苦挣扎。最终我在 monaco-languageclient的更新日志中发现了以下评论:
vscode-compatibility 应该在运行时用作 vscode 模块的实现。使用 webpack 调整模块分辨率:
解决:{别名:{'vscode':require.resolve('monaco-languageclient/lib/vscode-compatibility')}}
将该别名添加到我的 webpack 配置(在我的情况下为 quasar.conf)后,编译成功。
因此,事实上 monaco-languageclient 并不像错误消息所暗示的那样依赖于 vscode 模块,而是应该使用包本身内部的兼容性存根。
| 归档时间: |
|
| 查看次数: |
1266 次 |
| 最近记录: |