跳到主要内容

桌面和网页一套代码怎么兼容?

结论​

业务逻辑写成不依赖 Node 的部分,平台差异收口到少数适配函数。运行时用编辑器提供的能力检测,而不是写死 process 或磁盘路径。桌面做不到和网页完全同一份未打包源码时,就共享源码、分两个打包入口。

展开​

可以共享的:

  • 命令、配置、树、Webview 消息协议
  • workspace.fs、WorkspaceEdit、诊断、补全这些 vscode API
  • URI,全程不要把 fsPath 当唯一标识

要分支的:

  • 启动语言服务器:桌面用子进程,网页没有 child_process
  • 读插件旁边的大文件:用 workspace.fs.readFile(context.extensionUri),两边都成立
  • 认证:优先 authentication 和 secrets,不要直接读本机凭据文件

检测方式:

  • vscode.env.uiKind === vscode.UIKind.Web 判断是不是网页
  • vscode.env.remoteName 判断是不是远程
  • 对可选能力用 as any 式的存在性判断不如直接分入口。打包工具把 Node 模块留在桌面包里

贡献点两边共用同一份 package.json。某命令在网页不可用时,用 when 里的上下文键藏起来,并在激活时根据 uiKind 设置这个键。不要让用户点下去才抛「process is not defined」。

测试至少跑两次思路:桌面扩展宿主一次,网页能力受限路径一次。很多 bug 是桌面开发时从来没走到 browser 入口。

容易讲错的点​

  • 兼容不是在每个函数里写一堆 try/catch require("fs")。失败会杂乱,包里仍然带着 Node。
  • 网页里没有持久的本地插件目录可以随便写。缓存放 globalState 或编辑器允许的存储 URI。
  • 远程桌面和纯网页是两种限制。远程有 Node,网页没有。适配函数不要只写一个布尔叫 isCloud。