# 共享工具与常量规范

> 重复代码的识别、共享归属、运行环境边界与行为兼容要求。

来源：https://next-docs.purechat.cn/development/code-sharing

抽取重复代码的目的是让同一规则只有一处实现。先核对调用方的输入、输出和失败路径，再决定是否共享。

## 共享代码放在哪里 [#共享代码放在哪里]

| 场景               | 归属                            |
| ---------------- | ----------------------------- |
| 跨 workspace 的纯函数 | `@pure/utils` 的明确子路径          |
| DOM、剪贴板与 Blob 下载 | `@pure/utils/client`          |
| Node、密钥或服务端资源    | `@pure/utils/server` 或服务端领域模块 |
| 跨包稳定常量、枚举与简单规则   | `@pure/const`                 |
| 模型目录与默认模型        | `@pure/model-bank`            |
| 仅在主应用复用的常量       | `src/const`                   |
| 社区、后台或渠道专属行为     | 对应功能域的共享 helper / hook        |

共享包不得反向导入主应用。客户端不得因一个校验函数导入数据库或服务端模块；优先使用只包含所需能力的入口，避免通过巨型 index 混入不兼容依赖。

## 抽取条件 [#抽取条件]

* 至少两个真实调用方承担同一业务规则，或已有公共工具可以直接复用。
* 优先使用标准库和已经安装的依赖，不为小 helper 新增依赖或转发封装。
* 细微差异用少量有含义的参数或字段访问函数表达；若需要一串开关描述不同流程，应保留独立实现。
* UI 提示留在组件 / hook；工具只返回结果或抛出原有错误。
* 不把一个页面的所有局部变量搬进全局 const。跨页面稳定常量才上提，领域常量就近维护。
* 不合并仅仅数值相同的超时、上限和默认值。历史迁移快照必须独立维护。
* 只读常量可以共享；会被修改的默认对象由调用端创建，避免页面之间共享可变状态。

## 必须保留的行为 [#必须保留的行为]

评估空值、空字符串、数组、非法输入、排序、时区、地区、精度和异常回退。尤其注意：

* `isObjectLike` 接受数组，`isRecord` 排除数组，不能机械替换。
* `getErrorMessage` 只读取真正的 Error；不自动接受带 message 字段的普通对象，也不把空消息替换成回退文案。
* URL 校验按用途命名。服务商地址的严格规则不能替代搜索链接或下载地址的规则。
* 可取消等待必须保留调用端原来的 resolve / reject 选择。
* 带剪贴板降级的函数和需要展示权限失败的复制交互不能混用。
* 保留接口响应、存储键、历史配置版本与外部可见导出；重命名内部实现时同步迁移全部调用方。

## 检查与后续治理 [#检查与后续治理]

每次修改相关功能时搜索同类 helper 和常量，优先复用。记录重复位置、行为差异、共享归属与验证结果；无法保持行为的候选记录原因后保留。

纯函数测试覆盖实际分支和边界，副作用测试验证资源清理与错误传播，不新增只断言页面骨架的组件测试。根项目与 workspace package 分开运行测试，交付前执行 [质量检查](./quality/lint.md)。样式共享遵循 [Tailwind 规范](./styling/tailwind-guidelines.md)。
