# @client-compose/codegen 中文文档

规范地址：https://npmcn.com/package/%40client-compose/codegen/

版本：0\.12\.1
npm 元数据更新时间：2026-11-03T19:12:46.572Z
中文译文更新时间：2026-11-10T09:37:26.078Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40client-compose/codegen
原文对照：https://npmcn.com/package/%40client-compose/codegen/?lang=original
项目主页：https://github.com/client-compose/client-compose/tree/main/codegen#readme
源码仓库：https://github.com/client-compose/client-compose

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：309 kB，43 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：0 个
- 首次发布：2026-10-19T14:06:35.079Z
- 最新版本发布：2026-11-03T19:12:46.211Z
- 近 30 天下载量：1787（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：13（近 12 个月 13 个）

## 中文简介

从客户端编译岛列表中生成Go和TypeScript的岛道具类型.

## 安装

```sh
npm install @client-compose/codegen
```

也可以使用：`pnpm add @client-compose/codegen`、`yarn add @client-compose/codegen`、`bun add @client-compose/codegen`

## README

# @ lient- compose/ 编码源

产生岛的道具类型 从岛的每个堆 清单,所以作曲家和 每个应用程序都通过建筑而不是手来商定每个岛屿的道具.

```sh
npx @client-compose/codegen client-compose.codegen.json            # write
npx @client-compose/codegen client-compose.codegen.json --check    # CI: exit 1 if out of date
npx @client-compose/codegen compat client-compose.codegen.json --base origin/main
                                                                   # CI: exit 1 on breaking changes
npx @client-compose/codegen strings client-compose.codegen.json    # CI: check the strings catalog
```

转到输出格式化 `gofmt` 如果你的路径。 (在此重播中, 运行 `node codegen/cli.ts …` 直接使用源。 )

## 安装

**有节点20+:** `npx @client-compose/codegen …`,或添加 `@client-compose/codegen` 是一个非常依赖.

