monaco react

其他资源 2025-08-04

@摩纳哥编辑/react·

摩纳哥的编辑器·使用任何React应用程序中的摩纳哥编辑器,而无需使用webpack(或lollup/parcel/etc)配置文件/插件


  • ✅反应V19支持!
  • ⌨️用打字稿重写
  • ⚡已经支持多模型编辑器;享受?
  • ?版本V4在这里 - 要查看新版本中的新事物以及如何从v3迁移,请阅读此文档(另外,如果您需要旧版本readme,它在这里)
  • ?已创建了新部分开发 /游乐场 - 现在您可以运行操场并与图书馆的内部玩耍
  • ?它已经与 @Monaco-editor/Loader集成了

概要

摩纳哥编辑器包装器,用于与任何React应用程序的轻松 /单行集成,而无需使用WebPack(或任何其他模块Bundler)配置文件 /插件。它可以与由Create-React-App,Create-SnowPack-App,vite,next.js或任何其他应用程序生成器生成的应用程序一起使用 -您无需弹出或重新打印它们

动机

摩纳哥编辑是一个著名的基于Web技术的代码编辑器,可为代码提供动力。该库处理摩纳哥编辑器的设置过程,并提供干净的API与任何React环境中的摩纳哥互动

演示

一探究竟!

文档

  • 安装
  • 介绍
  • 用法
    • 简单用法
    • 获得价值
    • 编辑实例
    • 摩纳哥实例
    • usemonaco
    • 加载程序/配置
    • 多模型编辑器
    • validate
    • 笔记
      • 对于电子用户
      • 对于Next.js用户
    • 创建自己的编辑器!
  • 开发 /游乐场
  • 道具
    • 编辑
    • 差异编辑器

安装

npm install @monaco-editor/react # or @monaco-editor/react@next for React v19

或者

yarn add @monaco-editor/react

或者您可以使用CDN。这是一个例子

注意:对于打字稿类型的定义,此软件包将摩纳哥编辑软件包用作同行依赖性。因此,如果您需要类型并且还没有安装摩纳哥编辑包,则需要这样做

问AI

摩纳哥反应AI将帮助您更好地理解该存储库。您可以要求提供代码示例,安装指南,调试帮助等等。

介绍

除了类型外,库还导出编辑和差异器组件,以及加载程序实用程序和usemonaco钩子:

 import Editor , { DiffEditor , useMonaco , loader } from '@monaco-editor/react' ;

用法

简单用法

这是摩纳哥编辑与React项目简单集成的示例。
您只需要导入和渲染编辑器组件:

; } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor from '@monaco-editor/react' ;

function App ( ) {
  return < Editor height = "90vh" defaultLanguage = "javascript" defaultValue = "// some comment" /> ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

扩展示例
); } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor from '@monaco-editor/react' ;

function App ( ) {
  function handleEditorChange ( value , event ) {
    // here is the current value
  }

  function handleEditorDidMount ( editor , monaco ) {
    console . log ( 'onMount: the editor instance:' , editor ) ;
    console . log ( 'onMount: the monaco instance:' , monaco ) ;
  }

  function handleEditorWillMount ( monaco ) {
    console . log ( 'beforeMount: the monaco instance:' , monaco ) ;
  }

  function handleEditorValidation ( markers ) {
    // model markers
    // markers.forEach(marker => console.log('onValidate:', marker.message));
  }

  return (
    < Editor
      height = "90vh"
      defaultLanguage = "javascript"
      defaultValue = "// some comment"
      onChange = { handleEditorChange }
      onMount = { handleEditorDidMount }
      beforeMount = { handleEditorWillMount }
      onValidate = { handleEditorValidation }
    />
  ) ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

获得价值

有两个选择可以获取当前值:

  1. 从编辑器实例获取当前的模型值
); } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React , { useRef } from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor from '@monaco-editor/react' ;

function App ( ) {
  const editorRef = useRef ( null ) ;

  function handleEditorDidMount ( editor , monaco ) {
    editorRef . current = editor ;
  }

  function showValue ( ) {
    alert ( editorRef . current . getValue ( ) ) ;
  }

  return (
    < >
      < button onClick = { showValue } > Show value  button >
      < Editor
        height = "90vh"
        defaultLanguage = "javascript"
        defaultValue = "// some comment"
        onMount = { handleEditorDidMount }
      />
     >
  ) ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

  1. 通过Onchange Prop获取当前的模型值
); } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor from '@monaco-editor/react' ;

