NextJs项目接入Monaco

312 阅读1分钟

Monaco-Editor支持两种模块AMD和ESM

在NextJS项目中,我们使用ESM的方式接入。

Webpack项目,ESM模块的两种接入方式

github.com/microsoft/m…

文档中介绍webpack项目ESM模型的两种接入方式:

方式1: 使用Monaco-Editor的webpack插件,即monaco-editor-webpack-plugin。

方式2: 不使用插件

使用monaco-editor-webpack-plugin方式接入Monaco-Editor

修改根目录next.config.mjs文件如下:

/** @type {import('next').NextConfig} */
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin'
const nextConfig = {
    eslint: {
        ignoreDuringBuilds: true,
      },
    webpack: (config, { isServer }) => {
        

    config.output.globalObject = "self";
    if (!isServer) {
      config.plugins.push(
        new MonacoWebpackPlugin({
          languages: [
            "json",
            "markdown",
            "css",
            "typescript",
            "javascript",
            "html",
            "scss",
            "less",
          ],
          filename: "static/[name].worker.js", //这个很重要
        })
      );
    }
       
        return config;
    },
};

export default nextConfig;

封装Monaco-Editor组件

"use client";
import * as monaco from "monaco-editor";
import React, { useEffect, useRef } from 'react';


export default function MocanoEditor({ value, language, onChange }: {
    value?: string, language?: string, onChange?: (value: string) => void
}) {
    const editorRef = useRef(null);
    const editor = useRef<any | null>(null);

    useEffect(() => {
        if (editorRef.current === null) return
        editor.current = monaco.editor.create(editorRef.current, {
            value: value || '',
            language: language || 'javascript'
        });

        editor.current.onDidChangeModelContent(() => {
            onChange && onChange(editor.current.getValue());
        });

        return () => {
            editor.current?.dispose();
        }

    }, [])

    useEffect(() => {
        if (editor.current === null) return
        editor.current.setValue(value || '');
    }, [value])

    useEffect(() => {
        if (editor.current === null) return
        const model = editor.current.getModel();
        monaco.editor.setModelLanguage(model, language || 'javascript');
    }, [language])

    function handleResize() {
        editor.current?.layout();
    }

    useEffect(() => {
        window.addEventListener('resize', handleResize)

        return () => {
            window.removeEventListener('resize', handleResize)
        }
    }, [])

    return (
        <div ref={editorRef} style={{ height: '500px', border: '1px solid #ddd', padding: '10px 0', overflow: 'scroll' }}>

        </div >

    );
}

参考:juejin.cn/post/709117…