libyear将依赖落后版本转化为“落后年数”,直观识别技术债;它基于版本发布时间差计算Libyears Behind值,仅分析已安装依赖,并支持CI门禁与abandoned包告警。

直接看 libyear 数值,比单纯跑 composer outdated 有用得多——它把“落后多少版本”转化成“落后多少年”,一眼就能识别出哪些依赖正在拖垮项目长期健康度。
用 ecoapm/libyear 量化依赖老化程度
Composer 自带的 composer outdated 只告诉你“有新版本”,但不说明“这个包停更多久了”。而 libyear 会基于每个包的最新发布日期与你当前锁定的版本发布时间,算出一个“Libyears Behind”值。比如:
-
monolog/monolog当前用的是 v1.25.0(2020-02 发布),最新是 v3.5.0(2025-11 发布)→ 落后约 5.8 年 -
symfony/console当前 v5.4.39(2023-08),最新 v7.2.0(2026-04)→ 落后约 2.7 年
安装和运行很简单:
composer global require ecoapm/libyear libyear --path ./
输出会按落后年数倒序排列,优先处理 >3 年的包。注意:它只分析已安装的依赖(vendor/ 中实际存在的),不扫描 composer.json 里未 install 的条目。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
区分“可更新”和“该废弃”的依赖
运行 composer outdated --direct 后,别急着全量 update。先人工筛查三类信号:
- 包名旁带
[abandoned]标记(如guzzle/guzzle [abandoned])→ 这不是版本滞后,是项目已死亡,必须替换为guzzlehttp/guzzle - 主版本号跳变(如从
^2.0升到^4.0)→ 查 CHANGELOG,确认是否含 BC break;很多“落后多年”的包其实卡在 major 版本迁移上 - 依赖树中某包被多个子依赖以不同 minor 版本要求 →
composer why-not vendor/package:version定位冲突源头,而不是硬推--with-dependencies
把更新频率纳入 CI 流程防技术债累积
光靠人盯不现实。建议在 CI 中加一道检查:
- 用
libyear --max-libyears=3 --fail-on-violation做门禁:超过 3 年自动失败,阻断 PR 合并 - 配合
composer show --outdated --direct --minor-only每周定时任务,只提醒可安全升级的 minor 补丁 - 对
abandoned包单独设告警:写个简单脚本 grepcomposer update --dry-run输出,匹配is abandoned就发钉钉/企业微信
真正难的不是工具链,而是判断“这个包落后 4.2 年,但业务逻辑完全没碰它,值得花两天迁移吗”。这时候得翻 git blame 看最近谁改过调用它的代码,再决定是修、绕还是删——自动化只能暴露问题,决策还得人来。

















