web代码编辑器有哪些,WEB代码编辑器哪家强

作为一名coder,像VS Code这样的代码编辑器自然是必不可少的,你还可以使用类似CodeSandbox这样的online编辑器开发demo程序。编辑器更多是作为工具方便我们进行日常的代码开发工作,倘若将编辑器视作产品的一部分为其提供可扩展的能力,我们该如何应对。答案是:web编辑器,现在热门的可视化页面搭建系统便是一个典型的案例。

今天要介绍的是三款开源的主流web编辑器:
Ace
CodeMirror
Monaco Editor

前世今生

Ace是来自Ajax.org Cloud9 Editor的一个独立的代码编辑器,它的前身是Bespin和后来的Skywriter。这两者最开始走的路线不一样,Bespin基于canvas,Ace基于DOM。Ace发布于2010年,之后Skywriter团队将Skywriter的插件系统和可扩展性融合到了Ace中,便形成了现在的Ace编辑器。现在,Ajax.org和Mozilla都在积极的开发和维护Ace。

CodeMirror的第一版于2007年发布,该版本基于浏览器的contentEditable属性实现。2010年发布的Ace采用了新的技术并证明即使是使用javascript操作数以千行的DOM也不存在性能问题,这驱使了CodeMirror的重构并发布了第二个版本,弃用了之前的contentEditable,性能得到了很大提升。如今,CodeMirror即将发布最新的重构版本6。

Monaco Editor算是后起之秀,随着2015年VS Code的发布而诞生,它与VS Code使用同样的核心代码。

快速开始

这里以不引入任何框架的,纯粹的html+css+js形式展示三类编辑器的使用。

Ace

官方示例


function foo(items) { var i; for (i = 0; i < items.length; i++) { alert("Ace Rocks " + items[i]); } }


    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/twilight");
    editor.session.setMode("ace/mode/javascript");

这里承载编辑器内容的html标签是pre,实际开发中并不常见,可以替换成div。
注意ace的引用方式。ace-builds repository是ace的最新发布包,直接将src* 子目录拷贝到项目中即可使用,发布包总共有四个版本。

  • src (完整版本)
  • src-min (压缩版本)
  • src-noconflict (ace.require完整版本)
  • src-min-noconflict (ace.require压缩版本) 当然我们也可以自行打包,从github仓库拉取源码,执行下面的脚本。
    npm install
    node ./Makefile.dryice.js
    
    于是就得到了完整的版本,即上述四个版本中的第一个,还可以通过脚本选项生成另外三个版本或是指定输出目录。

    CodeMirror

    直接下载zip文件并拷贝到项目中即可使用。 ```html
  // 方式1
  var ele = document.getElementById("editor");
  var editor = CodeMirror.fromTextArea(ele, {
    lineNumbers: true,
    mode: "javascript"
  });
  editor.setValue("var a = 'hello world';")
  // 方式2
  var editor2 = CodeMirror(document.getElementById("editor2"), {
    lineNumbers: true,
    value: "console.log('hello world');",
    mode: "javascript"
  })
这里有两种方式创建编辑器,fromTextArea的方式具有一些额外的特性。[详情戳这里](https://codemirror.net/doc/manual.html#fromTextArea)
### Monaco Editor
通过npm安装

npm install monaco-editor

安装完成后生成三个版本。
- esm    (es模块化版本,兼容webpack)
- dev    (完整的amd模块化版本)
- min    (压缩的amd模块化版本)
另外还有一个min版本的source maps文件夹和一个编辑器api描述文件monaco.d.ts  
[AMD版本的官方示例](https://github.com/microsoft/monaco-editor/blob/master/docs/integrate-amd.md)
```html

## Monaco Editor Sample

 

 
    
 
      require.config({ paths: { vs: "../node_modules/monaco-editor/min/vs" } });

      require(["vs/editor/editor.main"], function () {
        var editor = monaco.editor.create(
          document.getElementById("container"),
          {
            value: [
              "function x() {",
              '\tconsole.log("Hello world!");',
              "}",
            ].join("\n"),
            language: "javascript",
          }
        );
      });

实际项目基本都是基于前端框架开发,下面就以Vue为例介绍三类编辑器的使用。

在Vue项目中的使用

