ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Huly Core 深度指南:Huly 平台核心包库的架构、构建与二次开发实践

Huly Core 深度指南:Huly 平台核心包库的架构、构建与二次开发实践 Huly Core 深度指南Huly 平台核心包库的架构、构建与二次开发实践【免费下载链接】platformHuly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion)项目地址: https://gitcode.com/GitHub_Trending/platform80/platformHuly Core 是从 Huly 全栈项目管理平台中抽取出来的一组核心 TypeScript 包集合承载着 Huly 生态的底层数据模型、客户端访问层、文本处理引擎与平台运行基础设施。本文以 foundations/core/README.md 为主线结合仓库中 Rush 配置 与各包源码系统讲解 Huly Core 的包组成、环境要求、基于 Rush 的安装/构建/测试/发布全流程并延伸介绍 API Client 的编程式接入方式帮助你基于这些可复用的核心包构建自定义应用或集成 Huly 能力到现有项目。Huly Core 是什么Huly Core 是 Huly 平台核心包的独立集合位于本仓库的 foundations/core 目录。它是从 Huly Platform 中抽取出的基础构件包括核心数据模型core data models、客户端库client libraries、文本处理引擎text processing engines以及平台工具集platform utilities。这些包被设计为可复用、模块化、框架无关reusable, modular, framework-agnostic其目标场景有两个在 Huly Platform 之上构建自定义应用将 Huly 功能集成进已有项目。从目录结构看foundations/core/packages 下共维护了 26 个 npm 包全部以hcengineering/作用域发布。Rush 清单 rush.json 中每个包都声明了shouldPublish: true除内部脚本包hcengineering/scripts外表明它们都是面向 npm 生态对外发布的正式产物。包清单详解Core Packages数据模型与平台运行时hcengineering/core— 核心数据模型、类型定义与平台基础抽象。该包的 入口文件 对外导出classes、hierarchy、memdb、operations、operator、query、storage、tx、backup、versioning等模块。其中 classes.ts 定义了贯穿全平台的基石类型RefT强类型文档引用、Doc所有文档的基接口包含_id、space、modifiedOn、modifiedBy等统一字段、ClassT类描述符可携带domain、extends、implements、索引配置、AttachedDoc挂载到父文档的附属文档、Space空间模型以及AccountRole、Tx、Sequence、Blob等抽象。hcengineering/platform— 平台运行时、插件系统与依赖注入。核心源码在 platform.ts 中它定义了PRIPlatform Resource Identifier机制——几乎平台中的一切都是Resource通过形如core.string.ClassLabel的字符串标识来引用翻译文本、SVG 图标等资源并提供plugin()与mergeIds()用于声明插件 ID 命名空间、Id/Plugin/IntlString/StatusCode等类型化字符串。同包还包含 i18n、metadata、event、resource、status 等基础模块。hcengineering/model— 数据模型定义与 Schema 管理。其 dsl.ts 实现了一套模型 DSL用 TypeScript 装饰器与toposort拓扑排序收集ClassTxes将类定义自动转化为一系列Tx事务作为模型元数据供服务端加载与迁移使用。Client Libraries客户端访问与同步层hcengineering/client— 客户端数据访问与同步层负责前端与后端的实时数据同步。hcengineering/client-resources— 客户端共享资源与工具。hcengineering/api-client— 面向编程式访问的 API 客户端同时支持WebSocket与REST两种协议其完整使用文档见 api-client/README.md后文有专门章节展开。hcengineering/account-client— 账号管理客户端。hcengineering/collaborator-client— 实时协作文档客户端。hcengineering/hulylake-client— HulyLake 数据仓库datalake客户端。hcengineering/analytics与hcengineering/analytics-service— 分析与埋点工具及其服务端实现。Text Processing文本处理引擎文本处理是 Huly 文档/评论体系的重要底座这组包从底层引擎到上层格式逐层分工hcengineering/text-core— 核心文本处理引擎hcengineering/text— 高层文本处理工具其 src 下包含基于 ProseMirror/TipTap 的kit、nodes、marks、markup等扩展实现hcengineering/text-html— HTML 文本的渲染与解析hcengineering/text-markdown— Markdown 支持hcengineering/text-ydoc— Yjs 文档集成为协同编辑提供 CRDT 基础。Utilities平台工具hcengineering/query— 查询语言与执行引擎hcengineering/storage与hcengineering/storage-client— 存储抽象与实现、存储客户端hcengineering/rank— 基于 LexoRank 的排序工具Rank类型定义见 classes.tshcengineering/retry— 重试逻辑与容错模式hcengineering/rpc— RPC 通信层hcengineering/token— Token 管理与认证工具在 Rush 清单中以hcengineering/server-token发布。此外foundations/core/packages 目录中还维护着 README 未单独列出、但同样对外发布的辅助包measurements、measurements-otlp可观测性指标与postgres-basePostgreSQL 基础封装均在 rush.json 的projects清单中登记。环境要求与前置条件开始构建前系统需要满足依赖要求说明Node.jsv20.11.0 或更高README 要求实际 rush.json 中声明的支持范围更宽18.20.3 19.0.0 \|\| 20.14.0 25.0.0建议以 v20 LTS 为准Rush微软的可扩展 monorepo 管理工具本仓库锁定引擎版本5.158.1包管理器使用pnpm 10.15.1Rush 的 version selector 机制会保证全局安装的任意版本在仓库内按rushVersion声明表现一致common/scripts/install-run-rush.js等脚本也会自动使用该版本。安装与构建全流程安装首先全局安装 Rushnpm install -g microsoft/rush然后在仓库根目录即 foundations/core依次执行rush install rush buildrush install会按照 rush.json 中的pnpmVersion安装本地副本的 pnpm为全部 26 个包建立统一的依赖树与符号链接rush build按拓扑依赖顺序增量构建所有包。构建与热更新常用构建命令对照rush build # 增量构建所有包利用 build cache rush rebuild # 忽略缓存全量重新构建 rush build:watch # 开发模式以 watch 模式持续构建包含 build 与 validate 阶段其中rush build:watch在开发迭代时最为常用——修改任意包的源码后依赖它的包会被自动重编译配合rushx test可以快速完成开发闭环。项目结构更新当项目结构发生变化新增包、调整依赖关系时需要重新关联并重建rush update rush buildrush update会重新解析依赖树并更新common/temp下的安装产物通常在修改 rush.json 的projects清单或各包package.json依赖后执行。故障排查构建缓存如果构建失败但代码本身没有问题常见原因是本地 build cache 损坏。此时删除缓存并全量重建rm -rf common/temp/build-cache rush rebuildRush 的构建缓存机制详见 Rush 官方 build cache 文档仓库内该缓存路径位于 common/temp 下。测试执行全部包的测试rush test若要单独运行某个包内的测试进入该包目录后执行rushx testrushx是 Rush 项目内脚本的执行入口等价于在该包上下文内运行npm test。各包根目录均配置了独立的 jest.config.js例如core、platform包都有对应的src/__tests__目录存放单元测试。包版本管理与发布Huly Core 的版本发布使用仓库级脚本bump.js完成。对单个包进行版本号递增node ./common/scripts/bump.js -p projectName其中projectName替换为要发布的包名如hcengineering/core。该脚本位于 common/scripts/bump.js属于本仓库 monorepo 的公共工具链同目录下还提供sync-versions.js、check-versions.js等版本一致性维护脚本。每个包的变更历史记录在各自的 CHANGELOG.md 中。通过 API Client 编程式接入 HulyREADME 特别指出若想以编程方式与 Huly 交互应使用 API Client。它提供覆盖全部 Huly 操作的类型化接口可用来构建集成与自定义应用。以下要点均出自该文档。两种客户端WebSocket 与 RESTWebSocket 客户端connect与 Huly 平台 API 保持长连接适合实时同步场景REST 客户端connectRest使用标准 HTTP 请求执行操作适合一次性/低频率调用。两者使用相同的连接选项import { connect } from hcengineering/api-client // 使用邮箱密码连接WebSocket const client await connect(https://huly.app, { email: johndoeexample.com, password: password, workspace: my-workspace }) // 使用完毕后关闭连接 await client.close()REST 版只需将导入改为connectRest调用方式一致import { connectRest } from hcengineering/api-client const client await connectRest(https://huly.app, { email: johndoeexample.com, password: password, workspace: my-workspace })认证方式与连接参数客户端支持两种认证方式邮箱 密码或Token。认证成功后客户端拥有与对应用户相同的资源访问权限。urlHuly 实例地址如https://huly.appworkspace目标工作区名称可在工作区 URLhttps://huly.app/workbench/workspace-name中获取token可选认证 Token与邮箱密码二选一email/password可选账号凭据。使用 Token 连接import { connect } from hcengineering/api-client const client await connect(https://huly.app, { token: ..., workspace: my-workspace })查询findOne 与 findAll两个核心检索方法均接受三个参数_class目标类结果包含其全部子类、query查询条件与options可含limit、sort、lookup、projection、total。import { SortingOrder } from hcengineering/core import contact from hcengineering/contact // 查询单个文档 const person await client.findOne(contact.class.Person, { _id: person-id }) // 批量查询 排序 限制 const persons await client.findAll( contact.class.Person, { city: New York }, { limit: 10, sort: { name: SortingOrder.Ascending } } )文档 CRUDimport contact, { AvatarType } from hcengineering/contact // 创建文档 const personId await client.createDoc(contact.class.Person, contact.space.Contacts, { name: Doe,John, city: New York, avatarType: AvatarType.COLOR }) // 更新文档 await client.updateDoc(contact.class.Person, contact.space.Contacts, personId, { city: New York }) // 删除文档 await client.removeDoc(contact.class.Person, contact.space.Contacts, personId)集合Collections操作集合用于管理AttachedDoc——即挂载到父文档上的附属文档如联系人Person下的多个联系方式Channelimport contact, { AvatarType } from hcengineering/contact // 向集合中添加附属文档 await client.addCollection( contact.class.Channel, // 附属文档类 contact.space.Contacts, // 空间 personId, // 父文档 id contact.class.Person, // 父文档类 channels, // 集合名 { provider: contact.channelProvider.Email, value: john.doeexample.com } ) // 更新集合中的附属文档 await client.updateCollection( contact.class.Channel, contact.space.Contacts, channelId, personId, contact.class.Person, channels, { city: New York } ) // 从集合中移除附属文档 await client.removeCollection( contact.class.Channel, contact.space.Contacts, channelId, personId, contact.class.Person, channels )Mixins 扩展Mixin 允许在不改变原类的情况下为已有文档动态附加属性例如给Person增加员工Employee信息import contact, { AvatarType } from hcengineering/contact // 创建 mixin await client.createMixin( personId, contact.class.Person, contact.space.Contacts, contact.mixin.Employee, { active: true, position: CEO } ) // 更新 mixin 属性 await client.updateMixin( personId, contact.class.Person, contact.space.Contacts, contact.mixin.Employee, { active: false } )从源码理解核心抽象Huly Core 的设计可以用四个关键词概括类型化 ID 字符串RefT、Plugin、IntlString、ResourceT等都是带品牌标记branded type的字符串类型在编译期提供类型安全在运行期只是普通字符串便于序列化与网络传输见 classes.ts 与 platform.ts。事务Tx驱动的数据变更所有数据修改都以Tx形式表达TxCreateDoc、TxMixin、TxApplyIf等见 tx.ts客户端与服务端通过事务流实现同步与审计。类层次与 DomainClass描述符通过extends/implements构成继承体系并通过domain字段如DOMAIN_MODEL、DOMAIN_SPACE、DOMAIN_BLOB等见 classes.ts决定数据在底层存储中的归属配合IndexKind声明索引策略。插件化资源解析plugin()与mergeIds()将每个插件声明为一段扁平命名空间运行时按 PRI 加载翻译、图标等资源实现模块解耦platform.ts。许可证与生态Huly Core 以 EPL-2.0Eclipse Public License 2.0开源。在本仓库的 monorepo 布局中foundations/core是纯核心库层与 foundations/communication、foundations/net、foundations/server 等并列上层则由 models数据模型定义、plugins业务插件、pods服务部署单元等构成完整的 Huly 平台。对于开发者而言最直接的落地路径是参照上文在 foundations/core 下完成rush install与rush build随后基于hcengineering/core的模型抽象定义自己的Class与Space通过 api-client 的 WebSocket/REST 客户端与 Huly 服务端交互再利用text-markdown、text-html等文本包处理富内容即可在 Huly 平台上搭建出具备文档、任务与实时协作能力的自定义应用。【免费下载链接】platformHuly — All-in-One Project Management Platform (alternative to Linear, Jira, Slack, Notion, Motion)项目地址: https://gitcode.com/GitHub_Trending/platform80/platform创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进