background
NPM in the company is often ridiculed for some inherent bugs. Recently, I just had time to optimize, and then I tried to solve a publish bug I met before. Below is the analysis record.
Phenomenon of the problem
The company’s internal NETWORK NPM chose to use Verdaccio as the service. At present, a module published contains a deprecated field, resulting in the loss of the historical version, and only the version information of this publish is left.
Question why
The process for implementing deprecate in NPM CLI is as follows: github.com/npm/cli/blo…
- Request the GET interface to obtain information about the current module
- Then modify the deprecated field for the version that matches
- Request the PUT interface to update the module
Then the new module in CLI implementation is: github.com/npm/libnpmp…
- Read the local package.json content
- Request the PUT interface to upload the module
When Verdaccio implemented the server, the update module and the upload module were the same service interface, and the two actions were not handled properly: github.com/verdaccio/v…
This logic is deprecated: github.com/verdaccio/v…
Local-storage Processing logic: github.com/verdaccio/v… The invalid version information was removed here: github.com/verdaccio/v…
For example, if you already have a module of 1.0.0 or 1.0.1, the service will receive data like this when publishing 1.0.2:
{
"name": "module_name"."version": {
"1.0.2": {
"deprecated": "xxx" // If there are any}}},Copy the code
If you call NPM deprecate [email protected] “XXX” directly, the service will receive data like this:
{
"name": "module_name"."version": {
"1.0.0": {
"deprecated": "xxx" // If there are any
},
"1.0.1": {}}}Copy the code
The logic on the server side is the same:
- Storage Modifies the version information
- Filter to remove invalid version information (e.g. 1.0.0, 1.0.1)
- Overwrite the original package.json information with the current metadata
As a result, if package.json is published with a deprecated parameter, historical versions will be lost.
Repair way
The fix is also relatively simple, in fact, the main thing is to distinguish the current interface trigger is deprecate or publish. Read the versions of the module manually and compare the metadata received by the interface. If it is publish, it will not match. When deprecated is triggered, a new test can be added to check whether it was published with deprecated, which will be ignored and the new module upload process will continue.
The problem summary
In summary, the deprecated field is more like an NPM convention than an explicit field that requires users to write to package.json. If you need to add deprecated information to the version, use the official recommended scheme: Doc.codingdict.com/npm-ref/cli…
As well as the PR has been submitted to the official, looking forward to a wave of reply: github.com/verdaccio/v…