共享包开发
shared/ 放跨子项目复用的代码。目前有三个包,全部源码直出:main 与 exports 直接指向 src/index.ts,
没有构建步骤,子项目用 workspace:* 引用。改动即时生效,但也意味着没有编译期保护(见第五节)。
| 包 | 用途 | 引用方 |
|---|---|---|
@cikio/types |
跨项目共享的领域类型(当前是消息中心的类型) | ccu/、message/、forum/ |
@cikio/utils |
通用工具函数 | ccu/、message/ |
@cikio/moderation |
内容审核判定与留痕(纯逻辑库 + 词库脚本 + 迁移) | authserver/、ccu/、forum/ |
一、目录与配置
Section titled “一、目录与配置”shared/├─ package.json # name: cikio-shared,私有包;只提供 typecheck├─ tsconfig.json # 工作区统一编译口径└─ packages/ ├─ types/ { package.json, tsconfig.json, src/index.ts, src/message.ts } ├─ utils/ { package.json, tsconfig.json, src/index.ts } └─ moderation/ ├─ package.json tsconfig.json README.md wrangler.toml ├─ src/ # 源码 + *.test.mjs ├─ scripts/ # 词库抓取 / 导入 / 发布脚本 └─ migrations/ # D1 表结构(共享库 cikio-moderation)shared/tsconfig.json 的口径是 target: ES2022、module: ESNext、moduleResolution: Bundler、
strict: true、allowImportingTsExtensions、isolatedModules、verbatimModuleSyntax。
新包直接沿用这份配置,不要各写一套。
pnpm-workspace.yaml 里 shared/packages/* 是通配,所以在 packages/ 下新建目录会自动成为工作区成员,
不需要改根配置。
二、每个包的 package.json 模板
Section titled “二、每个包的 package.json 模板”{ "name": "@cikio/xxx", "version": "0.0.0", "private": true, "type": "module", "main": "./src/index.ts", "types": "./src/index.ts", "exports": { ".": "./src/index.ts" }, "files": ["src"], "scripts": { "typecheck": "tsc --noEmit" }}要点:
private: true+version: 0.0.0:不发 npm,只做工作区内部引用。- 三个入口字段(
main/types/exports)都指向src/index.ts,这是「源码直出」的全部机制。 - 需要子项目直接引子路径时,在
exports里显式加一条,别让引用方写深层相对路径。
子项目里这样引用:
import type { Message, MessageId } from '@cikio/types';import { formatDate } from '@cikio/utils';依赖必须写 "@cikio/xxx": "workspace:*"。改完依赖记得 pnpm install 并提交根 pnpm-lock.yaml。
三、@cikio/moderation:一个完整例子
Section titled “三、@cikio/moderation:一个完整例子”它是唯一带运行时逻辑、测试与数据库迁移的共享包,可以作为后续共享包的样板。
-
职责:给定文本,返回审核判定(放行 / 送审 / 替换 / 拦截)与命中明细;判定结果另行落库留痕。
-
源码模块:
types/normalize(归一化,处理同形字与干扰字符)/matcher(引擎)/policy(动作策略)/snapshot(词库快照读写)/moderator(对外主入口)/records(明细落库)/word-input(词库录入校验)。 -
零运行时依赖:只用平台 API(KV / D1 由调用方注入),便于被 Worker 直接打包。
-
测试:
node --test "src/**/*.test.mjs"(Node 内置 runner,不引测试框架):终端窗口 pnpm --filter @cikio/moderation test -
数据:表结构在
shared/packages/moderation/migrations/,作用于共享库cikio-moderation; 词库快照走 KV(bindingMODERATION_WORDS)。包内wrangler.toml不是部署单元, 只用于跑迁移与脚本。 -
词库脚本:
scripts/下区分抓取(fetch-lexicon.mjs)、导入(import-lexicon.mjs)、 发布快照(publish-wordlist.mjs),共用lib.mjs。 -
降级口径:调用方在词库读不到时按「放行 + 标记 degraded + 记日志」处理,不静默失败,也不误拦用户。
接入方(authserver、ccu、forum)通过各自的 D1 与 KV binding 传入数据库与词库,不要在业务站里另建一份敏感词表。
四、改动与验证
Section titled “四、改动与验证”pnpm --filter shared typecheck # 或 pnpm typecheck(会带上所有子项目)pnpm --filter @cikio/moderation test # 有测试的包pnpm build # 确认引用方仍能构建共享包的改动会影响所有引用方,提交前至少跑一次全量 pnpm typecheck 与 pnpm build。
五、两条必须知道的约束
Section titled “五、两条必须知道的约束”- 没有编译期保护:包是
.ts源码直出,没有独立的构建/类型产物,改坏了引用方也不会在pnpm install时报警, 只在类型检查或运行时暴露。改导出签名时务必自己跑一遍引用方的typecheck。 - 不要往里塞业务:只放真正被两个以上子项目用的东西。单站专用逻辑留在该站内部, 否则共享包会变成谁都改不动的大杂烩。