Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
title: 一次 npm 包安装失败的血泪史:当阿里镜像源遇到 ketcher-standalone
date: 2026-07-23 09:52:01
tags: [阿里镜像源, ketcher-standalone]
categories: [软件]
---

# 一次 npm 包安装失败的血泪史:当阿里镜像源遇到 ketcher-standalone

## 前言

今天在构建一个化学结构编辑器项目时,遇到了一个让人头大的问题:`npm install` 死活跑不通,报错 `404 Not Found`。折腾了半天,才发现是阿里镜像源里没有 `ketcher-standalone` 这个包的最新版本。这篇文章记录了整个排查过程和解决方案,希望能帮到遇到类似问题的同学。

## 问题背景

项目是一个基于 React + Ketcher 的化学结构编辑器。Ketcher 是一个开源的化学结构绘制工具,由 EPAM 开发维护。项目里依赖了 `ketcher-standalone` 这个包。

执行 Docker 构建时,在安装依赖的步骤卡住了:

```bash
RUN if [ -f package-lock.json ]; then
npm config set registry https://registry.npmmirror.com &&
npm ci --legacy-peer-deps;
# ... 省略其他包管理器判断
fi
```

## 报错信息

构建日志里出现了这样的错误:

```
245.2 npm error code E404
245.2 npm error 404 Not Found - GET https://cdn.npmmirror.com/packages/ketcher-standalone/3.16.1/ketcher-standalone-3.16.1.tgz
245.2 npm error 404 The requested resource 'ketcher-standalone@https://registry.npmmirror.com/ketcher-standalone/-/ketcher-standalone-3.16.1.tgz' could not be found or you do not have permission to access it.
```

同时还伴随着一堆 deprecated 警告:

```
53.52 npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory.
55.09 npm warn deprecated git-raw-commits@5.0.1: Deprecated and no longer maintained.
123.5 npm warn deprecated glob@7.2.3: Old versions of glob are not supported...
```

但这些警告只是干扰项,真正致命的是 `404`。

## 问题排查过程

### 第一步:确认包是否真的存在

第一时间去官方 npm 仓库查了一下:

```bash
npm view ketcher-standalone versions --registry=https://registry.npmjs.org/
```

输出显示 `3.16.1` 和 `3.17.0` 都是存在的。说明包本身没问题,问题出在镜像源上。

### 第二步:检查阿里镜像的缓存状态

打开阿里镜像的包页面:`https://npmmirror.com/package/ketcher-standalone`

果然,页面上显示的最新版本只有 `3.15.x`,而 `3.16.1` 和 `3.17.0` 都还没有同步过来。

### 第三步:确认问题根因

阿里镜像(npmmirror.com)采用的是**按需同步**机制,不是全量实时复制。只有当一个包被首次请求时,才会从官方源拉取并缓存到镜像站。

`ketcher-standalone` 是小众包(主要用于化学/生物信息学领域),使用的人不多,所以镜像源还没来得及同步新版本。加上 `3.16.1` 和 `3.17.0` 可能是最近发布的,阿里镜像的同步队列还没轮到它。

## 解决方案

### 方案一:切回官方源(最直接)

既然阿里源没有,那就直接用官方源:

```bash
npm config set registry https://registry.npmjs.org/
npm install
```

安装完成后,如果需要切回阿里源:

```bash
npm config set registry https://registry.npmmirror.com/
```

### 方案二:仅针对该包使用官方源

如果不想全局切换,可以单独指定该包的安装源:

```bash
npm install ketcher-standalone@3.16.1 --registry=https://registry.npmjs.org/
```

不过注意,如果使用 `npm ci`,它严格按照 `package-lock.json` 走,仍可能失败。建议用方案一。

### 方案三:手动触发镜像同步

阿里镜像提供了手动同步接口,可以主动通知它去拉取最新版本。

**方式 A:网页端触发**

访问 `https://npmmirror.com/package/ketcher-standalone`,点击页面上的 **Sync** 按钮。

**方式 B:命令行触发**

```bash
# 安装 cnpm 工具(如已安装可跳过)
npm install -g cnpm --registry=https://registry.npmmirror.com/

# 手动触发同步
cnpm sync ketcher-standalone
```

同步通常需要几分钟到十几分钟,完成后就可以从阿里源正常安装了。

### 方案四:修改 Dockerfile 临时切换源

针对 Docker 构建场景,我最终采用了方案一,在 `RUN` 命令中临时切换源:

```dockerfile
RUN npm config set registry https://registry.npmjs.org/ && \
npm ci --legacy-peer-deps
# 安装成功后可以切回阿里源(可选)
```

## 为什么会出现这种情况?

1. **镜像同步机制**:阿里镜像不是实时全量同步,而是按需缓存+定时轮询。
2. **包的流行度**:`ketcher-standalone` 属于垂直领域的小众包,触发同步的用户少。
3. **版本发布时间**:如果 `3.16.1` 刚发布不久,镜像还没来得及轮询到。

## 经验与教训

1. **不要盲目信任镜像源**:镜像源虽快,但不是万能的。遇到 `404` 时,第一时间去官方源确认包是否存在。
2. **理解镜像的工作原理**:知道阿里镜像是按需同步的,遇到小众包缺失就知道该怎么处理了。
3. **CI/CD 环境要有备选方案**:构建环境最好能配置多个镜像源做 fallback,或者直接用官方源 + 国内加速 CDN。
4. **善用镜像的手动同步功能**:`cnpm sync` 和网页端的 Sync 按钮是很有用的工具。

## 参考链接

- [ketcher-standalone 官方 npm 页面](https://www.npmjs.com/package/ketcher-standalone)
- [阿里镜像包页面](https://npmmirror.com/package/ketcher-standalone)
- [npmmirror 同步文档](https://npmmirror.com/)

---

**后记**:写完这篇博客后,我去 `https://npmmirror.com/package/ketcher-standalone` 点了一下 Sync 按钮,过几分钟再试,果然可以正常下载了。所以如果你也遇到同样的问题,记得先去点一下同步按钮 😄
```