Microsoft의 Visual Studio Code에서 사용되는 코드 편집기 컴포넌트를 웹에서 사용할 수 있게 만든 라이브러리이다. Monaco Editor는 다양한 프로그래밍 언어에 대한 구문 강조, 자동 완성, 디버깅 지원, 코드 탐색 기능을 제공한다.
주요 특징:
[링크]
npm install @monaco-editor/react
or
yarn add @monaco-editor/react
import Editor, { DiffEditor, useMonaco, loader } from '@monaco-editor/react';
Editor 컴포넌트가 우리가 사용해야 하는 컴포넌트임.
function App() {
const editRef = 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}
/>
</>
);
}
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}
/>
);
}
DiffEditor은 한 개의 Editor에서 화면을 분할하여 두 개의 코드(original, modified)를 볼 수 있다. original코드 측은 읽기 전용으로, modified는 편집 가능으로 표시된다.
얘네는 DiffEditor에서 파생된 getOriginalEditor()과 getModifiedEditor()가 있어서 따로 불러서 처리할 수 있다.
import React, { useRef } from 'react';
import { DiffEditor } from '@monaco-editor/react';
function MyDiffEditor() {
const diffEditorRef = useRef(null);
function handleEditorDidMount(editor) {
diffEditorRef.current = editor;
}
function runOriginalCode() {
const originalCode = diffEditorRef.current.getOriginalEditor().getValue();
// 실행 로직 추가
console.log('Original Code Output:', originalCode);
}
function runModifiedCode() {
const modifiedCode = diffEditorRef.current.getModifiedEditor().getValue();
// 실행 로직 추가
console.log('Modified Code Output:', modifiedCode);
}
return (
<div>
<DiffEditor
height="90vh"
original="// Original code here"
modified="// Modified code here"
language="javascript"
onMount={handleEditorDidMount}
/>
<button onClick={runOriginalCode}>Run Original Code</button>
<button onClick={runModifiedCode}>Run Modified Code</button>
</div>
);
}
export default MyDiffEditor;
Editor mount될 때 Ref를 만들어 current값에 넣어주는 게 선행되어야 한다.
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}
/>
);
}
Monaco 인스턴스는 Monaco Editor의 핵심 객체로, Monaco Editor의 기능과 설정을 관리하는 데 사용된다. 이 인스턴스를 통해 다양한 언어 지원, 구문 강조, 코드 자동 완성, 코드 편집 및 탐색 기능 등을 사용할 수 있다.
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 handleEdito rDidMount(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}
/>
);
}
handleEditorWillMount(monaco) 에서 Editor가 마운트되기 전에 Editor에 대한 설정을 할 수 있다.
useMonaco를 통해 현재 Monaco Editor 인스턴스를 반환시킬 수도 있음.
const monaco = useMonaco();
useEffect(() => {
if (monaco) {
console.log('Monaco 인스턴스:', monaco);
}
}, [monaco]);
멀티모델 에디터는 다중 모델로 복수의 탭을 만들어서 코드를 작성하는 구조라고 보면 된다.
주요 포인트
#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,
},
};
export default files;
#위 JSON 예시 코드를 통해 파일을 변경하는 예시
import React from 'react';
import ReactDOM from 'react-dom';
import Editor from '@monaco-editor/react';
import files from "./files";
function App() {
const [fileName, setFileName] = useState('script.js');
const file = files[fileName];
return (
<>
<button disabled={fileName === 'script.js'} onClick={() => setFileName('script.js')}>
script.js
</button>
<button disabled={fileName === 'style.css'} onClick={() => setFileName('style.css')}>
style.css
</button>
<button disabled={fileName === 'index.html'} onClick={() => setFileName('index.html')}>
index.html
</button>
<Editor
height="80vh"
theme="vs-dark"
path={file.name}
defaultLanguage={file.language}
defaultValue={file.value}
/>
</>
);
}
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);