# npm 版本发布冲突记录

## 问题描述

发布 `v4.9.4` 版本时，因 `latest` 标签已指向更高版本 `6.5.6`，npm 拒绝发布：

```
npm error Cannot implicitly apply the "latest" tag because previously published version 6.5.6
is higher than the new version 4.9.4. You must specify a tag using --tag.
```

## 核心规则

| 情况 | 结果 | 是否需要 --tag |
|------|------|:---:|
| 新版本 **高于** 当前 `latest` | 自动成为新的 `latest` | ❌ 不需要 |
| 新版本 **低于** 当前 `latest` | npm 拒绝（报错） | ✅ **必须** 用 `--tag` |

## 标签 vs 版本号

| 概念 | 示例 | 说明 |
|------|------|:---:|
| **版本号** | `4.9.4` | 写在 `package.json` 里，**唯一标识**一个发布 |
| **标签名** | `latest`, `legacy`, `beta` | 一个**别名/指针**，指向某个版本号 |

**关键理解**：`--tag` 只影响默认安装版本，不影响用户按版本号安装。用户始终可以通过 `npm install <包名>@4.9.4` 安装到指定版本。

## 解决方案

### 方案一：使用 `--tag` 指定自定义标签（推荐）

```bash
npm publish --tag legacy
```

标签名不能是有效的 SemVer 格式，例如 `v4.9.4` 是不允许的。推荐标签：`legacy`、`old-stable`、`archive`、`v4` 等。

安装方式：

```bash
npm install <包名>@4.9.4       # 通过版本号安装（推荐）
npm install <包名>@legacy       # 通过标签安装
```

### 方案二：发布后调整 `latest` 标签（需谨慎）

```bash
# 先以自定义标签发布
npm publish --tag legacy

# 再将 latest 标签指向 4.9.4
npm dist-tag add <包名>@4.9.4 latest
```

**注意**：方案二会让所有执行 `npm install <包名>` 的用户安装到 `4.9.4`，即使已有更高的版本。

### 方案三：补加更清晰的标签

```bash
# 发布
npm publish --tag legacy

# 补加语义化标签
npm dist-tag add <包名>@4.9.4 v4
```

## 常见错误

| 错误信息 | 原因 |
|----------|------|
| `Tag name must not be a valid SemVer range: v4.9.4` | 标签名不能是合法的版本号格式 |
| `Cannot implicitly apply the "latest" tag because previously published version X is higher than the new version Y` | 新版本低于当前 `latest` 指向的版本 |

## 版本发布顺序分析示例

假设已发布的版本序列：

```
4.9.2  ← 发布时 latest = 4.9.2   ✅ 正常发布
5.6.12 ← 比 4.9.2 更高 → latest 自动变成 5.6.12   ✅ 正常发布
4.9.3  ← 比 5.6.12 更低 → 必须用 --tag
5.7.1  ← 比 4.9.3 更高 → latest 自动变成 5.7.1   ✅ 正常发布
5.7.3  ← 比 5.7.1 更高 → latest 自动变成 5.7.3   ✅ 正常发布
```

**规律**：发布低版本的人没有一个是有特殊权限的，他们只是正确使用了 `--tag` 而已。