array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 怎样固定依赖的依赖的依赖的版本 - 爱码网

说到 package.json 的版本固定,你或许会想到 dependencies devDependencies 。

"@ant-design/pro-layout": "^4.5.16",
    "@antv/data-set": "^0.10.2",
    "antd": "^3.23.6",
    "classnames": "^2.2.6",
    "dva": "^2.4.1",
    "echarts": "^4.7.0",
    "echarts-for-react": "^2.0.15-beta.1",
    "html2canvas": "^1.0.0-rc.5",
    "jquery": "^3.5.0",
    "lodash": "^4.17.11",
    "moment": "2.24.0",
    "omit.js": "^1.0.2",
    "path-to-regexp": "^3.1.0",
    "qs": "^6.9.0",
    "react": "^16.8.6",
    "react-copy-to-clipboard": "^5.0.1",
    "react-dom": "^16.8.6",
    "react-helmet": "^5.2.1",
    "react-read-more-read-less": "^1.0.7",
    "react-to-print": "^2.6.3",
    "redux": "^4.0.1",
    "slash2": "^2.0.0",
    "umi": "^2.9.6",
    "umi-plugin-pro-block": "^1.3.4",
    "umi-plugin-react": "^1.10.1",
    "umi-request": "^1.2.7",
    "webpack-theme-color-replacer": "^1.2.15"
  },

注意moment那一行,去掉了 ^ 符号。此时版本就被固定了。
但是,这个只对开发者主动引用的依赖有效,对“依赖的依赖”,“依赖的依赖的依赖”是无效的。
举个例子,antd 用了 rc-calendar ,rc-calendar 用了 moment,假设moment最新版是2.4.1,那么,rc-calendar使用的moment仍然是2.4.1,而不是2.4.0。
从package-lock.json中可以看出。

    "rc-calendar": {
      "version": "9.15.6",
      "resolved": "https://registry.npmjs.org/rc-calendar/-/rc-calendar-9.15.6.tgz",
      "integrity": "sha512-TJD4cUXsBAjyCzo7BaGb86nZyJetBUt/Rpu0H1WWhp9AJc+Tl7aj7TCD3TM5Y8Ak/yxsA8WDBMuKw1XdQMsM5g==",
      "requires": {
        "babel-runtime": "6.x",
        "classnames": "2.x",
        "moment": "2.x",
        "prop-types": "^15.5.8",
        "rc-trigger": "^2.2.0",
        "rc-util": "^4.1.1",
        "react-lifecycles-compat": "^3.0.4"
      }
    },

怎样解决

方法1

npm 和 yarn 都有 lock 机制。

  • 在 npm 里面叫 package-lock.json.
  • 在 yarn 里面叫 yarn.lock.
    举个例子。
  1. 我创建了一个项目,并安装了依赖。其中 antd 用的版本是 3.23.5,也是当时的最新版。
  2. 第二天,我删除了依赖,但没有删除 package-lock.json (yarn.lock)而此时 antd 的版本更新到了 3.23.6.
  3. 我再次安装依赖。因为 package-lock.json (yarn.lock)存在,所以我仍然会安装 3.23.5。
  4. 这个规则在云效里也是适用的。只要把 package-lock.json (yarn.lock)上传到git,云效也会按照这个文件的约定去打包。

方法2

上一个方法,如果 package-lock.json (yarn.lock)不存在,或者需要大范围更新(每一个依赖类库的每一个版本都会有唯一的sha512标识码,手动更改不现实),就不适用了。但我们还有另一个办法。
yarn的作者就这个问题专门写了一个文档。

链接:https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-selective-versions-resolutions.md

文章很长,不看也可以,我们只需要知道怎么解决这个问题。
package.json里面加一个对象,和 dependencies devDependencies 平级。

"resolutions": {
    "**/moment": "2.24.0"
  },

这样,整个项目中所有的moment的版本都会指定为2.24.0。
但你可能会需要一些更精细的设置(比如只指定“某个依赖的某个依赖的某个依赖”的版本)。你可以从上面的文章里找到答案。

Q&A

  • npm是否支持resolutions设置?
    不确定,因为我平时装依赖用的是yarn。

相关文章: