前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【MonacoEditor】:VSCode 代码编辑器

【MonacoEditor】:VSCode 代码编辑器

作者头像
WEBJ2EE
发布2021-02-26 16:05:24
发布2021-02-26 16:05:24
4K00
代码可运行
举报
文章被收录于专栏:WebJ2EEWebJ2EE
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
复制
目录
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
代码运行次数:0
运行
复制
https://github.com/Microsoft/monaco-editor-samples/

2.2. 还有个 Webpack 插件?

MonacoEditor 采用 worker 机制对语法进行异步解析动作,以提升性能。这要求我们需要对 MonacoEditor 需要用到的 worker 进行配置,告诉它我们想用哪几种语法解析策略。

例如:

代码语言:javascript
代码运行次数:0
运行
复制
// @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
代码运行次数:0
运行
复制
// 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 的编译配置
  • 自动引入控件和语言包
代码语言:javascript
代码运行次数:0
运行
复制
https://github.com/Microsoft/monaco-editor-webpack-plugin

2.3. 需要什么依赖?

  • monaco-editor
  • monaco-editor-webpack-plugin

2.4. 怎么初始化?

接口:

代码语言:javascript
代码运行次数:0
运行
复制
export function create(domElement: HTMLElement, options?: IStandaloneEditorConstructionOptions, override?: IEditorOverrideServices): IStandaloneCodeEditor;

示例:

代码语言:javascript
代码运行次数:0
运行
复制
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
代码运行次数:0
运行
复制
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
代码运行次数:0
运行
复制
  // 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
代码运行次数:0
运行
复制
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
代码运行次数:0
运行
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档