client 半端
别名:__DSH_BOOT__、客户端半端、双半端、client bundle、dsh.client
一个插件可以有两半:宿主侧(在 Node 进程里跑)与客户端侧(在浏览器里跑)。客户端半端靠 package.json 的 dsh.client 声明、exports 里的 ./client 产物、以及服务端注入的 window.__DSH_BOOT__ 入口图挂进页面。
一句话
宿主半端加能力,客户端半端加界面。 两半在同一个 npm 包里分发,但跑在两个进程里:宿主侧在你启动 DSH 的那个 Node 进程里,客户端侧在浏览器里。
一个插件必须提供的三样东西
package.json的dsh.client声明。字段只有三个:platform(字符串,必需)、inject(字符串数组,可选,声明它依赖哪些别的客户端包先加载)、immediately(布尔,可选,表示要立刻加载而不是等图里轮到它)。缺platform、inject不是字符串数组、immediately不是布尔,都会在组合阶段直接抛错。exports里的"./client"。服务端要把声明解析成一个真实文件路径:接受两种写法——直接给字符串,或者给一个带字符串default的对象。解析不到聚合报MissingClientBundleError,并连带报出它在找哪个路径。- 产物本身(惯例是
lib/client.js)。它是构建出来的浏览器 bundle,不是源码。
一个真实的声明长这样(@deepseek-ai/dsh-client-ui-theme 的 package.json):
"exports": { "./client": { "default": "./lib/client.js" } },
"dsh": {
"client": {
"inject": ["@deepseek-ai/dsh-client-connection", "…"],
"platform": "web",
"immediately": true
}
}
从声明到页面上的脚本
服务端扫描已加载的插件行,把每个客户端半端变成入口图里的一行:
{ id, url: "/plugins/<id>/client.js?rev=<12 位 sha1>", rev, inject?, immediately? }
rev 是内容哈希,只用来破缓存。整个图会被序列化成一行脚本,插在 <head> 的最前面:
<script>window.__DSH_BOOT__ = {"rev":"…","entries":[…]}</script>
注入时会把 < 转义成 \u003c,这样插件控制的字符串不能提前闭合 script 标签。缺图或图畸形时前端选择大声失败:页面不能引导任何东西,报错比半死不活好。
三条容易踩的边界
- 跨插件引用是构建错误:
inject决定加载顺序,但值导入(直接 import 别人模块里的对象)在打包时就被拦下。工厂里的同步require只能要求已经注册的包——异步加载还没落地。 - 加载失败要可诊断:
client.js拿不到时聚合错误会列出包名与它期待的路径,别只报「插件没生效」。 - 客户端半端不是「换界面」:它挂在某个界面里(侧边栏、设置页、输入框附近)。换掉界面本身属于客户端形态,见「界面与客户端」分区。
与安全的关系
客户端半端是第三方代码在你的浏览器里跑,和宿主半端一样在同一个信任面上。发布前请按规范检查:只有 exports 与 dsh.client 声明得干净,加载顺序才是确定的。插件安装与加载的完整链路见 tutorial/3。
出处
- 声明解析与入口图:
@deepseek-ai/dsh-client-modules的lib/index.js(parseDshClient、clientExportOf、graphRow、injectBootManifest)。 - 浏览器侧解析边界:同包
lib/client.js的parseBootManifest。 - 真实声明样本:
@deepseek-ai/dsh-client-ui-theme的package.json(dsh.client三个字段齐全)。 - 插件侧另一样本:
dsh-pack-plugin的package.json(dsh.bundle.patch+dsh.client同时声明,见 plugin/2)。
相关教程
谁引用了这一条
信息表
- category
- concept.plugin
- layer
- plugin
- spec
- ~/.dsh/profiles/node_modules/@deepseek-ai/dsh-client-modules/lib/index.js(parseDshClient / graphRow / injectBootManifest)与 lib/client.js(parseBootManifest)
- updatedAt
- 2026-10-02
被 3 篇教程引用 · 被 2 条词条引用
最后更新 2026-10-02