node.js:依赖的版本(时刻-时区)在运行时改变
Posted
技术标签:
【中文标题】node.js:依赖的版本(时刻-时区)在运行时改变【英文标题】:node.js: version of dependency (moment-timezone) changes at runtime 【发布时间】:2018-10-27 08:45:33 【问题描述】:在最后一天,我研究了一个神秘的问题,其中moment-timezone
功能在特定的、看似任意的情况下不起作用。 我发现我的 moment-timezone
库的运行时版本在某个时候从版本 0.5.17 更改为 0.5.13。
在添加更多详细信息之前,这是node.js
问题还是moment-timezone
问题?
moment-timezone
的具体问题我最终使用yarn selective-version-resolutions 解决了,但如果这实际上是node.js
问题,我认为需要采取更极端的措施(yarn install --flat?)。
我不知道是哪个依赖项导致版本在运行时发生更改,但这是在添加 resolutions
部分之前我的 yarn.lock
文件中的相关部分:
moment-timezone@0.5.17:
version "0.5.17"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.17.tgz#3c8fef32051d84c3af174d91dc52977dcb0ad7e5"
dependencies:
moment ">= 2.9.0"
moment-timezone@^0.5.0, moment-timezone@^0.5.4, moment-timezone@~0.5.5:
version "0.5.13"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.13.tgz#99ce5c7d827262eb0f1f702044177f60745d7b90"
dependencies:
moment ">= 2.9.0"
如您所见,我的直接依赖关系是版本 0.5.17,但我的其他模块的依赖关系正在解析为版本 0.5.13。但我不明白在某些时候 我的 依赖项是如何解决到 0.5.13 的。
要检查moment-timezone
版本,我只需使用moment.tz.version
。这意味着在我的生产代码中,以下代码打印 0.5.17 直到某个时候突然打印 0.5.13:
const moment = require('moment-timezone');
console.log(`moment.tz.version: $moment.tz.version`);
最后一个细节:版本更改为 0.5.13 时中断的时刻时区函数是 moment.tz
函数 added in version 0.5.14 上的可选标志,在此代码中:
moment(utcDateTime, format).clone().tz(timezone, true)
谁能解释这怎么可能?我希望这是一个时区错误,而不是 node.js 错误...
【问题讨论】:
你有package-lock
吗?删除它和您的node_modules
,检查您的package.json
中的版本是否正确,然后运行npm install
。
@MaxBaldwin,这如何解释模块版本在运行时发生变化?正如我所说,我使用纱线选择性版本分辨率解决了具体问题。
当你安装 npm 或 yarn 时,会先查看你的 yarn.lock
,然后再查看 package.json
。它几乎像缓存一样工作。如果它看到对正在安装的包的引用,它将安装该版本并跳过package.json
但是经常发生的是你引用了同一个包的多个版本(在 yarn.lock 文件中),它们应该和谐地生活在一起。
这可能是因为添加包的顺序以及稍后运行的 yarn 命令可能会改变它。由于您有多个依赖项引用不同的版本,因此您确实需要使用解决方案,就像您已经在做的那样。
【参考方案1】:
我今天遇到了同样的问题,几个小时后,我想我知道发生了什么。如果你检查 moment-timezone 代码,你会看到它在初始化时需要 moment,添加 tz
属性以及与时区相关的所有内容,最后返回修改后的 moment 实例:
需要时刻 -> https://github.com/moment/moment-timezone/blob/0.5.27/moment-timezone.js#L12
修改矩实例 -> https://github.com/moment/moment-timezone/blob/0.5.27/moment-timezone.js#L532
返回具有所有新方法和属性的实例 -> https://github.com/moment/moment-timezone/blob/0.5.27/moment-timezone.js#L626
因此,如果您的直接依赖项和其他模块中的依赖项解析为相同的 moment
版本,则同一对象被修改两次,您获得的最终版本仅取决于您需要的顺序 moment-timezone
和具有 moment-timezone
作为依赖项的模块。
其实在moment-timezone
代码中,你可以看到这些行被注释掉了:
// Do not load moment-timezone a second time.
// if (moment.tz !== undefined)
// logError('Moment Timezone ' + moment.tz.version + ' was already loaded ' + (moment.tz.dataVersion ? 'with data from ' : 'without any data') + moment.tz.dataVersion);
// return moment;
//
我不知道为什么开发人员对此进行了注释,但显然这是一种已知行为。
【讨论】:
以上是关于node.js:依赖的版本(时刻-时区)在运行时改变的主要内容,如果未能解决你的问题,请参考以下文章
在 Windows 上运行 Python 以获取 Node.js 依赖项