Ace

  • 安装

    npm install ace-builds
    
  • 引入

    import ace from "ace-builds"
    

    实际使用过程中我们一般都会指定代码的语言类型,还有可能修改编辑器的默认样式。这样的话,我们还需要引入相关的语言类型文件和主题文件。

    import "ace-builds/src-noconflict/mode-javascript.js"
    import "ace-builds/src-noconflict/theme-tomorrow.js"
    

    但是,如果我们想动态切换语言类型或是主题,是不是应该把对应的js文件全部引入呢?Ace为我们提供了更简洁的方法。

    import "ace-builds/webpack-resolver"
    

    这样就完成了语言类型和主题的动态加载,前提是项目基于webpack构建的。

  • 常用api 设置主题

    myEditor.setTheme("ace/theme/tomorrow")
    

    设置语言类型

    // 一个editor可能存在多个session
    myEditor.session.setMode("ace/mode/javascript")
    myEditor.setMode("ace/mode/javascript")
    

    设置/获取值

    myEditor.setValue("the new text here")
    myEditor.session.setValue("the new text here")
    myEditor.getValue() // or session.getValue
    

    设置tab大小

    myEditor.session.setTabSize(4)
    

    是否只读

    myEditor.setReadOnly(true)    // false可编辑
    

    当我们要设置多个属性值时,除了单独调用每个api,还可以使用下面这种方式。

    myEditor.setOptions({
    mode: "ace/mode/javascript",
    theme: "ace/theme/tomorrow",
    value: "hello world"
    })
    

    有了这些常用的api,编辑器基本成型了。可以参考官网或是源码ace.d.ts查看全部的接口。

  • 高级特性 Ace自带语法检查功能,目前支持JavaScript, JSON, PHP, CoffeeScript, CSS, XQuery,XML,HTML。
    效果如下:

    除了语法检查,还可以设置代码提示和自动补全。只需要引入语言构建扩展,并设置相关属性即可。 ```js import "ace-builds/src-noconflict/ext-language_tools"

myEditor.setOptions({ enableBasicAutocompletion: true, enableSnippets: true, enableLiveAutocompletion: true, });

效果如下:   
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c53109dafeeb498b9a388e82714c060f~tplv-k3u1fbpfcp-watermark.image)  
图中的提示及补全片段都可以在[源码](https://github.com/ajaxorg/ace-builds/blob/master/src-noconflict/snippets/javascript.js)中找到,我们可以按照源码中的语法添加自定义的提示及补全片段信息。  

### CodeMirror
- 安装

npm install codemirror

- 引入
```js
import CodeMirror from "codemirror/lib/codemirror.js"
import "codemirror/lib/codemirror.css"

同样,对于主题和语言类型也需要引入相应的文件。

import "codemirror/theme/material.css"
import "codemirror/mode/javascript/javascript.js"
  • 常用api 设置属性
    myEditor.setOption("mode", "text/javascript")
    myEditor.setOption("value", "hello world")
    
    设置/获取值
    myEditor.getValue()
    myEditor.setValue("hello world")
    
  • 高级特性 CodeMirror默认是没有语法检查功能的,需要利用插件addon进行扩展。
    import "codemirror/addon/lint/lint.css"
    import "codemirror/addon/lint/lint.js"
    import "codemirror/addon/lint/javascript-lint.js"
    this.editor = CodeMirror.fromTextArea(this.$refs.editor, {
    mode: "text/javascript",
    gutters: ["CodeMirror-lint-markers"],
    lint: true
    })
    
    另外还需要引入语言对应的检查工具,可以在项目的index.html中引入。 ```html
效果如下。  
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/83de7dee7023465c902cdc8b92ab8581~tplv-k3u1fbpfcp-watermark.image)   
代码提示和智能补全,需要引入相关插件,设置属性并绑定快捷键触发。
```js
import "codemirror/addon/hint/show-hint.js"
import "codemirror/addon/hint/show-hint.css"
import "codemirror/addon/hint/javascript-hint.js"
myEditor = CodeMirror.fromTextArea(this.$refs.editor, {
  mode: "text/javascript",
  extraKeys: { "Ctrl-Enter": "autocomplete", "Cmd-Enter": "autocomplete" }
})
CodeMirror.commands.autocomplete = function (cm) {
  cm.showHint({ hint: CodeMirror.hint.javascript });
}

这里分别定义了windows和mac系统下触发代码提示和智能补全的组合键,Ctrl+Enter Cmd+Enter。效果如下。
CodeMirror支持diff模式,需要引入的插件及实现如下。

import "codemirror/addon/merge/merge.css"
import "codemirror/addon/merge/merge.js"

const orig1 = `import Vue from 'vue'
import App from './App.vue'\n

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')`;

