# sc-build — dsh-session-categories 的可重复构建工程 > 这个目录的存在理由只有一条:**让 8 项客户端代差补丁不再是"补丁",而是源码。** > 以前那套是直接改 `node_modules` 里的 `lib/client.js`——插件一升级就全丢,得重打。 > 现在改**源码**、**真编译**,重建一条命令。 > > 📄 上游发布用的 `README.md` / `README.zh.md` **原样保留**(将来发布要用),本文件只管构建。 --- ## 快速开始 ```powershell # node / pnpm 不在默认 PATH 上,先补上 $env:Path = [Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [Environment]::GetEnvironmentVariable("Path","User") + ";" + "$env:APPDATA\npm" cd "E:\AI\DSH\DSH-Workspace\deepseek-harness\default-workspace\sc-build" npx tsdown # 编译 → lib/client.js(+ 会多出一个 lib/style.css) node scripts/inline-css.mjs # 把 style.css 折进 client.js,删掉它 node scripts/verify-build.cjs # 校验:语法 / 加载契约 / CSS 内联 / 依赖集合 ``` 产物:`lib/client.js` 装入(**client 半边刷新页面即生效,不用重启 DSH**): ```powershell Copy-Item "lib\client.js" ` "C:\Users\ASUS 98\.dsh\profiles\desktop\node_modules\dsh-session-categories\lib\client.js" -Force ``` --- ## 目录说明 | 路径 | 作用 | |---|---| | `tsdown.config.ts` | 打包配置:`__ModuleLoader__` 信封、typert 别名、`deps.alwaysBundle` | | `tsconfig.base.client.json` | 基础 TS 配置(**故意不 extends 任何 dsh 内部文件**) | | `tsconfig.client.json` | 客户端半边配置 | | `scripts/inline-css.mjs` | **CSS 内联后处理**——见下,这步不能省 | | `scripts/verify-build.cjs` | 产物校验,exit=0 才算过 | | `packages/client/ui-session-categories/src/` | **源码**(补丁已合入) | | `packages/.../src/typert.remote-client.js` | 生成的 typert 运行时(供 alias 内联) | | `package.upstream.json` | 上游原始 `package.json`(发布清单,保留参考) | | `../upstream/` | 从 GitHub 拉的上游源码快照 | --- ## 三个坑(都会再踩,别省这一步) ### 1. 上游**不是**可构建仓库 `ht719/dsh-session-categories` 是从 dsh monorepo 搬出来的**源码快照**: - `packages/**/tsconfig.json` → `extends "../../../tsconfig.base.client.json"`(**不存在**) - 依赖 `../../../vendor/cordis`、`ui-slots`、`ui-primitives`…(**全不存在**) - `peerDependencies` 全是 `"workspace:^"`(**独立 clone 出来 `pnpm install` 都跑不通**) - `.gitignore` 里 `packages/**/lib/` ⇒ **产物是签入的,不是构建出来的** **正确的样板是** `resources/app/node_modules/dsh-community-market`: 独立仓库 + **实数版本** peerDeps(`0.2.0-rc.2`)+ 自带 `tsdown.config.ts`。 本工程的 `tsdown.config.ts` / `tsconfig*.json` 就是照它写的。 ### 2. `@tsdown/css` 是**自动加载**的,而且 `inject` 不是"内联" tsdown 源码里: ```js if (pkgExists("@tsdown/css")) { const { CssPlugin } = await import("@tsdown/css"); ... } ``` ⇒ **装了这个包它就自动生效,别在 config 里 `import css from '@tsdown/css'`** (它只导出具名 `CssPlugin`,**没有 default export**,import 了直接崩)。 而且 `css.inject: true` 的语义是「**保留 import 语句指向 CSS 文件**」—— **不是**把 CSS 内联进 JS。产物会变成: ```js import './style.css'; // ← 非法!它在 CJS 的 __ModuleLoader__ 信封里 window.__ModuleLoader__.load({ ... }) ``` **host 的模块加载器只给 bundle 一个 CommonJS `require`,根本没有 CSS loader。** ⇒ 所以必须跑 `scripts/inline-css.mjs`:它删掉那句 import,把 CSS 折成 `