关于 adding-dependencies
一项指导工程 Agent 判断是否引入依赖,并评估、锁定、记录和移除依赖的软件工程技能;使用前需具备 `principal-engineering` 技能。
主要功能
- 01优先用现有代码与平台能力
- 02评估依赖成本和维护状况
- 03记录新增依赖的理由
- 04锁定版本并测试更新
- 05用途结束后移除依赖
适用场景
- 01为新功能评估软件包
- 02规划依赖版本更新
- 03审查项目依赖策略
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ riekelt/ principal-engineer --skill adding-dependencies安装后在 Claude Code 中输入/adding-dependencies确认已加载。
详细介绍
添加依赖
必需的背景知识: principal-engineering 技能。
概述
依赖就像一名新雇员,而不是一段代码:引入功能的同时,也引入了它的缺陷、发布节奏、传递依赖树,以及维护者的精力。核心原则:先用尽已有资源,再审慎评估要引入的依赖,固定版本,并记录原因。
用尽已有资源
按列表逐项检查,遇到满足需求的层级就停下;好的方案往往会组合两个层级:用现有依赖处理难点,再围绕它写几行自己的代码:
- 需求本身。 推测性的需求不算需求;跳过它,并用一句话说明。
- 此代码库。 几个文件之外就有能解决问题的辅助函数、类型或模式;复用它。重复实现仓库已有的内容,是
keeping-one-source-of-truth禁止的数据缺陷。 - 标准库。 安装重复实现标准库功能的包之前,先查看标准库索引。
- 平台。 用数据库约束替代应用代码,用原生控件替代控件库,用运行时自身的原语替代封装。
- 项目已经携带的依赖。 它的传递依赖成本已经支付。注意两个界限。开始使用传递依赖,就会使它成为新的直接依赖:声明它,将版本固定为已解析的版本,并进行简单评估,因为这段代码已经随项目发布。检查复用跨越的类别:将开发工具的传递依赖提升为运行时依赖,会把成本转嫁给每位使用者的安装过程,而不只是 CI。
- 自己写几行代码。 如果确实只需要二十行,那么维护二十行代码胜过维护别人的整个仓库。
- 只有前六项都不行时: 才引入新依赖,并按下文进行评估。
评估要引入的依赖
- 核算整份“雇用”成本:它带来的传递依赖树、安装和构建负担、与项目许可证的兼容性、安全记录(安全公告,以及扫描器可用时的供应链评分)。
- 检查活跃情况:近期发布情况、问题的响应方式,以及有多少人可以合并代码。选择一个精疲力竭的维护者负责的关键依赖,就是在主动承担风险。
- 阅读你将调用的部分:了解你所依赖的 API 接口和故障模式,而不是 README 中的承诺。扎实求证同样适用于他人的代码。
- 优先选择只做一件事的工具,而不是包含四十项功能的框架;另外三十九项功能仍会随之而来,增加体量和攻击面。
- 记录决策。 新依赖是一项决策:记录它的用途、考虑过哪些替代方案,以及在什么条件下将其移除(如果已安装
recording-decisions,请通过它记录)。
依赖策略
依赖容忍度应由项目自行声明,就像项目的风险等级一样:完全自包含(有些应用确实应该全面禁止外部代码)、采用精选的允许列表,或经过评估后再添加。项目规则或 CLAUDE.md 会说明采用哪种策略;如果没有说明,就询问系统绝不能依赖什么,并将答案视为策略声明。即使不方便,也必须遵守既定策略;更改策略需要记录为一项决策,而不是直接执行 npm install。
未声明策略不构成硬性阻碍:如果现在无人能给出答案,就按明确说明的假设策略继续,在决策记录中写明这一假设,并指定负责人跟进策略声明问题。
固定版本并验证
- 提交锁文件并固定版本;CI 或基础镜像中未固定的
latest,就像一颗按照别人时钟倒计时的定时炸弹。 - 更新和其他变更一样。升级主版本之前,先阅读发布说明(先了解破坏性变更和迁移要求)。针对更新后的版本运行测试(
testing-changes)。主版本升级应单独提交,以便清晰追溯;多个补丁版本升级可以合并提交。 - 引入的第三方代码必须在代码树中注明来源和版本;无法确定日期的内容,就无法更新。
移除
- 某项依赖的用途消失后,应在移除该用途的同一次变更中一并移除;为了“以防万一”而保留某个包,是第 1 级所说的臆测需求的反面。
- 当依赖只剩一个小型调用点时,可以考虑自己实现那几行代码。
- 无人维护但又不可或缺的依赖,是一项需要指定负责人并制定计划的风险,而不是寄希望于它一直可用。
常见错误
- 小工具冲动:代码树不是靠重大决策长大的,而是一次添一个小包,每个包单独看都合情合理。
- 为调用一个函数而安装一个框架。
- 依赖某个包的内部实现或私有路径;只有公开契约才有保障。
- 把传递依赖当成自己的依赖来导入:今天未声明,下次刷新锁文件时就会消失。如果需要它,就声明它。
- 为了避免阅读仓库中已有的代码而添加依赖(跳过了第 2 级)。
- 未注明来源就复制代码,之后却想不起来复制的是哪个版本。
- 一次性更新所有内容,然后再用二分查找找出哪个升级导致构建失败。
评论
支持 Markdown