转自 : https://zhuanlan.zhihu.com/p/47746336
什么是Monaco Editor?
微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VSCode,而Monaco Editor(下文简称monaco)就是从这个项目中成长出来的一个web编辑器,他们很大一部分的代码(monaco-editor-core)都是共用的,所以monaco和VSCode在编辑代码,交互以及UI上几乎是一摸一样的,有点不同的是,两者的平台不一样,monaco基于浏览器,而VSCode基于electron,所以功能上VSCode更加健全,并且性能比较强大。
开始使用
本文采用的是webpack编译,所以以下都是基于webpack来说明。
基本功能
首先,我们需要安装monaco
npm install monaco-editor -S
然后在自己的文件中引入monaco,这里不需要全部引入,只需要引入自己需要使用的功能模块即可。
HTML
<div id="monaco">
</div>
JS
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
const monacoInstance=monaco.editor.create(document.getElementById("monaco"),{
value:`console.log("hello,world")`,
language:"javascript"
})
monacoInstance.dispose();//使用完成销毁实例
我们设置了语言为javascript,界面是出来了,但是却发现没有语法高亮,输入命令发现其实根本没有javascript语言,只有一个最基础的plaintext。
所以我们还需要再定义一个javascript语言,但是定义一门语言并不是一件很容易的事情,幸好,monaco自身提供了许多种内置语言,我们只需要引入即可。
import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution';
引入完成,再次查看界面,发现已经有了语法高亮。
这时,我们可以尝试像使用VSCode一样使用monaco,按下ctrl+f来执行文本查找,我们会发现出来的不是monaco的查找控件,而是浏览器的,因此我们需要引入查找控件。
import 'monaco-editor/esm/vs/editor/contrib/find/findController.js';
再次尝试查找,出来的已经是monaco的查找控件啦。
monaco还有许多这类控件,我们可以按需引入自己用到的。
不过有一个更加简便的方法,那就是直接引入main文件来代替api文件。
import * as monaco from 'monaco-editor/esm/vs/editor/editor.main.js';
点开文件,我们可以看到
editor.main.js
import '../language/typescript/monaco.contribution';
import '../language/css/monaco.contribution';
import '../language/json/monaco.contribution';
import '../language/html/monaco.contribution';
import '../basic-languages/monaco.contribution';
export * from './edcore.main';
采用这种方式引入的话,会自动带上所有的内置语言和控件,唯一的缺点就是包的体积过大。
目前为止,我们已经实现了一个可以输入,高亮,查找的web编辑器,但是,和VSCode比较起来,还少了许多重要的功能,例如代码补全,错误提示以及快捷命令功能等。
增加代码提示
export default function (monaco) {
// 创建代码提醒
monaco.languages.registerCompletionItemProvider('xxx_name', {
provideCompletionItems: function (model, position) {
// find out if we are completing a property in the 'dependencies' object.
var textUntilPosition = model.getValueInRange({
startLineNumber: 1,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column
});
var suggestions = [];
var word = model.getWordUntilPosition(position);
var range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn
};
// console.log(textUntilPosition, range, word);
if (textUntilPosition.charAt(textUntilPosition.length - 2) == '.') {
suggestions = [{
label: "lenth",
insertText: "length"
}];
}
return { suggestions: suggestions };
}
});
}
结尾
本文重点在于介绍monaco的基本设计和使用,代码细节部分不是很详细,如果有疑问,可以翻阅monaco的官方文档。谢谢~