**没有节点** (去项目):单独下载 `client-compose-codegen` 用于您平台的可执行文件 [代码释放](https://github.com/client-compose/client-compose/releases?q=%40client-compose%2Fcodegen&expanded=true)数字 : `linux-x64`, (中文(简体) ), `linux-arm64`, (中文(简体) ), `darwin-x64`, (中文(简体) ), `darwin-arm64` 或者说 `windows-x64`,带有 `SHA256SUMS` 要校验的文件 这个 例如,通过GitHub CLI:

```sh
gh release download "@client-compose/codegen@0.2.0" -R client-compose/client-compose \
  -p "client-compose-codegen-darwin-arm64" -p SHA256SUMS
shasum -a 256 --check --ignore-missing SHA256SUMS
chmod +x client-compose-codegen-darwin-arm64 && mv client-compose-codegen-darwin-arm64 /usr/local/bin/client-compose-codegen
```

二进制与 npm 包的参数相同 。 他们没有公证,所以在macOS一个副本 通过浏览器需要下载 `xattr -d com.apple.quarantine <file>` 在它运行之前 (负载 `gh` 或者说 `curl` 别.

## 配置

`client-compose.codegen.json` (路径相对于此文件; 仅配置您使用的目标):

```json
{
  "manifests": "islands",
  "actions": "actions",
  "targets": {
    "go": { "out": "composer-go/islands_gen.go", "package": "main" },
    "typescript": { "out": "web/islands.generated.ts", "protocolImport": "@client-compose/protocol" }
  }
}
```

`actions` 可选:为每个目标生成的行动清单(第5段)。 A 类 配置可能只包含 `actions`。 。 。 .

对于实体(第2.1项),添加 `"entities": "entities"`,一个实体列表。 见 [实体](https://npmcn.com/package/%40client-compose/codegen/#readme-entities)。 。 。 .

对于几种显示共享类型(第2.2段),添加 `"types": "types"`,类型目录 名单 见 [共享类型](https://npmcn.com/package/%40client-compose/codegen/#readme-shared-types)。 。 。 .

对于字符串(第4.7段),添加 `"appStrings": "app-strings.json"` (应用字符串显示), `"screenStrings": "screen-strings.json"` (每个屏幕自己的字符串,用于Go和TypeScript作曲), `"catalog": "strings"` (目录) `<locale>.json` 如果不是作曲家服务的文件) `en`, (中文(简体) ), `"defaultLocale"`。见 [字符串](https://npmcn.com/package/%40client-compose/codegen/#readme-strings)。 。 。 .

在Go项目中,a `//go:generate client-compose-codegen <config>` (或 `npx @client-compose/codegen <config>`(行让) `go generate` 运行它 (见 [`examples/todo/composer-go/main.go`](https://github.com/client-compose/client-compose/blob/main/examples/todo/composer-go/main.go)) (中文(简体) ).

## 你得到的东西

对于 `profile-header` v2, 每个目标生成 a `ProfileHeaderV2` 了解自身类型 岛屿类型和版本,所以注册不能给岛屿取名错误:

| 堆栈 | 已生成 | 用作 |
| --- | --- | --- |
| 走开 | `struct` + 键 `IslandType()` 编号 : `IslandVersion()` 方法 | `cc.Define(func(ctx, r) (ProfileHeaderV2, error) { … })` |
| 类型脚本 | `interface` +描述符 `const` 名称相同 | `registry.register(ProfileHeaderV2, (props) => …)`, (中文(简体) ), `island(ProfileHeaderV2, resolve)` |

供采取行动 `follow-user` v1( 第5.1节) :

| 堆栈 | 已生成 | 用作 |
| --- | --- | --- |
| 走开 | `FollowUserV1Input` (与其行动、版本、输入计划和结果类型挂钩), `FollowUserV1Result`,并且每个声明错误都有一个错误类型,例如:. `FollowUserV1Blocked` | `cc.DefineAction(func(ctx, call, in FollowUserV1Input) (FollowUserV1Result, cc.Effects, error) { … })`返回时 `FollowUserV1Blocked{}` 作为错误 |
| 类型脚本 | `FollowUserV1Input`, (中文(简体) ), `FollowUserV1Result`,则 `FollowUserV1Error` 工会,以及 `FollowUserV1` 描述符 | `action(FollowUserV1, perform)` 在作曲家, `callAction(…, FollowUserV1, input)` 或者说 `useAction(FollowUserV1)` 在应用程序中 |

## 实体

一个实体命名一些岛屿, 所以一个动作可以说它有什么变化 (第2.1和5.3节)。 每一个都显示在 `entities` 目录和岛道具标记对象 显示一个与 `entity`数字 :

```json
// entities/todo.json
{ "entity": "todo", "id": "id", "properties": { "id": { "type": "string" }, "title": { "type": "string" }, "done": { "type": "boolean" } } }

// in an island's props
"todos": { "type": "array", "items": { "type": "object", "entity": "todo", "required": ["id", "title"], "properties": { … } } }
```

代码源检查每个标记对象: 它有实体的ID, 需要, 以及每个实体的 它显示的属性有实体的设置。 它可能有自己的属性. `compat` 将标出或未标出对象视为断裂变化.

| 堆栈 | 已生成 | 用作 |
| --- | --- | --- |
| 走开 | `TodoEntity`每一个财产,除了id,每一个可选的; `IslandEntities()` 在拥有实体的岛屿上 | `cc.Set("3", TodoEntity{Done: &done})`, (中文(简体) ), `cc.Delete[TodoEntity]("3")` |
| 类型脚本 | `TodoEntity` 及其描述者; `entities` 岛上的描述 | `changed(TodoEntity, "3", { done: true })`, (中文(简体) ), `deleted(TodoEntity, "3")`; 客户端使用描述符应用更改' `entities` |

## 共享类型

当若干岛屿、行动或实体拥有相同形状时(图像、个人徽章、a) ,定义一次并参考一次。 每一个都显示在 `types` 目录:对象,或 字符串语句,与其它语句相同。 类型可能指另一个类型,但不指 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}我们自己来.

```json
// types/image.json
{ "type": "image", "description": "A picture.", "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri" }, "width": { "type": "integer" } } } }

// anywhere a schema can be: an island's props, an action's input, result or error details, an
// entity's properties, or another shared type
"cover": { "$ref": "image", "description": "Shown at the top." }
```

仅说明( E)`description`, (中文(简体) ), `title`, (中文(简体) ), `$comment`, (中文(简体) ), `examples`可以坐在旁边 `$ref`类型 生成一次,以其自己的名字(`Image`,有巢类类似 `ImageFocus`和每个 引用使用它,所以一个帮助者或组件可以在它出现的地方带走它. 到处都有计划 嵌入或比较(作曲者用来验证的动作输入方案,实体检查), 参考书目被写出,所以参考书目完全指现存类型的写作会是什么. `compat` 判断每个岛屿改变为共同类型,并根据它们的规则采取行动: 给一个共享的enum添加一个值 是打破它使用的地方.

代码源生成 Go 和 TypeScript 。 斯威夫特和克特林的目标 与他们的客户 需要一个维护者回来.

## 字符串

每个应用节目的词出自作曲家(spec §4.7). 岛屿表宣布 由按键组成的字符串,每个参数都填入,以及 `counted` 对于一个言语依赖 `count`数字 :

```json
"strings": {
  "heading": { "description": "Over the list." },
  "greeting": { "params": ["name"] },
  "articleCount": { "params": ["count"], "counted": true }
}
```

App string express 声明属于无岛的词(一个占地者"Loading","Loading"), a 验证信息),格式相同: `{ "strings": { … } }`。每个目标生成一个类型 其成员是弦:为无正框者提供正文,为具有下列功能者提供功能:

| 堆栈 | 已生成 | 用作 |
| --- | --- | --- |
| 类型脚本 | `ArticleListV1Strings`和描述器的 `strings`· ; `AppStrings` | `props.t.articleCount({ count })` 在登记的组成部分中; `useAppStrings(AppStrings).retry` |

单词是目录,每个语言一个文件,例如. `strings/pl.json`数字 :

```json
{
  "app": { "retry": "Spróbuj ponownie" },
  "islands": {
    "article-list@1": {
      "heading": "Najnowsze",
      "greeting": "Cześć {name}",
      "articleCount": { "#0": "Brak artykułów", "#one": "{count} artykuł", "#few": "{count} artykuły", "#*": "{count} artykułów" }
    }
  }
}
```

屏幕的自有弦是其作曲家使用自己的词,例如其元标题. 屏幕 字符串显示通过屏幕标识来宣告, `{ "screens": { "author": { "title": { "params": ["author"] } } } }`,目录里有 `screens`开始 `AuthorScreenStringsFor(r).Title(name)`; 类型脚本, `lc.strings(AuthorScreenStrings).title({ author })`。 。 。 .

已计数字符串的变体键入 `#<number>`, (中文(简体) ), `#<category>` (CLDR's `zero`, (中文(简体) ), `one`, (中文(简体) ), `two`, (中文(简体) ), `few`, (中文(简体) ), `many`, (中文(简体) ), `other`)或(或) `#*`,按此顺序选择. `strings` 检查目录与 显示:默认语言必须拥有每个字符串;缺少一个字符串的则得到警告 回到默认的。 未知的钥匙和岛屿,变体 `#*`,字符串上的变体 这不算,和 `{slots}` 而不是参数是错误.

## 支持的计划子集

化身使用JSON Schema的一个特意小分集. 外面的任何东西都会被拒绝 错误,所以一个表 永远不能指不同语言中不同的事物.

| 司马 | 走开 | 类型脚本 |
| --- | --- | --- |
| `string` | `string` | `string` |
| `string`, (中文(简体) ), `format: uri` | `string` | `string` |
| `string`, (中文(简体) ), `enum: [...]` | 名称 `string` 类型 + conss | 字符串结合 |
| `integer` | `int` | `number` |
| `integer`, (中文(简体) ), `format: int64` | `int64` | `number` |
| `number` | `float64` | `number` |
| `boolean` | `bool` | `boolean` |
| `array` 与 `items` | `[]T` | `T[]` |
| `object` 与 `properties` | 名称结构 | 命名接口 |
| `object` 与 `additionalProperties` | `map[string]T` | `Record<string, T>` |
| 没有在 `required` | a. 指针,或为零; `omitempty` | `prop?:` |

共享类型( E)`{ "$ref": "image" }`)成为它自己命名的类型:见 [共享类型](https://npmcn.com/package/%40client-compose/codegen/#readme-shared-types)。 。 。 .

还允许: `description` (成为医生的评论), `title` (命名为巢型), `$comment`, (中文(简体) ), `examples`。不支持 : `$ref` 除了同一类人的名字之外, `oneOf`编号 :`anyOf`编号 :`allOf`类型工会, `null`, (中文(简体) ), `pattern`, (中文(简体) ), `minimum` 和其他校验关键词,格式 `uri`, (中文(简体) ), `int32` 财务报告和审定财务报表 `int64`。 。 。 .

**取名问.** 巢穴类型以其属性来命名(`author` → `Author`),或之后 `title` 如果设置。 没有标题的矩阵项目获得一个 `Item` 后缀和地图值a `Value` 后缀. Go 和 TypeScript 将它们平整(`PostGridV1Post`) (中文(简体) ). 共享类型以自身命名 (单位:千美元)`image` → `Image`)),其名称不可能是相形见绌的生成. 地产名称为骆驼卡塞德(去:PascalCased 有标准 初始化,例如:. `avatarUrl` → `AvatarURL`),保留了原JSON密钥.

## 清单的兼容性规则

Apps和作曲家独立部署,而旧的App版本长期被安装. 所以,一个岛屿版本的改变必须保持 **两者** 工作方向: 旧应用程序解码 新作曲家的有效载荷,以及新作曲家旧作曲(apps可先发作)的解码. 客户端跳过 道具不解码的岛屿(secret §4.4),所以一次突破性的改变悄悄地隐藏了该岛.

| 一岛版内的变化 | 允许? |
| --- | --- |
| 添加可选属性 | ✅ |
| 删除可选属性 | qq 旧应用程序已经处理它 缺席 |
| 变动 `description` 或者说 `title`,重新排列enum值 | 页:1 `title` 更改重命名生成的类型, 您的编译器将指出这些类型) |
| 添加所需的属性 | 新应用程序拒绝尚未发送的作曲家的有效载荷 |
| 删除所需的属性 | 旧的应用程序需要它 |
| 选择或要求财产 | ❌ |
| 更改类型, `format`,或整数大小 | ❌ |
| 添加或去除 enum 值 | qq应用无法解码他们不知道的值 |
| 删除岛屿版本 | {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}但是只支持这个版本的应用程序 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}停止接收这个岛 |

在 a 中进行分解更改 **新岛版** (新设) `profile-header.v3.json`和保持旧的 已经发布的应用程序版本 .

在一个岛屿版的字符串和应用程序字符串可以添加,它们的描述和 词变了 删除一个, 改变其参数, 或使其计数或不计数, 正在打破: 已释放 应用程序仍然显示, 与他们建造的参数.

行动遵循同样的规则(第5.1节)。 已发布应用程序继续发送旧输入和解码 结果和错误细节,所以 `input`, (中文(简体) ), `result` 每个错误 `details` 遵循上表. 由于客户端将未知代码视为通用代码,可添加或删除已声明的错误代码 失败。 给出已有错误 `details`或者把他们带走 是破碎的 删除动作 版本只警告: 应用程序仍然称它得到 `unsupported_action_version`。 。 。 .

### 在CI里检查

`compat` 与先前的状态相比

```sh
client-compose-codegen compat client-compose.codegen.json --base origin/main   # a git ref
client-compose-codegen compat client-compose.codegen.json --base-dir ./old-islands
```

```text
✖ profile-header v2 · props.badge: became required: new apps would reject payloads from a composer that omits it

1 breaking change(s) in client-compose.codegen.json compared with origin/main.
Put them in a new island version instead (profile-header v3), and keep the old version for apps already released.
```

在 GitHub 动作中,请查看 `fetch-depth: 0` 通过 `--base "origin/$GITHUB_BASE_REF"` 牵出 请求.

## 测试

[`codegen/test/fixtures/islands`](https://github.com/client-compose/client-compose/tree/main/codegen/test/fixtures/islands) 覆盖每个支持 特性。 它所生成的输出通过Go和TypeScript的测试被编译并解码.

## 常见问题

### @client-compose/codegen 是什么？

从客户端编译岛列表中生成Go和TypeScript的岛道具类型\.

### 如何安装 @client-compose/codegen？

在项目目录运行 npm install @client-compose/codegen，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 client-compose-codegen，可以用 npx client-compose-codegen 直接运行。

### @client-compose/codegen 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @client-compose/codegen 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @client-compose/codegen 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @client-compose/codegen 可以商用吗？

@client-compose/codegen 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @client-compose/codegen 的下载量有多少？

根据 npm 官方下载统计，@client-compose/codegen 在 2026/10/10 – 2026/11/08 这 30 天内被下载 1,787 次，日均约 60 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @client-compose/codegen 还在维护吗？

最新版本 0\.12\.1 发布于 2026/11/04（6 天前）；至今共发布 13 个版本，其中过去 12 个月发布了 13 个；首次发布于 2026/10/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