function App ( ) {
  function handleEditorChange ( value , event ) {
    console . log ( 'here is the current model value:' , value ) ;
  }

  return (
    < Editor
      height = "90vh"
      defaultLanguage = "javascript"
      defaultValue = "// some comment"
      onChange = { handleEditorChange }
    />
  ) ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

(通过`编辑器实例获取“ diffeditor”值)
); } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React , { useRef } from 'react' ;
import ReactDOM from 'react-dom' ;

import { DiffEditor } from '@monaco-editor/react' ;

function App ( ) {
  const diffEditorRef = useRef ( null ) ;

  function handleEditorDidMount ( editor , monaco ) {
    diffEditorRef . current = editor ;
  }

  function showOriginalValue ( ) {
    alert ( diffEditorRef . current . getOriginalEditor ( ) . getValue ( ) ) ;
  }

  function showModifiedValue ( ) {
    alert ( diffEditorRef . current . getModifiedEditor ( ) . getValue ( ) ) ;
  }

  return (
    < >
      < button onClick = { showOriginalValue } > show original value  button >
      < button onClick = { showModifiedValue } > show modified value  button >
      < DiffEditor
        height = "90vh"
        language = "javascript"
        original = "// the original code"
        modified = "// the modified code"
        onMount = { handleEditorDidMount }
      />
     >
  ) ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

编辑实例

编辑实例是从onmount道具作为第一个参数暴露的,第二个是摩纳哥实例

); } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React , { useRef } from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor from '@monaco-editor/react' ;

function App ( ) {
  const editorRef = useRef ( null ) ;

  function handleEditorDidMount ( editor , monaco ) {
    // here is the editor instance
    // you can store it in `useRef` for further usage
    editorRef . current = editor ;
  }

  return (
    < Editor
      height = "90vh"
      defaultLanguage = "javascript"
      defaultValue = "// some comment"
      onMount = { handleEditorDidMount }
    />
  ) ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

摩纳哥实例

有三个选项可以获取摩纳哥实例:

  1. 通过onmount/beforemount
); } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React , { useRef } from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor from '@monaco-editor/react' ;

function App ( ) {
  const monacoRef = useRef ( null ) ;

  function handleEditorWillMount ( monaco ) {
    // here is the monaco instance
    // do something before editor is mounted
    monaco . languages . typescript . javascriptDefaults . setEagerModelSync ( true ) ;
  }

  function handleEditorDidMount ( editor , monaco ) {
    // here is another way to get monaco instance
    // you can also store it in `useRef` for further usage
    monacoRef . current = monaco ;
  }

  return (
    < Editor
      height = "90vh"
      defaultLanguage = "javascript"
      defaultValue = "// some comment"
      beforeMount = { handleEditorWillMount }
      onMount = { handleEditorDidMount }
    />
  ) ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

  1. 通过装载机实用程序
 import { loader } from '@monaco-editor/react' ;

loader . init ( ) . then ( ( monaco ) => console . log ( 'here is the monaco instance:' , monaco ) ) ;

codesandbox

  1. 通过Usemonaco Hook
; } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor , { useMonaco } from '@monaco-editor/react' ;

function App ( ) {
  const monaco = useMonaco ( ) ;

  useEffect ( ( ) => {
    if ( monaco ) {
      console . log ( 'here is the monaco instance:' , monaco ) ;
    }
  } , [ monaco ] ) ;

  return < Editor height = "90vh" defaultValue = "// some comment" defaultLanguage = "javascript" /> ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

usemonaco

usemonaco是一个返回摩纳哥实例的钩子。但是,应该考虑一个重要的说明:载荷实用程序( @Monaco-editor/loader的引用)正在处理初始化过程:该过程是异步完成的,并且仅一次。因此,如果初始化的第一个启动器是usemonaco钩子,则由于其异步安装,第一个返回的值将为null。只需检查返回的usemonaco的值

; } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React , { useEffect } from 'react' ;
import ReactDOM from 'react-dom' ;

import Editor , { useMonaco } from '@monaco-editor/react' ;

function App ( ) {
  const monaco = useMonaco ( ) ;

  useEffect ( ( ) => {
    // do conditional chaining
    monaco ?. languages . typescript . javascriptDefaults . setEagerModelSync ( true ) ;
    // or make sure that it exists by other ways
    if ( monaco ) {
      console . log ( 'here is the monaco instance:' , monaco ) ;
    }
  } , [ monaco ] ) ;

  return < Editor height = "90vh" defaultValue = "// some comment" defaultLanguage = "javascript" /> ;
}

const rootElement = document . getElementById ( 'root' ) ;
ReactDOM . render ( < App /> , rootElement ) ;

codesandbox

装载机config

库导出(命名)称为加载程序的实用程序。基本上,它是 @Monaco-editor/Loader的参考。默认情况下,正在从CDN下载摩纳哥文件。有能力改变这种行为,以及涉及摩纳哥AMD加载器的其他事情。我们有一个默认配置文件,您可以通过下面显示的方式进行修改:

 import { loader } from '@monaco-editor/react' ;

// you can change the source of the monaco files
loader . config ( { paths : { vs : '...' } } ) ;

// you can configure the locales
loader . config ( { 'vs/nls' : { availableLanguages : { '*' : 'de' } } } ) ;

// or
loader . config ( {
  paths : {
    vs : '...' ,
  } ,
  'vs/nls' : {
    availableLanguages : {
      '*' : 'de' ,
    } ,
  } ,
} ) ; 
将摩纳哥编辑用作NPM软件包

从版本v4.4.0开始,可以将摩纳哥编辑用作NPM软件包;从node_modules导入它,并将摩纳哥源包含在您的捆绑包中(而不是使用CDN)。为了使它起作用,您可以执行以下操作:

 import * as monaco from 'monaco-editor' ;
import { loader } from '@monaco-editor/react' ;

loader . config ( { monaco } ) ;

// ...

注意:您应该注意,这可能需要其他WebPack插件,例如摩纳哥编辑 - webpack-plugin,也可能不可能在CRA生成的应用程序中使用而不弹出它们。

如果使用Vite,则需要这样做:

 import { loader } from '@monaco-editor/react' ;

import * as monaco from 'monaco-editor' ;
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' ;
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' ;
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' ;
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' ;
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' ;

self . MonacoEnvironment = {
  getWorker ( _ , label ) {
    if ( label === 'json' ) {
      return new jsonWorker ( ) ;
    }
    if ( label === 'css' || label === 'scss' || label === 'less' ) {
      return new cssWorker ( ) ;
    }
    if ( label === 'html' || label === 'handlebars' || label === 'razor' ) {
      return new htmlWorker ( ) ;
    }
    if ( label === 'typescript' || label === 'javascript' ) {
      return new tsWorker ( ) ;
    }
    return new editorWorker ( ) ;
  } ,
} ;

loader . config ( { monaco } ) ;

loader . init ( ) . then ( /* ... */ ) ;

codesandbox

注意:您所传递的对象将与默认的对象深入合并

多模型编辑器

当您渲染编辑器组件时,正在创建一个默认模型。需要提到的是,当您更改语言或价值道具时,它们会影响在组件座上自动创建的相同模型。在大多数情况下,这是可以的,但是开发人员想实现多模型编辑器以支持标签/文件(例如IDES)时会面临问题。并且以前要处理多个模型,他们必须手动进行操作。现在,支持多模型API?让我们检查一下它的工作原理。有三个参数可以创建一个模型 - 价值,语言和路径(摩纳哥。您可以将最后一个(路径)视为模型的标识符。现在,编辑器组件具有路径道具。当您指定路径道具时,编辑器组件会检查其是否具有该路径的模型。如果是,将显示现有模型,否则,将创建(并存储)新模型。使用此技术,您可以与路径相通用文件,并创建一个完全多模型的编辑器。您可以打开文件,进行一些更改,选择另一个文件,当您返回第一个文件时,将使用整个视图状态,文本选择,撤消堆栈,滚动位置等显示上一个模型(简单演示)

这是一个简单的例子:让我们想象我们有一个像某种文件结构的JSON一样,类似的是:

 const files = {
  'script.js' : {
    name : 'script.js' ,
    language : 'javascript' ,
    value : someJSCodeExample ,
  } ,
  'style.css' : {
    name : 'style.css' ,
    language : 'css' ,
    value : someCSSCodeExample ,
  } ,
  'index.html' : {
    name : 'index.html' ,
    language : 'html' ,
    value : someHTMLCodeExample ,
  } ,
} ;

这是我们简单的多模型编辑器实现:

); } const rootElement = document.getElementById('root'); ReactDOM.render(, rootElement);">
 import React from 'react' ;
import ReactDOM from 'react-dom' 
					
					
下载源码

通过命令行克隆项目:

git clone https://github.com/suren-atoyan/monaco-react.git