preface
- The company has a data center class project, due to a variety of reasons, such as the old technology stack is inconvenient to iteration, and recently began to reconstruct. The predecessors of this project have been iterating for three years, but we can think of the workload of reconstruction [manual head]. The former end technology stack is NG1.x + Nodejs. Since it is a data center type project, it is inevitable to write code on the page. The module I am responsible for the task of this period reconstruction happens to have a code editor, and the ng1. X project uses one
moaco-editor
In order to make the style more consistent, I do not want to change the type of code editor ~
Easier to usemonaco-editor
Third-party packages
- Ng1.x does not use third-party packages, while
monaco-editor
The official document reads like… So I decided to open the NPM search wave, there are still some open source packages for us to use, introduce two, pro test good ①react-monaco-editor2.@monaco-editor/react
Just a quick chatreact-monaco-editor
and@monaco-editor/react
The difference of
- Both are encapsulated based on React + TS
react-monaco-editor
Take a look at the entry file
And we can see,react-monaco-editor
Encapsulates theMonacoEditor
和 MonacoDiffEditor
Helped us deal with some automatic closing of parentheses, code comparison… And derived amonaco
Is easy to customize.
@monaco-editor/react
Also see how the entry file is richer than the one above@monaco-editor/react
It helped us encapsulate a few hooks that declare cycles, which I decided to use in my project on second thought@monaco-editor/react
Custom encapsulation of code editors
monaco-editor
Compare versions
- One thing to note
monaco-editor
There is an issue with code not being highlighted in 0.25.1+.-
Custom themes (described below)
-
Using the Monaco-editor-webpack-plugin, create-react-app generates projects that do not expose webpack.config.js by default. We need to use third-party packages or execute NPM eject to expose the configuration file and modify the configuration. I used Craco in the project.
1) NPM install Monaco - editor - webpack - the plugin// find your configuration file const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); module.exports = { ... plugins: [ new MonacoWebpackPlugin(['apex'.'azcli'.'bat'.'clojure'.'coffee'.'cpp'.'csharp'.'csp'.'css'.'dockerfile'.'fsharp'.'go'.'handlebars'.'html'.'ini'.'java'.'javascript'.'json'.'less'.'lua'.'markdown'.'msdax'.'mysql'.'objective'.'perl'.'pgsql'.'php'.'postiats'.'powerquery'.'powershell'.'pug'.'python'.'r'.'razor'.'redis'.'redshift'.'ruby'.'rust'.'sb'.'scheme'.'scss'.'shell'.'solidity'.'sql'.'st'.'swift'.'typescript'.'vb'.'xml'.'yaml'])],... };Copy the code
-
Basic usage
```js import React, { Fragment } from "react"; import MonacoEditor from "@monaco-editor/react"; const DpEditor = () => { const [code , setCode] = "SELECT user FROM acction_user" const options = { readOnly: True, // whether it is read-only automaticLayout: true, // automaticLayout wordWrap: true, // folding display... // There are many configuration items, the following will be attached to the configuration items of the official document}; Function onChangeHandle(value) {setCode(value)} function handleEditorWillMount(Monaco) {// Monaco } function handleEditorDidMount() {// When unmounted, this hook can be used to destroy Monaco... } return (<Fragment> <div className="editor-container" style={{height:"500", width:"500" }}> <MonacoEditor loading={<div>loading... <div>} theme="vs" language={'sql'} value={code} options={options} onChange={onChangeHandle} beforeMount={handleEditorWillMount} onMount={handleEditorDidMount} /> </div> </Fragment> ); }; export default DpEditor; ` ` `Copy the code
- Here we have a code editor with basic effects
Rich usage
-
Of course, for most application scenarios this is not enough at all, and we need some customization
-
Custom themes
import React, { Fragment } from "react"; import MonacoEditor from "@monaco-editor/react"; const DpEditor = () = > { const [code , setCode] = "SELECT user FROM acction_user" const options = { readOnly: true.// Whether it is read-only automaticLayout: true.// Automatic layout wordWrap: true.// Fold line display.// There are many configuration items. The official documentation of the configuration items will be posted below }; function onChangeHandle(value) { setCode(value) } function handleEditorWillMount(monaco) { // The Monaco mounted hook argument is the Monaco instance, where you can do some customization + defineTheme(monaco.editor); } function handleEditorDidMount() { // This hook can be used to destroy Monaco... operation } + function defineTheme( editor) { + editor.defineTheme("dpLightTheme", { + base: "vs-dark".// Basic theme + inherit: true, + rules: [...sqlTokenConfig], // Specify a custom content + colors: { + "editor.background": "# 313131".// Edit the back landscape + / / 'editor. LineHighlightBorder' : '# E7F2FD', / / edit line border color+}, +}); +}return( <Fragment> <div className="editor-container" style={{ height:"500" , width:"500" }}> <MonacoEditor loading={<div>loading... <div>} theme="vs" language={'sql'} value={code} options={options} onChange={onChangeHandle} beforeMount={handleEditorWillMount} onMount={handleEditorDidMount} /> </div> </Fragment> ); }; export default DpEditor;Copy the code
Look at the effect, the code color and the background color are already the color we want
-
Custom code prompts
import React, { Fragment } from "react";
import MonacoEditor from "@monaco-editor/react";
const DpEditor = () = > {
const [code , setCode] = "SELECT user FROM acction_user"
const options = {
readOnly: true.// Whether it is read-only
automaticLayout: true.// Automatic layout
wordWrap: true.// Fold line display.// There are many configuration items. The official documentation of the configuration items will be posted below
};
function onChangeHandle(value) {
setCode(value)
}
function handleEditorWillMount(monaco) {
// The Monaco mounted hook argument is the Monaco instance, where you can do some customization
defineTheme(monaco.editor);
customPrompt( monaco);
}
function handleEditorDidMount() {
// This hook can be used to destroy Monaco... operation
}
function defineTheme( editor) {
editor.defineTheme("dpLightTheme", {
base: "vs-dark".// Basic theme
inherit: true.rules: [...sqlTokenConfig], // Specify a custom content
colors: {
"editor.background": "# 313131".// Edit the back landscape
/ / 'editor. LineHighlightBorder' : '# E7F2FD', / / edit line border color}}); }function customPrompt(monaco) {
const suggestions = ["XID"."XML"."XOR"."YEAR"."YEAR_MONTH"."ZEROFILL"."I'm a custom."].map((item) = > {
return {
insertText: item,
kind: monaco.languages.CompletionItemKind.Function, // The corresponding prompt icon is different
label: item,
};
});
monaco.languages.registerCompletionItemProvider(language, {
provideCompletionItems() {
return {
suggestions,
};
},
quickSuggestions: true.// Disable by default
triggerCharacters: ["$"."."."=".":"].// More than one character can be defined to trigger the prompt
});
}
return( <Fragment> <div className="editor-container" style={{ height:"500" , width:"500" }}> <MonacoEditor loading={<div>loading... <div>} theme="vs" language={'sql'} value={code} options={options} onChange={onChangeHandle} beforeMount={handleEditorWillMount} onMount={handleEditorDidMount} /> </div> </Fragment> ); }; export default DpEditor;Copy the code
- Look at the effect
- If you are interested in the Monaco official address, please read it and I will continue to add it when I have time.
-END-