Jun 17, 2022

Monaco Editor 简易指南

是什么?

Monaco Editor 是由微软开源的 Web 端编辑器,它在很大程度上支撑了当下最流行的代码编辑器 VSCode。我们只需要在 Web 项目引入 Monaco Editor,就可以获得和 VSCode 接近的编辑体验,同时也支持小地图、代码格式化、语法纠错等各种骚操作。

如何阅读文档

点开 Monaco Editor 的 官网,乍看之下非常简陋,我们甚至无法直接找到如何初始化编辑器!因此在快速上手之前,我会先讲解一下如何阅读 Monaco Editor 的文档。

SPOXtky8z6eFmI4.png

让我们聚焦到官网的导航栏,API DOC 包涵了 Monaco Editor 的全部参数、方法、事件等,以标准的 TypeScript 语法编写;PLAYGROUND 给出了一系列 Demo;MONARCH 则演示了如何自定义语法格式和代码高亮。

点进 API DOC,会看到 Monaco Editor 划分了 editorlanguagesworker 三个 Namespace:

  • editor 包含一切编辑器有关的行为,比如样式、交互等,基本是我们最常用的;
  • languages 包含一切编程语言相关的行为,比如语法高亮、注册一种新的编程语言等;
  • worker 则是 Monaco Editor 启用的各种 Web Worker,比如代码解析工作就会使用 Web Worker 异步执行,不会对编辑器部分造成影响。

5mEbVkLcjqyQZJA.png

个人感觉对于大部分开发者,应该只会用到 editor 里的 API🤣。点击 editor 就可以看到各种 TypeScript 定义了,此处以我们一定会用到的 monaco.editor.create 方法为例,此方法用来初始化一个编辑器实例,点击 create 就可以跳转到对应的方法定义位置。

bVy8mIYouwlvRTj.png

可以看到第一个参数是 HTMLElement,第二个参数是可选的 IStandaloneEditorConstructionOptions

4FGPmLHf1IBDykV.png

点击 IStandaloneEditorConstructionOptions 就会跳转到参数列表,指明编辑器接受哪些参数,以及参数的可选值等。

QaMJ7YRSE3Zugqd.png

而 create 方法返回的是一个 IStandaloneCodeEditor,而它具备的一系列事件里,我们最常用的可能就是 onDidChangeModelContent,编辑器内容变更就会触发此事件。

dXJu2LHv5APFrmx.png

Monaco Editor 的配置项茫茫多,面对千奇百怪的需求时,我们可能很难通过搜索引擎找到适合的解决方案,这种情况下也只能尝试去看懂和理解 API DOC 了。稍后我也会尝试列出一些常用 API。

快速上手

首先安装 Monaco Editor:

npm install monaco-editor // or yarn add monaco-editor

安装完毕后,我们需要找一个具有高度的 dom 容器承载编辑器:

<div id="editor_container" style="height: 600px">

接着初始化编辑器:

import * as monaco from 'monaco-editor'; monaco.editor.create(document.getElementById('editor_container'), { // 此处的配置项几乎与 VSCode 中的一致 automaticLayout: true, scrollBeyondLastLine: true, tabSize: 2, });

此时就能在屏幕上看到最基本的编辑器了~

注意!import * as monaco from 'monaco-editor' 将会引入全部的语言和组件,体积会很大,如果只需要用到编辑器的一部分内容,可以按需引入。

// 单独引入 JSON 语言的 Worker import 'monaco-editor/esm/vs/language/json/json.worker'; // 单独引入查找组件 import 'monaco-editor/esm/vs/editor/contrib/find/browser/findController';

在 Webpack (Vue) 项目中使用

如果我们的项目使用 Webpack 打包,那引入 Monaco Ediotr 后应该会在控制台看到这样的警报。

OBnNDl9iuQry78H.png

这是由于 Webpack 没有引入 Monoca Editor 所需的 WebWorker。上面也提到了 Monaco Editor 为了提高性能,不同语言的语法解析操作都依赖对应的 worker,引入 worker 后编辑器才能实现语法高亮、代码提示等骚操作。

解决方案是我们可以在 Webpack 的 entry 中手动添加 worker,但这种方案比较麻烦,此处不再赘述。更简单的方案是直接使用官方提供的 monaco-editor-webpack-plugin 插件,此处以 VueCli 为例。

首先安装插件:

npm i -D monaco-editor-webpack-plugin // or yarn add -D monaco-editor-webpack-plugin

接着在 vue.config.js 中添加配置:

const { defineConfig } = require('@vue/cli-service'); const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); module.exports = defineConfig({ configureWebpack: { plugins: [ new MonacoWebpackPlugin({ languages: ['javascript', 'css', 'html', 'typescript', 'json'], }), ], }, });

如果我们项目中的编辑器中只需要支持 javascript 和 json,就可以只在数组中保留 ['javascript', 'json'] 两项。同样的,我们也可以自行添加更多 worker,比如 sql,以实现 SQL 语法的高亮和提醒。

编程语言支持

以 JSON 语言为例,当我们成功引入 JSON 语言的 worker 后,就可以开启对 JSON 语言的更多支持。使用起来也非常简单:

let $editor; const jsonModel = monaco.editor.createModel( '', // 初始文本内容 'json', // 语言类型 ); $editor = monaco.editor.create(monacoEditorRef.value, { model: jsonModel, // ... });

此时我们编写 JSON 代码时就可以获得更好的体验了。

Kd7A3Bb8vJ9Yjki.png

常用 API