[译] 如何更新 package.json 中的依赖项

简介: [译] 如何更新 package.json 中的依赖项

原文:medium.com/better-prog…

Npm (Node Package Manager) 是一种应用于 JavaScript 编程语言的包管理器,也是 Node.js 的 JavaScript 运行时环境的默认包管理器。

在一个项目中,其包依赖项列表保存在 package.json 文件中。每个已安装的包都被分配了一个版本号,一般由 三部分组成:major.minor.patch

  • major 表示非兼容的重大 API 改变
  • minor 表示向后兼容的功能性改变
  • patch 表示向后兼容的 bug 修正

默认情况下,npm 会安装最新的版本,并在版本号前面附加一个 ^ 插入符号,如 “^15.2.0”。有这种插入符号的依赖项意味着至少要安装 15.2.0 的版本。

当存在一个更高的 major 版本时,它就可能被使用。比方说当时有了个 15.6.2,就会在安装时升级到该版本。

若你想更稳妥些,使用 ~ 波浪号 的 “~15.2.0” 以表示只使用 patch 位更高的版本。当然,纯 “15.2.0” 将保证只使用该精确的版本号。语义化版本命名法的更多细节见 semver.org/

迄今为止,一切顺利。

问题来了

斗转星移,依赖愈增。当你想升级所有包以获取新特性或是修正缺陷时,你会如何做呢?

首先你得确定最新版本是多少。这里有个 GitHub 上的例子:


{
  "name": "npm_upgrading",
  "version": "1.0.0",
  "description": "A tutorial how to upgrade NPM packages",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/JenniferFuBook/npm_upgrading.git"
  },
  "author": "Jennifer Fu",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/JenniferFuBook/npm_upgrading/issues"
  },
  "homepage": "https://github.com/JenniferFuBook/npm_upgrading#readme",
  "dependencies": {
    "lodash": "~4.17.12",
    "prettier": "1.18.0",
    "react": "^15.2.0"
  }
}

如果你在 VSCode 上安装过 “Version Lens” 的话,它将展示所有包的最新版本:

或者也可以使用 npm 命令行接口:npm outdated

  • Current 即当前被安装的版本
  • Wanted 是满足 package.json 中的 SemVer 范围的最大版本
  • Latest 是该包在仓库中标记为 latest 的版本
  • Location 是该包在所居于的依赖树中所在的位置

CLI 输出中的包颜色表示了过期等级。红色意味着匹配到了一个比 package.json 中定义的 SemVer 需求还要新的已安装版本;黄色表示仓库中有比 SemVer 需求更新的版本。

在上例中,lodash 并未过期,因此没有被列出。同时,Prettier 在 minor 位落后于最新版本了,而 React 是在 major 位。

如果依赖项被修改为这样:

红色标记将会凸显 LodashPrettier

解决之道

在找出过期包之后,我们修正 package.json 中相关的版本规格。而后可以运行 npm installnpm update 以升级。

  • npm install 会安装一个包及其依赖的任何包。如果该包中存在 package-lockshrinkwrap 文件(在并存时后者优先级更高),将会按其进行依赖项安装。
  • npm update 会更新依赖项列表中出现的所有包,同时也会安装缺失的包。

二者的区别是什么呢?

首先,如果已安装的包版本满足 package.json 中定义的 SemVer 规格,则 npm install 会以模糊版本策略忽略掉它,并不会重新安装;而 npm update 则仍会(译注:在符合 SemVer 规格的前提下)将其升级到对应的最新 latest 版本。

译注:比如成文时 lodash 库的最新版本是 4.17.15,假设已安装版本为 4.17.14,则运行 npm install 后不会有任何变化,而 npm update 会将其升级到 4.17.15

同时,对 devDependencies 的处理也是不同的:

  • npm install 会安装或升级 devDependencies ,除非添加了 --production 标记
  • npm update 会忽略 devDependencies ,除非添加了 --dev 标记

太概念化了是吧?来举个例子,我们把 Prettier 的版本从 “1.18.0” 改成 “~1.18.0”:

如果运行 npm install,Prettier 的版本就是足够“模糊”的,以致 package-lock.json 中会保留原来的 “1.18.0”:

运行 npm ls 也能看到:

