Embedding a Monaco Editor Inside React App | by Jennifer Fu | Dec, 2022

An editor that supports 78 languages ​​with syntax highlighting, autocompletion, autocorrect etc.

photo by setyaki irham Feather unsplash

Monaco Editor is a browser-based code editor provided by Microsoft. It is licensed under the MIT License and is supported in Edge, Chrome, Firefox, Safari and Opera, but is not supported in mobile browsers or web frameworks. Monaco Editor powers Visual Studio Code, an impressive IDE for Windows, Linux and macOS.

Currently, Monaco Editor supports 78 languages, with syntax highlighting, autocompletion, autocorrect and many other advanced features. It can be used to build sophisticated IDEs, such as Visual Studio Code, or as code to display a tool in web applications.

A React app can be deployed monaco-editor Import directly or some React-wrapped package. There are two popular packages, @monaco-editor/react And react-monaco-editor,

NPM trends for @monaco-editor/react and react-monaco-editor.
image by author

react-monaco-editor Available for six years with 3,036 stars. It’s managed very actively. This requires webpack changes, which is inconvenient for some applications, such as the Create React App.

@monaco-editor/react Available with 2,162 starts for three years. It’s managed quite actively. The appeal of this package is that it requires no changes other than installing the package. An app like Create React App doesn’t require ejecting or re-adding the app. By default, it uses CDN to download monaco-editor, However, importing monaco-editor As one npm Package may require extra webpack plugins, such as monaco-editor-webpack-plugin,

this moment, @monaco-editor/react is more popular. We’ll take this as a basis for embedding a Monaco editor inside a Create React app.

@monaco-editor/react Monaco is the editor for React. it uses monaco-editor in a React application without the need to set up plugins or modify configuration files for Webpack, Rollup, Parcel, or any bundler.

Monaco Editor provides a script called loader, which supplies the tooling for downloading the Monaco sources. library, called @monaco-editor/loader, handles the configuration and loading part. It also provides an easy-to-use API to interact. with the help of loaderEmbedding the Monaco editor requires one line of code.

is here package.json of @monaco-editor/react,

  • On line 22, it declares a dependency, @monaco-editor/loaderwhich will be installed node_modules,
  • In lines 14 and 15, it declares peerDependencies of react And react-dom, a peerDependency Declares the compatible version of the package. If peerDependency already exists in node_modules With the correct version, nothing will happen. Otherwise, the installation shows a warning.
  • on line 13, @monaco-editor/react also declared as peerDependency, If it is not present, the installation will show the following warning.
warning " > @monaco-editor/react@4.4.6" has unmet peer dependency "monaco-editor@>= 0.25.0 < 1".

code works without @monaco-editor/react, but it works without TypeScript definitions for monaco-editor, If you want to simplify type definitions, monaco-editor need to be installed.

We are going to embed a Monaco editor in a Create React App. The following command creates a React project:

% yarn create react-app react-monaco-editor
% cd react-monaco-editor

we install @monaco-editor/react And monaco-editor,

% yarn add @monaco-editor/react monaco-editor

After installation, these become part of the packages dependencies In package.json,

"dependencies": 
"@monaco-editor/react": "^4.4.6",
"monaco-editor": "^0.34.1"

Work environment is ready.

In fact, using the Monaco editor requires one line of code, if the import line doesn’t count.

