Monaco Editor 实操指南:从语言 Worker 接线到执行结果展示
【免费下载链接】monaco-editorA browser based code editor项目地址: https://gitcode.com/gh_mirrors/mo/monaco-editor
Monaco Editor 是 VS Code 所用的浏览器代码编辑器,本文教你在页面里直接看到"代码执行结果":先起编辑器实例,再接好语言 worker 拿到检查反馈,然后把代码交给 Web Worker 执行并打印输出,最后用断点追查变量状态。
能力全景:执行结果到底在哪一层
先说清楚一个事实:Monaco Editor 本身是编辑器组件,不是可运行环境。"看到执行结果"这件事被拆在了几层里,各层职责如下:
| 能力 | 所在位置 | 你看到的东西 |
|---|---|---|
| 内联诊断 | 内置 TS/JSON/HTML/CSS 语言 worker | 代码下方红色波浪线、错误列表 |
| 补全与悬停 | 内置语言特性(由 worker 配合) | 候选弹窗、签名提示 |
| 编辑器内执行代码 | 需自行接线(页面内运行或 Web Worker) | 页面下方的输出区 |
| 断点调试 | 浏览器 DevTools / VS Code 调试器 | 变量值、调用栈、单步 |
| 语言服务器接入 | LSP 客户端(alpha 阶段) | 语言服务器下发的各类特性 |
如果你只要"检查类结果",前两行开箱即用;想要"运行输出"和"断点单步",需要自己动手接线。下面按接入、执行、展示、排错的顺序把整条链路走一遍。
🚀 接入:三步让编辑器跑在页面上
- 在你的项目里安装依赖:
npm install monaco-editor。 - 创建编辑器实例,最小可运行代码如下:
import * as monaco from 'monaco-editor'; monaco.editor.create(document.getElementById('container'), { value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join('\n'), language: 'javascript' });这段代码把编辑器挂到#container上,载入一段 JavaScript 并启用语法高亮。
- 接好语言 worker。使用打包器时,要告诉编辑器每种语言的 worker bundle 在哪里:
self.MonacoEnvironment = { getWorkerUrl: (moduleId, label) => { if (label === 'json') return './json.worker.bundle.js'; if (label === 'css' || label === 'scss' || label === 'less') return './css.worker.bundle.js'; if (label === 'html' || label === 'handlebars' || label === 'razor') return './html.worker.bundle.js'; if (label === 'typescript' || label === 'javascript') return './ts.worker.bundle.js'; return './editor.worker.bundle.js'; } };这就是接线部分:编辑器按语言标签调用getWorkerUrl,拿到对应文件后,检查、补全等重计算就移到后台线程。各打包器的现成配置见 ESM 集成文档,完整示例目录 里的 Vite 示例 可以直接作为起点。
注意:浏览器禁止
file://打开的页面创建 Web Worker。请用本地 http 服务访问(Vite 示例跑npm run dev,或npx serve .),否则控制台会报 "Could not create web worker",后面所有检查能力都会失效。
🔍 不运行也能看到的结果:内联诊断
worker 接好后,不需要任何额外代码:输入代码的同时,TS worker 做类型检查、JSON worker 做语法校验,错误以内联波浪线呈现,悬停可看错误详情,并汇总到问题列表,体验和 VS Code 的 Problems 面板一致。
TypeScript 还能通过编译选项控制检查行为,例如用typescriptDefaults.setCompilerOptions打开strict,用setDiagnosticsOptions开关语义检查;worker 入口源码在 ts.worker.ts。
这一层结果最划算:不依赖服务端、不启动进程,输入即时反馈。
让代码真正跑起来:三级执行与展示
最快路径:直接在页面里执行
代码短、可信且不需要隔离时,取editor.getValue()后在页面上下文执行(如包一层new Function(code)()),再把返回值或捕获到的console输出追加到输出区即可。零接线,但和页面共享同一窗口,不适合跑用户提交的代码。
Web Worker 沙箱执行接线
对不可信代码,把它放进独立 Worker 执行,用postMessage传回结果,页面只负责展示:
const worker = new Worker('run.worker.js'); document.getElementById('run').onclick = () => worker.postMessage(editor.getValue()); worker.onmessage = (e) => (document.getElementById('output').textContent = e.data);这段代码把"点按钮 → 把编辑器内容发给 Worker → 打印返回文本"串成一个闭环;Worker 侧把捕获到的 console 输出拼成字符串发回即可。
自定义语言 worker 里跑虚拟 TS 工程
如果"结果"指编译产物(DTS、AST、类型信息)而不是程序输出,可以挂进 Monaco 的 TS 语言 worker:用setWorkerOptions注册自定义 worker,在 worker 内借助@typescript/vfs搭虚拟 TS 工程,在后台线程完成编译分析。仓库示例就是这个思路:
monaco.languages.typescript.typescriptDefaults.setWorkerOptions({ customWorkerPath: 'custom-worker.js' }); const factory = await monaco.languages.typescript.getTypeScriptWorker(); const tsWorker = await factory(editor.getModel().uri); const dts = await tsWorker.getDTSEmitForFile( editor.getModel().uri.toString() );这段代码展示如何调用 TS worker 上的自定义方法:拿到当前文件的 DTS 声明输出。完整示例 里还有打印 AST 的按钮,同样需要本地服务器打开,不能直接双击 html。
断点调试:在调试器里查看变量状态
Monaco Editor 不带调试器,断点能力来自浏览器 DevTools 或 VS Code 的调试器。常规路径:开发工具能加载 source map 时(Vite dev 模式默认提供),直接在 DevTools 打断点或用 VS Code attach 调试,程序停在断点后,在 Variables 面板看当前变量值、Call Stack 面板看执行路径,再用单步逐行推进。
提示:区分"你自己写的代码"和"编辑器自身的代码"。后者的断点位于编辑器 bundle 内部,业务调试时通常只需关注前者。
排错速查:四种最常碰到的情况
| 现象 | 问题出在哪 | 怎么修 |
|---|---|---|
| 控制台报 "Could not create web worker" | 页面用file://打开 | 起本地 http 服务再访问 |
| 代码有错但不显示波浪线 | worker 没接上或getWorkerUrl路径对不上 | 对照 ESM 集成文档 核对 |
| 点执行按钮无反应 | Worker 文件加载失败(404 或跨域) | 看 Network 面板里的 worker 请求 |
| 执行时页面卡顿 | 重逻辑跑在主线程 | 把执行逻辑移到 Worker 内 |
下一步行动清单
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/mo/monaco-editor,进入samples/按 samples/README.md 安装并启动示例服务器,先把几种接入方式各看一遍。 - 复制 Vite 示例,按"Web Worker 沙箱执行接线"一节加一个执行按钮和输出区,跑通第一个执行闭环。
- 起本地服务器打开 自定义 worker 示例,分别触发 DTS 输出和 AST 打印,体验后台线程的编译结果。
【免费下载链接】monaco-editorA browser based code editor项目地址: https://gitcode.com/gh_mirrors/mo/monaco-editor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考