0
votes

I have been trying to integrate monaco-editor in a React app. I have had success but still facing issues. Below I have provided details of my development setup.

I have tsconfig.json file configured like this:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "lib": ["dom", "es5", "es2015.collection", "es2015.promise", "dom.iterable"],
    "jsx": "react",
    "sourceMap": true,
    "checkJs": false,
    "outDir": "./dist",
    "strict": true,
    "moduleResolution": "node",
    "baseUrl": "./node_modules",
    "typeRoots": ["node_modules/@types"],
    "allowJs": true,
    
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,

    "preserveConstEnums": true,    
    "isolatedModules": true
  },

  "include": ["./src/**/*"],
  "exclude": ["node_modules"]  
}

And my package.json has the scripts configured like this:

"scripts": {
    "test": "jest",
    "start": "webpack serve",
    "server": "nodemon --exec ts-node server.tsx",
    "build": "webpack -w --mode=development"
  }

The start script is using webpack-dev-server and the server is using ts-node to run my server.tsx file.

The monaco-editor is imported in a React component .tsx file as import * as monaco from 'monaco-editor';

When I run this command: npm run start which uses webpack-dev-server all done nicely and I am able to see my app in the browser.

However, when I run this command: npm run server which uses ts-node to execute server.tsx file, I get this error:

Error: Cannot find module 'monaco-editor'
Require stack:
- D:\Development\Workstation\VividCodes.UI_OLD\src\components\TestMonaco.tsx
- D:\Development\Workstation\VividCodes.UI_OLD\src\components\App.tsx       
- D:\Development\Workstation\VividCodes.UI_OLD\server.tsx
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
    at Function.Module._load (internal/modules/cjs/loader.js:725:27)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)

This is a copy of the content of server.tsx file:

import express from 'express';
import * as React from 'react';
import ReactDOMServer from 'react-dom/server';

import App from './src/components/App';

const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const config = require('./webpack.config.js');

const webpackHotMiddleware = require('webpack-hot-middleware');

const server = express();
const compiler = webpack(config);
const port = 3000;

server.use(
  webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
  })
);

server.use(webpackHotMiddleware(compiler));

server.get('/', (req: any, res: any) => {
  const initialMarkup = ReactDOMServer.renderToString(<App />);  
  console.log(initialMarkup);

  res.send(`
    <html>
      <head>
        <title>Monaco_Editor</title>
      </head>
      <body>
        <div id="mountNode">${initialMarkup}</div>
        <script src="/app.bundle.js"></script>
        <script src="/editor.worker.bundle.js"></script>
        <script src="/json.worker.bundle.js"></script>
        <script src="/css.worker.bundle.js"></script>
        <script src="/html.worker.bundle.js"></script>
        <script src="/ts.worker.bundle.js"></script>
      </body>
    </html>
  `)
});

server.listen(port, () => console.log(`Server started on port: ${port}`));

My plan was to use a correct custom server to render my components dynamically, than doing so on client-side.

1
You have to install the types for Monaco-editor I think. Try to install react-monitor-editor, it has its own types declarationsHamza Khattabi
Thanks for your comment. Reluctant to use another third-party library. react-monaco-editor looks like someone's personal project and I am not sure it's a good idea for production.xerxes
How can I install the types for monaco-editor, without using someone else's library?xerxes
So you can install the types definition from microsoft but it is noticed that the react-monaco-editor has its own type declaration. See there : npmjs.com/package/@types/react-monaco-editorHamza Khattabi
Yes I know react-monaco-editor has its own type declaration, as per your advice. I am not a fan of that library to be fair. I need to figure out how I can resolve the issue related 'types', you have advised earlier without using any other libraries. Relying on personal projects for production is not a good practice.xerxes

1 Answers

0
votes

Monaco-editor does not support server-side rendering. It cannot rebind to the existing DOM node. It has to be done on client-side unfortunately. And, there is currently no plans on implementing the server-side rendering functionality.

However, for those who have the same concern, if Webpack is what you're using for bundling, make sure you set minimising option to 'true'. This way, your bundled JS files will be much smaller. Also, there is a 'min' version of monaco-editor which can be used for production; but it's based on AMD.