◆

npm-check-updates(ncu)升级依赖命令详解

2023-02-02 01:370

包的作用

将你的 package.json 依赖升级到最新版本,忽略指定的版本。

这里要理解它和 npm update 的本质区别。npm update 受 package.json 里的版本范围约束,^1.2.0 最多升到 1.x 的最新版,绝不会跨到 2.0.0。所以一个装了两年没动的项目,npm update 跑一百遍,大版本还是停在原地。

ncu 的做法是直接改 package.json 里的版本号本身,把 ^1.2.0 重写成 ^2.5.1,突破范围限制。代价也很明显:跨大版本意味着可能有破坏性变更,升完必须跑测试、看 changelog,不能升完就提交。我一般把它当成「列出可升级清单」的工具,然后手工挑着升。

安装

npm install -g npm-check-updates

不想全局装可以直接 npx npm-check-updates,一次性使用,避免全局环境里堆工具。

检查 package.json 的最新依赖项

不带任何参数时 ncu 只读不写,把有新版本的包列出来,package.json 一个字都不改。这是最常用的姿势——先看清楚要升什么:

ncu

显示当前目录中项目的所有最新依赖项(不包括 peerDependencies):

下图是输出结果,左边是当前 package.json 里写的版本范围,右边是可升到的版本。注意看颜色区分:绿色是补丁级(patch),青色是次版本(minor),红色是主版本(major)。红色的那些是重点,跨大版本必须逐个查 changelog:

ncu 命令的输出结果,左列为当前版本范围,右列为可升级到的最新版本,按 patch/minor/major 用不同颜色区分

查看单个包的最新版本

只关心某个包时把包名跟在后面,输出会干净很多:

ncu vue

更新 package.json 的最新依赖项

加上 -u(--upgrade)才会真正写文件。这一步只改 package.json,不装包也不动 lockfile,所以执行完还要手动跑一次 npm install / pnpm install:

ncu -u

下图是加了 -u 之后的输出,末尾多了一行提示,告诉你 package.json 已被修改、需要执行 install 来落地:

ncu -u 的执行结果,列出已被写入 package.json 的新版本,并提示需要运行 install 安装

两步分开是好事,改完还有机会 git diff 看一眼再决定要不要装。真升出问题了,git checkout package.json 就退回去了。

更新单个依赖

大版本升级建议一个一个来,升完跑一遍测试再升下一个。一次全升上去,出错了根本不知道是哪个包的问题:

ncu -u vue

查看全局的安装包最新版本

-g 检查全局安装的包。注意这个模式下 ncu 只报告不修改(全局包没有 package.json 可写),它会打印出对应的升级命令让你自己执行:

ncu -g

使用通配符

大项目依赖几十上百个,按名字筛选很实用。下面几组写法效果等价,选一个顺手的记住即可。

检查某一个包

ncu vuex
ncu -f vuex
ncu --filter vuex

检查某一类的包

包名用引号包起来避免 shell 抢先展开。用 / 包裹的会被当成正则处理,需要更精确的匹配时用它:

ncu 'vue*'
ncu "/^react*$/"

检查除某个包以外的所有包

-x(--reject)是排除。有些包我明确不想动——比如被框架锁死版本的、或者已知新版有兼容问题的,把它们排掉,剩下的放心升:

ncu \!vue
ncu -x vue
ncu --reject vue

检查特定的几个包

ncu vue vuex
ncu vue,vuex
ncu -f "vue vuex"

检查不以 react 开头的包

ncu \!'react*'

tip

同理,更新的话只要在上面的每个语句后面加上 -u

只升小版本,不跨大版本

这是我实际用得最多的一个参数。--target 控制升级的激进程度:

ncu -u --target minor   # 最高升到最新的 minor,不跨 major
ncu -u --target patch   # 只升补丁版本,最保守
ncu -u --target latest  # 默认值,升到 registry 上的 latest

日常维护跑 --target minor 就够了,按语义化版本约定,minor 和 patch 不该有破坏性变更,升级风险低。major 单独拎出来处理。

对于 monorepo 如何更新

monorepo 里每个子包都有自己的 package.json,在根目录跑 ncu 只会处理根上那一个。--deep 让它递归查找所有子目录的 package.json 一并处理:

ncu --deep -u

--deep 实际是 --packageFile '**/package.json' 的简写,会跳过 node_modules。如果只想处理特定几个子包,直接用 --packageFile 指定路径 glob 更精确。

升级之后的收尾

改完 package.json 别忘了这几步。先 install 让 lockfile 同步,然后跑构建和测试。跨大版本的包挨个去看它的 migration guide——ncu 只负责告诉你有新版本,兼容性它一概不管。

如果 install 之后报出一堆 peer dependency 警告,通常是某个包升了大版本但它的插件生态还没跟上(典型场景是 eslint 升 9、vite 升大版本)。这时候要么退回去等生态成熟,要么在 pnpm 的 peerDependencyRules 里配置忽略。

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEnpm-check-updates(ncu)升级依赖命令详解加载中