然而运行 npm update 后,package-lock.json 中 Prettier 的版本则会升级到 “1.8.2”:

npm ls 的输出同样也更新了:

此外,Prettier 的波浪号式依赖也被改为插入号式了!

更优方案

如前所述,如果 SemVer 规格使用了波浪号式版本声明,即便是 npm update 也不会直接升级其 major 位版本号。在主版本变动频繁并带来破坏性改变的情形下,这种 update 策略是很有意义的,同时需要谨慎对待。

那么,如果就是想升级 major 版本该如何呢?

使用 VSCode 中的 Version Lens 插件时,我们可以据其提示手动更新依赖包的 major 版本。另外一个强大的工具是 npm-check-updates,会自动化地完成同样的工作;该 npm 工具可以被全局化安装:

npm install -g npm-check-updates

然后运行:ncu -u

现在,package.json 中的依赖项就被升级到最新了,包括 major 位的更新:

剩下的就简单了。运行 npm installnpm update 以完成升级。

谨慎使用 npm-check-updates -- 毕竟,能力越大责任越大。



相关文章
|
资源调度 前端开发 算法
前端依赖版本重写指南
感谢神奇的 Semver 动态规则,npm 社区经常会发生依赖包更新后引入破坏变更的情况(应用没有使用依赖锁的话),而应用开发者就要在自己的依赖声明里先临时绕过,避免安装到有问题的版本,如果是一级依赖,只需要改 package.json 的声明就可以了,但如果是子依赖,就需要进行版本重写(overrides/resolution)了。本文是一篇针对版本重写功能的指南性文章,当你遇到如下的问题时,就可以按照对应的依赖重写语法,解决这些依赖问题了。
8423 1
前端依赖版本重写指南
|
存储 JSON JavaScript
从创建到维护:掌握package.json的最佳实践(一)
从创建到维护:掌握package.json的最佳实践
|
JavaScript 前端开发 jenkins
【前端】vue项目打包Browserslist: caniuse-lite is outdated. Please run: npx update-browserslist-db@latest解决方案
【前端】vue项目打包Browserslist: caniuse-lite is outdated. Please run: npx update-browserslist-db@latest解决方案
4171 0
|
JSON Java fastjson
微服务——SpringBoot使用归纳——Spring Boot返回Json数据及数据封装——Spring Boot 默认对Json的处理
本文介绍了在Spring Boot中返回Json数据的方法及数据封装技巧。通过使用`@RestController`注解,可以轻松实现接口返回Json格式的数据,默认使用的Json解析框架是Jackson。文章详细讲解了如何处理不同数据类型(如类对象、List、Map)的Json转换,并提供了自定义配置以应对null值问题。此外,还对比了Jackson与阿里巴巴FastJson的特点,以及如何在项目中引入和配置FastJson,解决null值转换和中文乱码等问题。
1733 0
|
存储 资源调度
在 Pinia 中如何实现状态持久化?
在 Pinia 中如何实现状态持久化?
3034 57
完美解决Non-terminating decimal expansion; no exact representable decimal result.异常
完美解决Non-terminating decimal expansion; no exact representable decimal result.异常
27927 0
完美解决Non-terminating decimal expansion; no exact representable decimal result.异常
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
2253 1
SpringBoot入门(7)- 配置热部署devtools工具
|
缓存 资源调度
解决node升级到18版本node-sass安装问题
解决node升级到18版本node-sass安装问题
|
SQL 机器学习/深度学习 XML
mybatis-plus分页查询详解
mybatis-plus分页查询详解
11678 0
mybatis-plus分页查询详解
|
JavaScript
成功解决:el-dialog弹出窗口、数据第一次没有加载、第二次打开才能加载数据。(每次页面刷新后、第一次打开dialog窗口、图片数不加载)
这篇文章分享了解决Vue中`el-dialog`弹出窗口在第一次打开时数据未加载问题的技巧,通过改变组件的`key`属性来强制Vue重新渲染DOM,从而确保数据正确加载。
成功解决:el-dialog弹出窗口、数据第一次没有加载、第二次打开才能加载数据。(每次页面刷新后、第一次打开dialog窗口、图片数不加载)

热门文章

最新文章