Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
March 30, 2020 11:29 pm GMT

How To Add Monaco Editor to a Next.js app

Bottom Line Up Front

I use a slightly modified version of the steps mentioned in this GitHub comment. Modifications were necessary because I use TailwindCSS with Next.js.

Motivations

Monaco Editor is the open source editor used in VS Code, which itself is open source. I used to write my blogposts in VS Code, and as I make my own Dev.to CMS, I wanted to have all the familiar trappings of Monaco to help me out while I write.

Problems

However there are some issues we have to deal with:

  • Monaco is framework agnostic, so it requires writing some React bindings.
  • Monaco is written for a desktop Electron app, not for a server-side rendered web app.
    • This is solved by using import dynamic from "next/dynamic" and making Monaco a dynamic import.
  • Monaco also wants to offload syntax highlighting to web workers, and we need to figure that out
  • Next.js doesn't want any dependencies importing CSS from within node_modules, as this assumes a bundler and loader setup (e.g. webpack) and can have unintentional global CSS side effects (all global CSS is intended to be in _app.js).

We can solve this with a solution worked out by Elliot Hesp on GitHub and a config from Joe Haddad of the Next.js team.

Solution

The solution I use is informed by my usage of Tailwind CSS, which requires a recent version of PostCSS, which @zeit/next-css only has at 3.0 (because it is deprecated and not maintained).

I also use TypeScript, which introduces a small wrinkle, because Monaco Editor attaches a MonacoEnvironment global on the window object - I just @ts-ignore it.

// next.config.jsconst MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");const withTM = require("next-transpile-modules")([  // `monaco-editor` isn't published to npm correctly: it includes both CSS  // imports and non-Node friendly syntax, so it needs to be compiled.  "monaco-editor"]);module.exports = withTM({  webpack: config => {    const rule = config.module.rules      .find(rule => rule.oneOf)      .oneOf.find(        r =>          // Find the global CSS loader          r.issuer && r.issuer.include && r.issuer.include.includes("_app")      );    if (rule) {      rule.issuer.include = [        rule.issuer.include,        // Allow `monaco-editor` to import global CSS:        /[\\/]node_modules[\\/]monaco-editor[\\/]/      ];    }    config.plugins.push(      new MonacoWebpackPlugin({        languages: [          "json",          "markdown",          "css",          "typescript",          "javascript",          "html",          "graphql",          "python",          "scss",          "yaml"        ],        filename: "static/[name].worker.js"      })    );    return config;  }});

and then in your Next.js app code:

import React from "react";// etcimport dynamic from "next/dynamic";const MonacoEditor = dynamic(import("react-monaco-editor"), { ssr: false });function App() {  const [postBody, setPostBody] = React.useState("");  // etc  return (<div>  {/* etc */}    <MonacoEditor      editorDidMount={() => {        // @ts-ignore        window.MonacoEnvironment.getWorkerUrl = (          _moduleId: string,          label: string        ) => {          if (label === "json")            return "_next/static/json.worker.js";          if (label === "css")            return "_next/static/css.worker.js";          if (label === "html")            return "_next/static/html.worker.js";          if (            label === "typescript" ||            label === "javascript"          )            return "_next/static/ts.worker.js";          return "_next/static/editor.worker.js";        };      }}      width="800"      height="600"      language="markdown"      theme="vs-dark"      value={postBody}      options={{        minimap: {          enabled: false        }      }}      onChange={setPostBody}    />  </div>)}

Links


Original Link: https://dev.to/swyx/how-to-add-monaco-editor-to-a-next-js-app-ha3

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To