共计 1407 个字符,预计需要花费 4 分钟才能阅读完成。
背景
公司外部的 NPM 因为一些固有的 bug 常常被吐槽,最近刚好有工夫能够来做优化,而后就尝试解一下之前遇到的一个 publish 的 bug,下边是剖析记录。
问题景象
公司内网 NPM 抉择的是应用 verdaccio 来做服务,目前遇到了一个模块 publish 时蕴含 deprecated 字段导致历史版本失落,仅剩下本次 publish 的版本信息。
问题起因
NPM CLI 实现 deprecate 的时候流程是这样的:
https://github.com/npm/cli/bl…
- 申请 get 接口获取以后模块的信息
- 而后批改合乎的版本 deprecated 字段
- 申请 put 接口更新模块
而后新增模块在 CLI 的实现是:
https://github.com/npm/libnpm…
- 读取本地 package.json 内容
- 申请 put 接口上传模块
Verdaccio 在实现 server 的时候,更新模块和上传模块是同一个服务接口,两个动作之间又没有解决好:https://github.com/verdaccio/…
此局部逻辑为 deprecated 解决逻辑:https://github.com/verdaccio/…
local-storage 解决逻辑:https://github.com/verdaccio/…
这里删除了有效版本的信息:https://github.com/verdaccio/…
举例场景,如果曾经有一个模块存在 1.0.0、1.0.1 的版本,那么触发 publish 上传 1.0.2 版本的时候服务接管到的数据是这样的:
{
"name": "module_name",
"version": {
"1.0.2": {"deprecated": "xxx" // 如果有的话},
}
}
而如果间接调用 npm deprecate module_name@1.0.0 “xxx” 的时候服务接管到的数据是这样的:
{
"name": "module_name",
"version": {
"1.0.0": {"deprecated": "xxx" // 如果有的话},
"1.0.1": {}}
}
而两者在服务端的解决逻辑是一样的:
- storage 批改对应的版本信息
- 过滤移除生效的版本信息(比方这里就会把 1.0.0、1.0.1 的信息移除)
- 应用以后 metadata 笼罩原有的 package.json 信息
最终导致如果 publish 的时候 package.json 中蕴含 deprecated 参数则会呈现历史版本失落的状况。
修复形式
修复形式也比较简单,其实次要就是可能辨别出以后接口触发是 deprecate 导致的还是 publish 导致的就能够了。
那么咱们就通过手动读取一次以后模块的 versions 信息,而后比照本次接口触发时接管到的 metadata,如果是 publish,那么这里肯定不会匹配上的。
那么就能够在触发 deprecated 的时候新增一个检测,检测是否为 publish 时携带了 deprecated,这种状况间接疏忽,进入原有的新模块上传流程。
问题总结
总结来说,deprecated 字段更像是一个 NPM 外部约定的字段,而非一个须要使用者写到 package.json 中的显性字段,如果须要对版本增加废除信息,请用官网举荐的计划:https://doc.codingdict.com/np…
以及曾经把 PR 提给官网了,期待一波回复:https://github.com/verdaccio/…