const orig2 = `import Vue from "vue";
import Vuex from "vuex";
import App from "./App.vue";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";

Vue.config.productionTip = false;

Vue.use(ElementUI);
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    tabName: "",
  },
  mutations: {
    changeTab(state, tabName) {
      state.tabName = tabName;
    },
  },
});

new Vue({
  render: (h) => h(App),
  store: store,
}).$mount("#app");`;

myDiffEditor = CodeMirror.MergeView(
  document.getElementById("view"),
  {
    value: orig1,
    origLeft: null,
    orig: orig2,
    lineNumbers: true,
    mode: "text/javascript",
    highlightDifferences: true,
    connect: true,
    collapseIdentical: false
  }
);

diff功能需要依赖diff-match-patch开源库来计算差异。


最终效果如下。

Monaco Editor

  • 安装
    npm install monaco-editor
    
    此外,还需要安装配套的webpack插件。
    npm install monaco-editor-webpack-plugin
    
    在vue.config.js中添加插件。 ```js const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');

module.exports = { configureWebpack: { plugins: [ new MonacoWebpackPlugin() ] } }

- 引入
```js
import * as monaco from "monaco-editor"
  • 常用api 设置语言类型
    const model = myEditor.getModel()
    monaco.editor.setModelLanuage(model, "javascript")
    
    设置主题
    monaco editor自带三种主题,默认的"vs"及"vs-dark"、"hc-black"。
    monaco.editor.setTheme("vs-dark")
    
    设置属性
    例如,readOnly(是否只读)、renderLineHighlight(高亮行)、lineNumbers(是否显示行号)、fontSize(字体大小)等。
    myEditor.updateOptions({
    [name]: value    // name表示属性名称,value为对应的属性值
    })
    
    这里仅列举了部分属性,完整的请参考官网或是源码monaco.d.ts。官网还提供了丰富的示例
  • 高级特性 monaco editor默认支持TypeScript, JavaScript, CSS, LESS, SCSS, JSON, HTML的语法校验及智能提示补全功能。效果如下。

    和桌面端的vscode没有任何区别。
    再看diff模式。
    ```js const originalModel = monaco.editor.createModel(
        `import Vue from 'vue'
    
    import App from './App.vue'\n

Vue.config.productionTip = false

new Vue({ render: h => h(App), }).$mount('#app')`, "javascript" );

const modifiedModel = monaco.editor.createModel( `import Vue from "vue"; import Vuex from "vuex"; import App from "./App.vue"; import ElementUI from "element-ui"; import "element-ui/lib/theme-chalk/index.css";

Vue.config.productionTip = false;

Vue.use(ElementUI); Vue.use(Vuex);

const store = new Vuex.Store({ state: { tabName: "", }, mutations: { changeTab(state, tabName) { state.tabName = tabName; }, }, });

new Vue({ render: (h) => h(App), store: store, }).$mount("#app");`, "javascript" );

myDiffEditor = monaco.editor.createDiffEditor( document.getElementById("monaco-editor") ); myDiffEditor.setModel({ original: originalModel, modified: modifiedModel, });

效果如下。
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/be8d2a2242c94714ad18af085887c3c7~tplv-k3u1fbpfcp-watermark.image)

## 总结
Ace,CodeMirror,Monaco Editor这三类编辑器的基本功能几乎相差无几,部分api高度相似,同样都具备部分语言的语法校验和代码智能提示及补全功能,只不过在实现方式上有所区别。自定义主题和语言,三者也都支持,实际项目遇到的可能性较小,文中没有介绍。Ace和CodeMirror的diff模式都依赖第三方开源库,而Monaco Editor自带diff功能。Monaco Editor与vscode同根同源,对于日常的vscode使用者,monaco editor相比之下无疑更加亲切,UI更加美观。CodeMirror重构之后的新版本同样值得期待。如果项目需要用到TypeScript,Ace和Monaco Editor可能是更好的选择。

最后附上编辑器demo的[github链接](https://github.com/mcgong1008/editor-test),文中的代码片段均来自于此。

web代码编辑器有哪些,WEB代码编辑器哪家强的相似文章

案例+图解带你一文读懂Canvas🔥🔥(2W+字)分析巧用 -webkit-box-reflect 倒影实现各类动效分析css滚动条样式代码,实现一个渐变的滚动条分析vue踩坑记录,巨坑巨坑巨坑 记录一下以防下次遇到分析一些有趣的 JavaScript 和 CSS 库分析个人 echarts踩坑记录分析毛玻璃特效,backdrop-filter,让你的网站熠熠生”毛’分析浅谈前端的状态管理分析波浪形动画效果,波浪动画很常见,但这个波浪组件绝对不常见分析