巧用 package.json overrides / resolutions

semver 语义化版本控制

首先,快速的带大家回顾一下 semver 语义化版本控制

我们的 npm 模块都是严格遵循这套版本控制的

格式为 [major, minor, patch] 例如 react@18.2.0

大版本就是 18, 次版本为 2,补丁版本则为 0

大版本表示有 breakChange ,可能会有不向前兼容的 api

次版本则为一些小改动

补丁版本为一些 bug 的修复

次版本和补丁版都是向前兼容的版本

除此之外,在 package.json 中我们还可以看到一些符号

json 复制代码
  "dependencies": {
    // ^ 表示允许更新次版本和补丁版本,
    // 例如可以更新到 18.2.1 / 18.3.0
    // 但是不会更新到 19.0.0
    "react": "^18.2.0",
    // ~ 表示允许更新补丁版本,
    // 例如可以更新到 18.2.1
    // 但是不会更新到 18.3.0 / 19.0.0
    "react-dom": "~18.2.0",
    // 不加任何符号 表示准确的匹配某个版本
    "lodash": "4.17.21"
  },

现在回到正题 介绍一下 package.json 中的 overrides / resolution 字段

场景一:安装依赖冲突

我们初始化一个项目

yarn create vite npm --template react-ts

先用 npm 来介绍,后面针对 yarn 补充一些不同的地方

除去一些无用的依赖,我们得到一个最小的 package.json

json 复制代码
{
  "name": "npm",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.43",
    "@types/react-dom": "^18.2.17",
    "@vitejs/plugin-react": "^4.2.1",
    "typescript": "^5.2.2",
    "vite": "^5.0.8"
  }
}

然后我们引入一个用于 json 可视化的库

npm install react-json-view

这个时候就会得到一个报错

查看报错原因或者 react-json-view 的 package.json 的 peerDependencies

json 复制代码
"peerDependencies": {
    "react": "^17.0.0 || ^16.3.0 || ^15.5.4",
    "react-dom": "^17.0.0 || ^16.3.0 || ^15.5.4"
}

www.npmjs.com/package/rea...

可以看到 我们项目的直接依赖 react 的版本是 18.2.0 不满足 react-json-view 中需要的 react 的版本

这个时候就可以引出 overrides

我们在 package.json 中加入一个新的字段 overrides

json 复制代码
  "overrides": {
    // 表示只覆盖 react-json-view 这个项目下的依赖
    "react-json-view": {
      // $ 表示跟随本项目下的react版本,即^18.2.0
      "react": "$react",
      // 当然也可以直接指定对应的重写版本 (推荐上述写法)
      "react-dom": "^18.2.0"
    }
  }

然后再运行 npm install react-json-view 就可以看到依赖被成功的安装了

运行 npm ls react-dom 查看 react-dom 在项目中依赖关系

可以看到 react-json-view 下的 react-dom 版本已经被重写了

场景二:解决一些 security bug

第二种场景则是,例如你维护了一个时间比较久的项目,

突然在某次上线前的 security scan 中 发现了一些第三方模块的漏洞,需要升级这些模块来 fix

其中,有的可能是项目的直接依赖,有的则是第三方模块的子依赖,甚至可能是很深的子依赖

这个时候,你也需要用到 overrides 来重写项目中的依赖关系

当然前提是,你得知道重写后不会破坏项目的运行

还是这个项目我们运行

npm ls semver

我们可以看到 semver 在项目中有两个并存的版本 6.x 的 和 7.x 的

例如,如果有一天在安全扫描的时候,我们被告诉 6.x 的这个版本有安全问题需要升级到最新的版本

这个时候也可以通过 overrides 来实现

json 复制代码
  "overrides": {
    "react-json-view": {
      "react": "$react",
      "react-dom": "$react-dom"
    },
    "semver": "^7.5.4"
  }

重新安装依赖,可以看到项目中所有用到 semver 的地方都被替换成了我们指定的版本

当然启动项目也是正常的

补充一些 yarn 的区别

yarn 和 npm 不同的地方在于

yarn 中重写依赖的字段不是 overrides 而是 resolutions

同时查看依赖关系的命令为 yarn list --pattern react-dom 等价于 npm ls react-dom

overrides 中可以嵌套的书写,重写某个特定模块下的子依赖 例如

json 复制代码
  "overrides": {
    "react-json-view": {
      "react": "$react",
      "react-dom": "$react-dom"
    },
  }

但是在 yarn 下 只能写成

json 复制代码
  "resolutions": {
    "react": "$react",
    "react-dom": "$react-dom"
  }
相关推荐
桂月二二41 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
lee5764 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579654 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me4 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者4 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
qq_392794484 小时前
前端缓存策略:强缓存与协商缓存深度剖析
前端·缓存