Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No syntax highlighting with React Monaco Editor

Just installed React Monaco Editor and seems to be functioning properly except there is no syntax highlighting. I'm trying to use "python" as the language but the font stays the same gray default colour:

enter image description here

Any ideas on how to correct the issue?

Here is my Code.js where I'm running the Monaco Editor:

import React from "react";
import MonacoEditor from "react-monaco-editor";

class Code extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      code: 'print("Hello, World!")'
    };
  }
  editorDidMount(editor, monaco) {
    console.log("editorDidMount", editor);
    editor.focus();
  }
  onChange(newValue, e) {
    console.log("onChange", newValue, e);
  }
  render() {
    const code = this.state.code;
    const options = {
      selectOnLineNumbers: true,
      fontSize: 18,
      colorDecorators: true
    };
    return (
      <MonacoEditor
        width="800"
        height="600"
        language="python"
        theme="vs-dark"
        value={code}
        options={options}
        onChange={this.onChange}
        editorDidMount={this.editorDidMount}
      />
    );
  }
}

export default Code;

Also I added this code to the top of webpack.config.js:

const path = require('path');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
  plugins: [
    new MonacoWebpackPlugin({
      // available options are documented at https://github.com/Microsoft/monaco-editor-webpack-plugin#options
      languages: ['python']
    })
  ]
};

const APP_DIR = path.resolve(__dirname, './src');
const MONACO_DIR = path.resolve(__dirname, './node_modules/monaco-editor');

module.exports = {
  test: /\.css$/,
  include: APP_DIR,
  use: [{
    loader: 'style-loader',
  }, {
    loader: 'css-loader',
    options: {
      modules: true,
      namedExport: true,
    },
  }],
}, {
  test: /\.css$/,
  include: MONACO_DIR,
  use: ['style-loader', 'css-loader'],
}
like image 739
StackUnderFlow Avatar asked Feb 22 '20 19:02

StackUnderFlow


3 Answers

If you are using the Monaco editor with create-react-app you will need a different approach, if you don't want to eject the app (to allow manually editing the webpack config file). This paragraph describes it pretty well:

The easiest way to use the react-monaco-editor with create-react-app is to use the react-app-rewired project. For setting it up, the following steps are required:

  • Install react-app-rewired: npm install -D react-app-rewired
  • Replace react-scripts by react-app-rewired in the scripts section of your packages.json
  • Create a config-overrides.js in the root directory of your project with the following content:
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');

module.exports = function override(config, env) {  
    config.plugins.push(new MonacoWebpackPlugin({
        languages: ['json']
    }));
    return config;
}

For more information checkout the documentation of react-app-rewired here.

I did not have to specify anything else to make it work. No need to specify loaders for webpack manually.

like image 144
Mike Lischke Avatar answered Nov 11 '22 12:11

Mike Lischke


For me both of the above answers are not working - not sure if it's related to Codesandbox or I did a mistake.

But using @monaco-editor/react is working with-out any changes to the CRA setup.

The only difference in the usage is that the default export is not a controlled component - so onchange is not working.

To have a controlled component, just use import {ControlledEditor as MonacoEditor} from "@monaco-editor/react". The onchange handler needs to be slightly modified, first the event & then the newText - just a small difference in the implementation.

The usage looks like following:

import React, { useState } from "react";
import { ControlledEditor as MonacoEditor } from "@monaco-editor/react";
export const Editor = () => {
  const [code, setCode] = useState(`const greeting = () => {
    alert("Hello world");
}`);

  const options = {
    minimap: {
      enabled: false
    }
  };

  const changeHandler = (evt, newText) => {
    setCode(newText);
  };

  const editorDidMount = (editor, monaco) => {
    console.log("editorDidMount", editor);
  };

  return (
    <MonacoEditor
      width="100%"
      height="100%"
      language="javascript"
      theme="vs-dark"
      value={code}
      options={options}
      onChange={changeHandler}
      editorDidMount={editorDidMount}
    />
  );
};

The options can be used to modify the Monaco editor. In my case I don't want to display the minimap. All available options can be found in the editor api docs

You can find the working demo in this Codesandbox.

The only thing that I found that is not working is undo/redo as described in the following issue. No change event triggered but I'll check this later - for now I'm happy with it.

like image 41
AWolf Avatar answered Nov 11 '22 13:11

AWolf


Did you fail to configure CSS for Monaco Editor in Webpack? Perhaps that's issue since everything else looks good.


const path = require('path');
const MONACO_DIR = path.resolve(__dirname, './node_modules/monaco-editor');

{
  test: /\.css$/,
  include: MONACO_DIR,
  use: ['style-loader', 'css-loader'],
}

Solution

The Problem was nothing with the configuration but the place where it was configured. To customize webpack in your React CRA boilerplate, you must eject the app or use customize-cra if you don't want to eject, and do the configuration. OP here configured webpack inside node-modules/, That's not the right to configure your webpack, like at all. Use react-app-rewired with customize-cra.

like image 36
Pushkin Avatar answered Nov 11 '22 13:11

Pushkin