• home > webfront > visualization > CodeEditor >

    Monaco Editor在线代码编辑器项目应用

    Author:zhoulujun Date:

    Monaco的实现采用worker的方式,事件监听有:onDidChangeOptions 配置改变事件、onDidChangeLanguage 语言改变事件、onDidChangeModelContent 内容改变事件

    官方演示:https://microsoft.github.io/monaco-editor/playground.html#customizing-the-appearence-scrollbars

    官方demo示例:https://microsoft.github.io/monaco-editor/index.html

    git地址:https://github.com/Microsoft/monaco-editor-samples

    知识感觉它的api不好懂,https://microsoft.github.io/monaco-editor/api/index.html

    深入开发难。

    项目实践

    项目中引入monaco-editor

    安装monaco-editor

    npm install monaco-editor -S


    自己的文件中引入monaco

    <div id="monaco"></div>
    <script>
    // 不需要全部引入,只需要引入自己需要使用的功能模块即可。
    import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
    // 引入monaco自身提供了许多种内置语言,比如JavaScript
    import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution';
    // 引入查找控件,使用VSCode一样使用monaco,按下ctrl+f来执行文本查找
    import 'monaco-editor/esm/vs/editor/contrib/find/findController.js';
    const monacoInstance=monaco.editor.create(document.getElementById("monaco"),{
                value:`console.log("hello,world")`,
                language:"javascript"
    })
    monacoInstance.dispose();//使用完成销毁实例
    </script>

    全量版本

    直接引入: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';

    直接引入editor.main.js的话,会自动带上所有的内置语言和控件,可以直接使用,但是会造成前端输出包的体积过大。

    monaco-editor配置

    Monaco的实现采用worker的方式,因为语法解析需要耗费大量时间,所以用worker来异步处理返回结果比较高效。

    monaco-editor-webpack-plugin

    webpack配置

    const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');module.exports=function(){
      return {
        ...
        plugins:[
          new MonacoWebpackPlugin({
             languages:["javascript","css","html","json"],
             features:["coreCommands","find"]
          })
        ]
        // ...
      }}

    插件会帮我们做这么几件事

    1. 自动注入getWorkerUrl全局变量

    2. 处理worker的编译配置

    3. 自动引入控件和语言包。

    具体要引入哪些控件和语言包,我们可以通过配置languages和features来控制。缺省情况下,插件的会引入默认的语言包和控件(所有的控件和语言包),具体可以查看这个地址Microsoft/monaco-editor-webpack-plugin

    Monaco事件绑定

    • onDidChangeOptions 配置改变事件

    • onDidChangeLanguage 语言改变事件

    • onDidChangeModelContent 内容改变事件

    以编辑事件onDidChangeModelContent 为列

    monacoInstance.onDidChangeModelContent((event) => {
     const newValue=monacoInstance.getValue();
     console.log(newValue)
    })

    monacoInstance是一个create方法返回的实例,他包含很多操作实例的方法。event是一个IModelContentChangedEvent对象,他包含了非常非常详细的变更信息,包括操作的类型(撤销、恢复,还是手动输入引发的文本变更),变更的文本位置,变更的文本内容等。

    要获取最新的值,则需要调用:monacoInstance.getValue();

    onDidChangeModelContent,里面有一个Model,这命名可是很讲究的,字面意思就是变更Model内容触发事件,从头到尾,我们都没看到有Model的存在,那么为什么这边是变更Model内容触发事件呢,难道我们操作的是Model?

    是的,其实我们在编辑的时候,就是在Model上编辑,默认情况下,monaco会帮我生成一个Model,我们可以调用getModel打印一下

    monacoInstance.getModel大于结果

    Model其实是一个保存编辑状态的对象,他里面含有语言信息,当前的编辑文本信息,标注信息等。所以我们可以缓存一下Model对象,在需要的时候直接调用setModel即可随时切换到之前的状态。或者也可以在初始化实例的时候设置一个Model。

    const model=monaco.editor.createModel("hahahaha","javascript");
    monacoInstance = monaco.editor.create(this.monacoDom.current, {model:model})

    而且我们可以直接在model上来绑定我们的事件

    model.onDidChangeContent((event)=>{...})


    Model最后也需要我们销毁,这里分两种情况,假如是通过createModel创建的Model,那么我们需要手动销毁,但是如果是monaco默认创建的,则不需要,在调用实例的销毁方法时,会顺带销毁默认创建的Model。

    model.dispose();


    Monaco API思维导图

    API主要分为editor和language,涉及编辑器的操作使用editor提供的API,language主要进行代码程序语言的扩展。

     Monaco API思维导图



    同类文章:

    Monaco Editor 入门指南 https://zhuanlan.zhihu.com/p/88828576

    闲谈Monaco Editor-基本使用 https://zhuanlan.zhihu.com/p/47746336

    基于JavaScript的代码编辑器的比较和选型 https://sq.163yun.com/blog/article/184733100361850880





    转载本站文章《Monaco Editor在线代码编辑器项目应用》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/visualization/webCodeEditor/8561.html