桌面和网页一套代码怎么兼容?
结论
业务逻辑写成不依赖 Node 的部分,平台差异收口到少数适配函数。运行时用编辑器提供的能力检测,而不是写死 process 或磁盘路径。桌面做不到和网页完全同一份未打包源码时,就共享源码、分两个打包入口。
展开
可以共享的:
- 命令、配置、树、Webview 消息协议
workspace.fs、WorkspaceEdit、诊断、补全这些vscodeAPI- 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。