modified here src/App.js,

  • on line 1, Editor is imported from '@monaco-editor/react',
  • On line 5, Monaco is created with the editor 100% see height (vh, it specifies language Is javascriptAnd value Is console.log('Hello, World!');,

Execution yarn startAnd the Monaco editor is embedded in the React app with predefined content.

Monaco editor with content, console.log('Hello, world!');
image by author

Try deleting some characters in the above editor, and it shows a verification message: Unterminated string literal,

Monaco editor showing validation message, unterminated string literal
image by author

Yes, the editor has verification capability.

IntelliSense Code completion is a general term for a variety of code editing features, including parameter information, quick information, and member lists. IntelliSense Features available in Visual Studio Code are also available in the Monaco editor. Different Thinking, IntelliSense ready for typescript, javascript, css, less, scss, jsonAnd html,

Currently, Monaco editor supports 78 languages, which are imported monaco.contribution.ts, The list continues to grow as time passes.

The default editor is editable with line numbers. Let’s provide a longer code to embed src/App.js,

  • In lines 4-29, value entrusted with the contents of the original src/App.js,
  • on line 32, value is displayed in the editor.

Execution yarn start, and the Monaco editor shows line numbers. If you try to modify the code, it is editable.

Monaco editor showing original src/App.js
image by author

add support, optionsto the Editor.

height="100vh"  
language="javascript"
value=value
options= readOnly: true, lineNumbers: 'off'
/>

The editor becomes read-only without line numbers.

Monaco editor that is read only without line numbers
image by author

apart from readonly And lineNumbersThere are many options in the interface, IEditorOptions,

we hardcoded value In src/App.js above, which is not a good practice. One option is to use a file uploader to load files dynamically.

modified here src/App.js,

  • In 4-6 rows, components, FileUploaderis defined using which is a file-select field with a Choose File Button for file upload. On selecting a file, onFileLoad The function is triggered (line 5) from setFile (line 24).
  • on line 9, state, fileis created for the selected file.
  • on line 10, state, valueCreated for selected file content.
  • in lines 12-20, useEffect is run on file Change. it makes a FileReader (line 14), reads the file contents (line 18), and setValue to file content (line 16).
  • on line 24, FileUploader Has been added.
  • On line 25, adjust the height of the editor 90vh,

Execution yarn startand click Choose File Button to load Create React App src/index.js,

FileUploader with uploaded src/index.js
image by author

dynamic loading is not clean?

Burden src/App.css,

src/App.css uploaded with syntax errors
image by author

We see a lot of syntax errors. what is wrong?

This is because we hardcoded language To javascript, This needs to be adjusted depending on the type of file loaded. file One name field with file extension and a type Farm. file extension can be 'js', 'css', 'html', 'json'etc a type field can be "text/javascript", "text/css", "text/html", "text/json"e.t.c.

We use the file extension to set the file type. modified here src/App.js,

  • on line 11, state, languageis made for the chosen language, which is used on line 34.
  • In lines 20-27, the file extension is evaluated to generate newLanguagewhich is used setLanguage (line 27).

Burden src/App.css Again, and there are no syntax errors.

src/App.css uploaded without syntax errors
image by author

Burden public/index.html,

uploaded to public/index.html
image by author

Although a Monaco editor supports several languages, you may want to create your own language. We show an example of how to do this.

as we said @monaco-editor/loader handles the configuration and loading part, loader.init() Handles the entire initialization process and returns an instance of monaco, Editor component uses this utility to — get access to monaco And the editor makes.

The following example is adapted from office websitewhich turns on the color for specific content in the log file.

  • In lines 4-40, it defines a function to return the log file contents.
  • In lines 43–119, useEffect Call loader.init() To define a new language, mySpecialLanguage,
    – On line 46, the new language is registered.
    — In lines 49-58, it defines four tokens based on the regular expression, custom-error (line 52), custom-notice (line 53), custom-info (line 54), and custom-date (line 55).
    – In lines 61-73, it defines myCoolTheme theme that has rules for the language, custom-info is gray (#808080 line 65), custom-error is red (#FF0000) And bold (line 66), custom-notice is orange#ffa500line 67), custom-date is green (#008800line 68), and the default color is black (#000000line 71).
    – on lines 76-108, it registers some autocompletion shortcuts, simpleText (lines 79–83), testing (lines 84–90), and ifelse (lines 91–104).
    — on lines 110-117, this creates the editor with the specified theme (myCoolThemeline 113), value (getCode()line 114), and language (mySpecialLanguage, line 115). The condition on line 111 ensures that the editor is added once.
  • on line 121, it creates container div with a height of 100vh,

Execution yarn startAnd we see the colored log file in the editor.

colored log file in editor
image by author

This example registers some autocompletion shortcuts, simpleText, testingAnd ifelse, The following video shows how it works:

image by author

Monaco Editor provides a separate editor that compares two files. Usage is straightforward.

modified here src/App.js,

  • on line 1, DiffEditor is imported from '@monaco-editor/react',
  • in lines 5-9, DiffEditor used with props of original And modified material.

Execution yarn startAnd we see the code difference.

code is different
image by author

We have embedded a Monaco editor inside a React app. It supports almost all popular languages ​​with syntax highlighting. For typescript, javascript, css, less, scss, jsonAnd htmlit provides IntelliSense Including code completion, parameter information, quick information, and member lists. In addition, we can create our own language for additional features, such as color themes, auto-completion and auto-correction.

We have shown examples of how to display a hardcoded file Editorin a dynamically loaded file Editorand in two files DiffEditor,

Thank you for reading.

Thanks for working with me on the Monaco editor, S Sriram and Siddharth Chintapalli.

Want to Connect?

If you are interested, check out my directory of web development articles.

Leave a Reply