@monaco-editor/react一款不错的代码编辑插件

2,167 阅读3分钟

看看效果

image.png

本文将介绍如何使用monaco-editor。

相关问题:怎么设置中文、因文件大打包慢、解决在线取不到monaco的错误、配置CDN、主题切换、自定义右键菜单。

希望对你有帮助,也是给我自己做笔记。

使用到的版本,附带npm链接

monaco-editor: "^0.48.0"

@monaco-editor/react: "^4.6.0"

monaco-editor-webpack-plugin: "^7.1.0"

先说明@monaco-editor/react的核心是monaco-editor。

而使用@monaco-editor/react时默认使用线上的monaco-editor,通常获取monaco-editor资源又因延时导致报错几率大。

解决办法可以将monaco-editor本地化,这种方式会因为包大导致打包的问题,像我做的项目比较大,再加上使用这么大的包,打包时直接醉了。

也可以将monaco-editor配置到自己的CDN中,取自己服务器上的资源,这是我目前使用的方式,暂时没出现问题。

如果是配置CDN不需要配置monaco-editor-webpack-plugin,也不需要安装monaco-editor,但是要下载一次才能复制到自己服务器。

好。开始

下载依赖包

npm install monaco-editor @monaco-editor/react monaco-editor-webpack-plugin

先说monaco-editor本地化配置

首先配置webpack.config.js

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
{
    plugins:[
        ...,
        new MonacoWebpackPlugin({
        languages: ['json', 'java', 'javascript', 'typescript', 'sql', 'mysql', 'html', 'css', 'xml'], // 加载特定语言支持
    ]
}

案例

import * as monaco from 'monaco-editor';
import Editor, { loader } from '@monaco-editor/react';

// 解决在线取不到monaco的错误
loader.config({
    'vs/nls': { availableLanguages: { '*': 'zh-cn' },// 设置为中文
    paths: { vs: 'node_modules/monaco-editor/min/vs' } },
    monaco 
});

onChange(value){
    this.setState({value: value})
}
<Editor
    height="100%"
    width="100%"
    language="javascript"
    value={this.state.value}
    onChange={this.onChange.bind(this)}
/>

CDN版本的配置

从node_modules中找到monaco-editor文件夹,放在Nginx服务器中。

如果使用create-react-app搭建项目,可以将monaco-editor放在public中,效果是一样的。

案例

import Editor, { loader } from '@monaco-editor/react';
const localBaseUrl = 'http://xxx.xxx.xxx.xxx:xxxx/cdn/monaco-editor/min/vs';
loader.config({ paths: { vs: localBaseUrl },'vs/nls':{ availableLanguages: { '*': 'zh-cn' }}});

onChange(value){
    this.setState({value: value})
}
<Editor
    height="100%"
    width="100%"
    language="javascript"
    value={this.state.value}
    onChange={this.onChange.bind(this)}
/>

主题的设置

import Editor, { loader } from '@monaco-editor/react';
const localBaseUrl = 'http://xxx.xxx.xxx.xxx:xxxx/cdn/monaco-editor/min/vs';
loader.config({ paths: { vs: localBaseUrl }, 'vs/nls': { availableLanguages: { '*': 'zh-cn' } } });
const vs = {
    base: 'vs',
    inherit: true,
    rules: [
        { token: '', foreground: '000000', background: 'ffffff' },
    ],
    colors: {
        'editor.foreground': '#000000',
        'editor.background': '#FFFFFF',
    }
}
const dark = {
    base: 'vs-dark',
    inherit: true,
    rules: [
        { token: '', foreground: 'd4d4d4', background: '1e1e1e' },
    ],
    colors: {
        'editor.foreground': '#D4D4D4',
        'editor.background': '#1E1E1E',
    }
};
handleEditorDidMount(editor, monaco) {
    const { theme } = this.state;
    if (theme === "vs") {
        monaco.editor.setTheme('vs');
        monaco.editor.defineTheme('vs', vs);
    } else {
        monaco.editor.setTheme('dark');
        monaco.editor.defineTheme('dark', dark);
    }
}
<Editor
    height="100%"
    width="100%"
    language="javascript"
    value={this.state.value}
    onMount={this.handleEditorDidMount.bind(this)}
/>

使用CDN获取资源不影响项目的打包速度和包的体积,在我看来优点大于缺点。但是在部署时千万要记得有这一项工作。

右键菜单的设置

一开始没找到汉化配置的时候就是通过重构菜单触发内置事件的方式解决的。

目的达成后,我对菜单研究并不是很多,希望对你有帮助。

import Editor, { loader } from '@monaco-editor/react';
const localBaseUrl = 'http://xxx.xxx.xxx.xxx:xxxx/cdn/monaco-editor/min/vs';
loader.config({ paths: { vs: localBaseUrl }, 'vs/nls': { availableLanguages: { '*': 'zh-cn' } } });

handleEditorDidMount(editor, monaco) {
    this.editor = editor;
    const formatDocument = this.editor.getAction('editor.action.formatDocument');
    formatDocument.label = '格式化文档1' 
    this.editor.addAction(formatDocument) 
        this.editor.addAction({
            id: '1021223', // 菜单项 id
            label: '格式化文档', // 菜单项名称
            keybindings: [2048], // 绑定快捷键
            contextMenuGroupId: '9_cutcopypaste', // 所属菜单的分组
            run: () => {
                // editor.action.formatDocument:格式化整个文档。
                // editor.action.formatSelection:仅格式化选中的代码片段。
                // editor.action.selectAll:全选编辑器内容。
                // editor.action.clipboardCutAction:剪切(Ctrl + X 或 Command + X)。
                // editor.action.clipboardCopyAction:复制(Ctrl + C 或 Command + C)。
                // editor.action.clipboardPasteAction:粘贴(Ctrl + V 或 Command + V)。
                // editor.action.undo:撤销操作(Ctrl + Z 或 Command + Z)。
                // editor.action.redo:重做操作(Ctrl + Y 或 Ctrl + Shift + Z,或 Command + Shift + Z)。
                // editor.action.deleteLines:删除当前行。
                // editor.action.moveLinesDownAction:向下移动当前行。
                // editor.action.moveLinesUpAction:向上移动当前行。
                // editor.action.commentLine:添加 / 移除单行注释。
                // editor.action.addCommentLine:添加单行注释。
                // editor.action.removeCommentLine:移除单行注释。
                const formatDocumentAction = this.editor.getAction('editor.action.formatDocument');
                formatDocumentAction.run();
            }, // 点击后执行的操作
        })  
}
<Editor
    height="100%"
    width="100%"
    language="javascript"
    value={this.state.value}
    onMount={this.handleEditorDidMount.bind(this)}
/>