你跑完npm outdated,屏幕上一片红。但CI照过不误,构建绿灯,代码上线。几周后,某个陈旧的依赖在生产环境炸了——这才是Node.js项目的日常。

问题很直白:npm outdated能告诉你哪些包落后了,但它不会让你的构建失败。没有退出码,没有阈值配置,无法区分生产依赖和开发依赖。团队想定个规矩,比如"生产依赖不能落后最新版超过2个小版本",原生工具做不到。

打开网易新闻 查看精彩图片

手动更新变成救火演习,而不是可控流程。

我写了npm-outdated-check,把这个诊断工具变成CI的一等公民。

核心能力

语义版本阈值控制。你可以设死线:主版本、次版本、补丁版本各允许落后多少。比如--max-major 0 --max-minor 2 --max-patch 5,意思是主版本必须对齐,次版本最多落后2个,补丁最多5个。

有意义的退出码。0表示通过,1表示有违规,2是配置错误,3是网络问题。CI能直接读取,违规即失败。

配置灵活。命令行参数或.npm-outdated-check.json文件都行。能过滤只检查生产依赖,或只检查开发依赖。输出格式支持纯文本、表格、JSON三种。

实现逻辑

工具读取package.json,向npm registry查询每个包的dist-tags.latest版本,用semver库解析当前版本和最新版本,计算主/次/补丁三者的差值。

关键代码片段:

const majorDiff = latest.major - current.major;const minorDiff = latest.minor - current.minor;const patchDiff = latest.patch - current.patch;const isViolation = majorDiff > config.maxMajor || minorDiff > config.maxMinor || patchDiff > config.maxPatch;

任一差值超过配置的阈值,即判定违规。

接入CI

作为开发依赖安装:

npm install -D npm-outdated-check

直接运行,使用默认阈值(主版本0,次版本2,补丁版本5):

npx npm-outdated-check

GitHub Actions示例:

name: Dependency Checkon: [push, pull_request]jobs:  outdated-check:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4      - uses: actions/setup-node@v4        with:          node-version: '18'      - run: npm install      - run: npx npm-outdated-check --max-minor 3

如果某个依赖落后了4个次版本,构建失败,通知到位。

实际价值

把"记得更新依赖"这种靠自觉的事,变成"不更新就进不了主分支"的硬性约束。团队可以逐步收紧阈值,从允许落后5个版本开始,慢慢收敛到1个版本,最终对齐最新。

不再依赖某个工程师的记忆力,也不再等到生产事故才行动。