最近打算在 nextjs 15 下使用 manco editor 编辑器,编辑器可以正常显示,但是没有代码补全功能和悬停提示功能。原因可能是语言服务使用的 worker 报错,导致无法正常使用该功能。 下面使用的一些代码片段
"use client";
// MonacoEditor 组件
import { editor, Range, languages } from "monaco-editor";
import React, { useEffect, useRef, useState } from "react";
export default function MonacoEditor() {
const containerRef = useRef(null);
const [language, setLanguage] = useState("javascript");
const standarEditorRef = useRef<editor.IStandaloneCodeEditor>(null);
useEffect(() => {
const standardEditor = editor.create(containerRef.current!, {
value:
'function hello() {\n\talert("Hello world!");\n}\nconsole.log("https://kimi.moonshot.cn/chat/ctjtnu0h9477s9jrkgj0")\nalert("1")',
language: language,
theme: "vs-dark",
tabSize: 2,
standarEditorRef.current = standardEditor
return () => {
standardEditor.dispose();
standarEditorRef.current = null
};
}, []);
useEffect(() => {
if (standarEditorRef.current) {
const model = standarEditorRef.current.getModel();
// @ts-ignore
model.setLanguage(language);
}
}, [language]);
return (
<div>
<div>
<select
value={language}
name="language"
id=""
onChange={(event) => {
setLanguage(event.target.value);
}}
>
<option value="javascript">javascript</option>
<option value="css">css</option>
<option value="html">html</option>
</select>
</div>
<div ref={containerRef} id="container" className="h-[600px] w-full"></div>
</div>
);
}
没有使用 @monaco-editor/react 库是因为这个库还不支持 react 19
"use client";
// page.tsx
// 这里使用 next/dynamic 是保证编辑器代码只在客户端运行
import dynamic from "next/dynamic";
const DynamicMonacoEditor = dynamic(() => import('./components/MonacoEditor'), {
ssr: false
})
export default function Home() {
return (
<div>
<DynamicMonacoEditor></DynamicMonacoEditor>
</div>
)
}
// next.config.ts 文件
import type { NextConfig } from "next";
import MonacoWebpackPlugin from "monaco-editor-webpack-plugin";
import path from 'path'
const nextConfig: NextConfig = {
/* config options here */
webpack(config, { isServer }) {
if (!isServer) {
config.plugins.push(
new MonacoWebpackPlugin({
// 默认会包括所有的语言
// import metadata from 'monaco-editor/esm/metadata' console.log(metadata.languages) 可获取所有的语言
// languages: ['javascript', 'typescript']
})
);
}
return config;
},
};
export default nextConfig;
next.config.ts 是参考这里 https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-esm.md 设置的,next 打包时没有使用 Turbopack 而是使用 webpack 进行打包。这里需要使用 isServer 判断一下,因为 nextjs 会根据不同环境使用不同的 webpack 配置,如果不判断会导致 build 失败
控制台的报错是因为 worker 导致的错误,查看报错的信息发现是在执行 _register 的函数导致的错误
大概猜测是加载 worker 时出现的错误