@摩纳哥编辑/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项目简单集成的示例。
您只需要导入和渲染编辑器组件:
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
扩展示例
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
获得价值
有两个选择可以获取当前值:
- 从编辑器实例获取当前的模型值
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
- 通过Onchange Prop获取当前的模型值
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”值)
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道具作为第一个参数暴露的,第二个是摩纳哥实例
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
摩纳哥实例
有三个选项可以获取摩纳哥实例:
- 通过onmount/beforemount
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
- 通过装载机实用程序
import { loader } from \'@monaco-editor/react\' ; loader . init ( ) . then ( ( monaco ) => console . log ( \'here is the monaco instance:\' , monaco ) ) ;
codesandbox
- 通过Usemonaco Hook
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的值
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 , } , } ;
这是我们简单的多模型编辑器实现:
import React from \'react\' ;
import ReactDOM from \'react-dom\' <spa
