跳到主要内容

扩展宿主和渲染进程为什么不能共享对象?

结论​

扩展宿主和渲染进程是两个进程,各自一份内存。插件拿不到编辑器里的 DOM 节点,渲染进程也拿不到插件里的对象。能过去的只有序列化之后的消息,例如命令参数、Webview 的 postMessage 和语言协议报文。

展开​

VS Code 基于 Electron。渲染进程负责窗口、编辑器绘制和 Webview。扩展宿主是单独的 Node 进程,专门跑插件,避免插件卡死或拖垮界面时把整个窗口弄崩。远程开发时工作区宿主还在另一台机器上,更不可能共享对象。

因此:

  • 不能把函数、类实例、闭包传给界面
  • TextDocument 这种对象只活在宿主 API 里,Webview 里要用纯数据
  • 调用界面能力只能走 vscode API,由宿主替你向工作台发请求,例如弹窗、打开文档、创建终端

这和前端里页面与 Web Worker 的关系很像,只是隔离更硬,还多了一层远程可能。设计状态时就要想清楚权威数据在宿主里,界面只是投影。

调试时如果在渲染进程的开发者工具里找不到插件断点,是正常的。插件断点在扩展宿主进程里,用「附加到扩展宿主」而不是只开页面调试器。

容易讲错的点​

  • 插件里操作 DOM 是做不到的。想自定义界面就用 Webview、树、状态栏这些 API。
  • postMessage 使用结构化克隆。undefined 字段、函数、DOM 节点都会丢或报错。
  • 同一台电脑上的两个进程也不共享堆。远程只是把这一点变得更明显。