目录
1. MonacoEditor 是什么?
2. MonacoEditor 入门基础
2.1. 有基础示例吗?
2.2. 还有个 Webpack 插件?
2.3. 需要什么依赖?
2.4. 怎么初始化?
2.5. 重新布局?
2.6. 监听内容变化?取值?
3. 综合示例
1. MonacoEditor 是什么?
Monaco Editor 是运行在浏览器环境中、为VS Code提供支持的代码编辑器。功能强大而且开源。
- 支持 TypeScript, JavaScript, CSS, LESS, SCSS, JSON, HTML 的智能感知、验证功能
- 多数语言支持的语法着色支持
- 代码差异比较
- 内置三种主题
2. MonacoEditor 入门基础
2.1. 有基础示例吗?
MonacoEditor 提供的官方示例仓库:
代码语言:javascript复制https://github.com/Microsoft/monaco-editor-samples/
2.2. 还有个 Webpack 插件?
MonacoEditor 采用 worker 机制对语法进行异步解析动作,以提升性能。这要求我们需要对 MonacoEditor 需要用到的 worker 进行配置,告诉它我们想用哪几种语法解析策略。
例如:
代码语言:javascript复制// @ts-ignore
self.MonacoEnvironment = {
getWorkerUrl: function (_moduleId: any, label: string) {
if (label === 'json') {
return './json.worker.bundle.js';
}
if (label === 'css' || label === 'scss' || label === 'less') {
return './css.worker.bundle.js';
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return './html.worker.bundle.js';
}
if (label === 'typescript' || label === 'javascript') {
return './ts.worker.bundle.js';
}
return './editor.worker.bundle.js';
}
};
代码语言:javascript复制// webpack.config.js
module.exports = {
mode: 'development',
entry: {
app: './src/index.tsx',
'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js',
'json.worker': 'monaco-editor/esm/vs/language/json/json.worker',
'css.worker': 'monaco-editor/esm/vs/language/css/css.worker',
'html.worker': 'monaco-editor/esm/vs/language/html/html.worker',
'ts.worker': 'monaco-editor/esm/vs/language/typescript/ts.worker'
},
...
}
MonacoEditor 官方的 monaco-editor-webpack-plugin 就能帮你搞定这些麻烦事:
- 自动注入 getWorkerUrl 全局变量
- 处理 worker 的编译配置
- 自动引入控件和语言包
https://github.com/Microsoft/monaco-editor-webpack-plugin
2.3. 需要什么依赖?
- monaco-editor
- monaco-editor-webpack-plugin
2.4. 怎么初始化?
接口:
代码语言:javascript复制export function create(domElement: HTMLElement, options?: IStandaloneEditorConstructionOptions, override?: IEditorOverrideServices): IStandaloneCodeEditor;
示例:
代码语言:javascript复制import React, { useRef, useEffect } from 'react';
import * as monaco from 'monaco-editor';
export const Editor: React.FC = () => {
const divEl = useRef<HTMLDivElement>(null);
let editor: monaco.editor.IStandaloneCodeEditor;
useEffect(() => {
if (divEl.current) {
editor = monaco.editor.create(divEl.current, {
value: ['function x() {', 'tconsole.log("Hello world!");', '}'].join('n'),
language: 'typescript'
});
}
return () => {
editor.dispose();
};
}, []);
return <div className="Editor" ref={divEl}></div>;
};
2.5. 重新布局?
当容器尺寸发生变化的时候(例如:浏览器 resize),需要通过 layout 接口让 MonacoEditor 重新计算布局。
接口:
代码语言:javascript复制export interface IEditor {
/**
* Instructs the editor to remeasure its container. This method should
* be called when the container of the editor gets resized.
*
* If a dimension is passed in, the passed in value will be used.
*/
layout(dimension?: IDimension): void;
}
示例:
代码语言:javascript复制 // autoLayout
useEffect(() => {
const layout = () => {
const editor = editorRef.current;
if (editor) {
editor.layout();
}
};
const debounedLayout = _.debounce(layout, 500);
window.addEventListener("resize", debounedLayout);
return () => {
window.removeEventListener("resize", debounedLayout);
};
}, []);
2.6. 监听内容变化?取值?
接口:
代码语言:javascript复制export interface ICodeEditor extends IEditor {
/**
* An event emitted when the content of the current model has changed.
* @event
*/
onDidChangeModelContent(listener: (e: IModelContentChangedEvent) => void): IDisposable;
onKeyDown(listener: (e: IKeyboardEvent) => void): IDisposable;
}
示例:
代码语言:javascript复制editor.onDidChangeModelContent((e) => {
// 内容变更回调
});
editor.onKeyDown((e) => {
// 按键监听回调
if (e.ctrlKey && e.keyCode === 49) { // Ctrl S
e.preventDefault();
// 。。。。
}
});
3. 综合示例
- 界面参考
- 界面布局:echarts 示例页
- 异常提示:react-live 示例页
- 开发技术
- React、Hook
- 布局方式
- Flex
- 开源组件
- 编辑器:MonacoEditor
- 预览器:ReactLive
参考:
Monaco Editor 官网: https://microsoft.github.io/monaco-editor/index.html https://github.com/Microsoft/monaco-editor https://github.com/Microsoft/monaco-editor-samples/ https://github.com/microsoft/monaco-editor-webpack-plugin react-monaco-editor: https://github.com/react-monaco-editor/react-monaco-editor