FORMA

内部插件 / 工具库开发实践

1. 背景与目标

在企业前端项目中,utilshookslibs 这类通用能力通常分散在多个仓库,常见问题包括:

  • 各项目重复拷贝“可能有用”的工具函数;
  • 实际使用面窄,沉淀质量不高;
  • 规则变更难以同步,版本漂移严重;
  • 引入后无人维护,逐渐演变为“幽灵依赖”。

因此,建设内部工具库的核心目标是:

  • 统一沉淀:一处维护、多处复用;
  • 可治理:有版本、有变更记录、有发布流程;
  • 可协作:可评审、可测试、可追溯;
  • 可扩展:逐步形成团队工程规范与能力平台。

2. 技术选型与原则

2.1 推荐组合

  • Monorepo + pnpm workspace:统一管理多包依赖与联调;
  • TypeScript:对外暴露稳定类型,降低接入歧义;
  • Vite Library Mode(底层使用 Rollup):生成 ESM/CJS 产物(如确有需要再补 UMD);
  • 测试框架(如 Vitest)+ 类型检查 + Lint:作为发布门禁。

2.2 选型原则

  • 优先简单可维护:先解决 80% 场景,不做过度抽象;
  • 以复用数据驱动收录:只有跨项目验证过价值的能力才进入公共库;
  • 先规范后规模:先定义目录、命名、发布与回滚机制,再扩大模块范围。

2.3 暂缓项说明

  • 暂不引入 Rust 等异构语言封装。对于前端工具库,过早引入跨语言链路会增加构建复杂度与维护成本;仅在明确性能瓶颈且收益可量化时评估。

3. 包设计与功能边界

建议将“工具库”拆分为多个职责清晰的包,避免单包无限膨胀:

  • @org/utils:通用函数(日期、数值、字符串、节流、防抖等);
  • @org/validators:校验规则与校验器(手机号、邮箱等);
  • @org/hooksVue 3 组合式逻辑(分页、加载态、弹窗状态管理等);
  • @org/request(规划中):HTTP 客户端工厂(拦截器、重试、错误策略);
  • @org/tracking(规划中):埋点上报适配层。

收录边界建议:

  • 与具体业务强耦合的逻辑不进入公共库;
  • 与 UI 框架强绑定的组件单独维护(如后续拆分 ui-library);
  • 每个导出函数必须有类型声明、示例和最小测试用例。

4. 工程结构建议(Monorepo)

可参考如下目录结构:

text
packages/
  utils/
  validators/
  hooks/
  request/
  tracking/

每个包建议至少包含:

  • src/:源码;
  • package.json:导出字段(exportstypessideEffects);
  • tsconfig.json:包级类型配置;
  • README.md:安装、示例、变更说明;
  • CHANGELOG.md:版本变更记录。

5. 构建、发布与版本治理

5.1 构建建议

  • 产物优先提供 ESMCJS,满足主流工程环境;
  • 标记 sideEffects,帮助 Tree Shaking;
  • 保证 .d.ts 声明文件随产物一并发布。

5.2 版本策略

采用语义化版本(SemVer):

  • MAJOR:不兼容变更;
  • MINOR:向后兼容的新功能;
  • PATCH:向后兼容的问题修复。

发布前应明确:

  • 变更影响范围;
  • 是否需要迁移说明;
  • 是否需要提供回滚版本。

5.3 发布门禁(建议)

在 CI 中至少串联以下检查:

  1. lint + typecheck
  2. test
  3. build
  4. 变更日志校验(确保每次发布有记录)

6. 安装与分发方式

6.1 方式一:通过私有 npm 源安装(推荐)

适合团队常规协作,统一依赖来源与版本审计。

bash
# 配置作用域私有源(示例)
npm config set @your-scope:registry https://nexus.example.com/repository/npm-private/

# 安装
pnpm add @your-scope/functional-helpers

说明:

  • 推荐使用“作用域级别 registry”而不是全局切换源,避免影响公共包下载;
  • 私服建议启用 HTTPS、访问控制与审计日志。

6.2 方式二:指定 tarball 地址

适用于试点阶段或临时验证,不希望调整全局源配置。

json
{
  "dependencies": {
    "@your-scope/functional-helpers": "https://nexus.example.com/repository/npm-private/@your-scope/functional-helpers/-/functional-helpers-1.0.0.tgz"
  }
}

6.3 方式三:离线文件依赖(隔离网络 / 特殊 CI)

json
{
  "dependencies": {
    "@your-scope/functional-helpers": "file:./functional-helpers-1.0.0.tgz"
  }
}

适用场景:

  • 受网络策略限制,构建节点无法访问私服;
  • CI 通过缓存机制提前准备好发布包。

7. 质量保障与协作规范

7.1 文档与示例

  • 每个包提供最小可运行示例;
  • 关键 API 给出输入/输出示例与边界行为说明;
  • 明确“稳定 API”与“实验性 API”。

7.2 贡献流程

  • 统一分支策略与提交规范(Conventional Commits);
  • PR 必须包含:变更说明、测试结果、影响评估;
  • 发布由 CI 执行,尽量避免本地手工发布。

7.3 兼容与回滚

  • 重大升级前给出迁移指南;
  • 保留最近稳定版本的回滚通道;
  • 对高风险改动提供灰度接入方案。

8. 后续规划

  • 按复用度逐步引入 requesttracking 等基础能力;
  • 对接内部脚手架,支持初始化时按需安装工具包;
  • 建立版本更新提醒机制(如在 CI 检测可升级版本);
  • 周期性清理低使用率 API,控制包体积与维护成本。

参考文献

  1. pnpm 官方文档
    https://pnpm.io/
  2. Vite 文档:Library Mode
    https://vite.dev/guide/build.html#library-mode
  3. TypeScript 官方文档
    https://www.typescriptlang.org/docs/
  4. npm 文档:scope 与 registry 配置
    https://docs.npmjs.com/cli/v10/using-npm/scope
    https://docs.npmjs.com/cli/v10/using-npm/config#registry
  5. SemVer 官方规范
    https://semver.org/
  6. Conventional Commits
    https://www.conventionalcommits.org/
  7. Sonatype Nexus Repository(npm)
    https://help.sonatype.com/en/npm-registry.html