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 onemoaco-editorIn order to make the style more consistent, I do not want to change the type of code editor ~

Easier to usemonaco-editorThird-party packages

  • Ng1.x does not use third-party packages, whilemonaco-editorThe 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-editorand@monaco-editor/reactThe difference of

  • Both are encapsulated based on React + TS
  • react-monaco-editorTake a look at the entry file

And we can see,react-monaco-editorEncapsulates theMonacoEditorMonacoDiffEditorHelped us deal with some automatic closing of parentheses, code comparison… And derived amonacoIs easy to customize.

  • @monaco-editor/reactAlso see how the entry file is richer than the one above@monaco-editor/reactIt helped us encapsulate a few hooks that declare cycles, which I decided to use in my project on second thought@monaco-editor/reactCustom encapsulation of code editors

monaco-editorCompare versions

  • One thing to notemonaco-editorThere is an issue with code not being highlighted in 0.25.1+.
    1. Custom themes (described below)

    2. 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-