You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过npm API获取私有包版本并迁移至Verdaccio私有仓库?

解决私有npm包迁移到Verdaccio的实用思路

我之前也碰到过类似的私有包迁移需求,现成工具确实大多对私有包支持不友好,分享几个亲测可行的方案给你:

一、正确获取私有包及版本列表

你之前用curl没拿到数据,大概率是请求头或API端点不对。npm Registry的私有包查询需要携带有效的authToken,且要调用正确的私有包查询接口:

1. 查询私有作用域下的所有包

用curl请求npm的搜索API,指定作用域和私有访问权限,记得带上Authorization头:

curl -H "Authorization: Bearer YOUR_OLD_AUTH_TOKEN" \
  "https://old-registry-url/-/v1/search?text=scope:YOUR_PRIVATE_SCOPE&access=private"

如果是npmjs官方仓库,把old-registry-url换成registry.npmjs.org就行。返回的JSON里会包含该作用域下所有私有包的基本信息。

2. 获取单个包的所有版本

拿到包名后,用npm view命令(需配置旧仓库的authToken)就能获取所有版本:

# 先临时配置旧仓库的认证
npm config set registry https://old-registry-url/
npm config set //old-registry-url/:_authToken YOUR_OLD_AUTH_TOKEN

# 查询某个包的所有版本,返回JSON格式
npm view @your-scope/your-package versions --json

或者用API请求更灵活:

curl -H "Authorization: Bearer YOUR_OLD_AUTH_TOKEN" \
  "https://old-registry-url/@your-scope%2Fyour-package"

返回的JSON中versions字段就是该包的所有版本号。

二、自动化迁移脚本的核心逻辑

用Node.js写脚本是最灵活的方式,能完整控制迁移流程,下面是核心步骤:

1. 收集用户输入

用inquirer包让用户输入必要信息:

const inquirer = require('inquirer');

const answers = await inquirer.prompt([
  { type: 'input', name: 'oldRegistry', message: '旧npm仓库地址:' },
  { type: 'input', name: 'oldAuthToken', message: '旧仓库authToken:' },
  { type: 'input', name: 'verdaccioUrl', message: 'Verdaccio仓库地址:' },
  { type: 'input', name: 'verdaccioAuthToken', message: 'Verdaccio的authToken:' },
  { type: 'input', name: 'privateScope', message: '私有包作用域(如@myorg):' }
]);

2. 获取私有包列表

用axios请求旧仓库API:

const axios = require('axios');

const searchUrl = `${answers.oldRegistry}/-/v1/search?text=scope:${answers.privateScope.replace('@', '')}&access=private`;
const searchRes = await axios.get(searchUrl, {
  headers: { Authorization: `Bearer ${answers.oldAuthToken}` }
});

const packageNames = searchRes.data.objects.map(item => item.package.name);

3. 遍历包并迁移所有版本

对每个包,先获取版本,再下载tar包,最后发布到Verdaccio:

const { execSync } = require('child_process');
const fs = require('fs');

// 配置旧仓库
execSync(`npm config set registry ${answers.oldRegistry}`);
execSync(`npm config set //${answers.oldRegistry.replace('https://', '')}/:_authToken ${answers.oldAuthToken}`);

// 配置Verdaccio
execSync(`npm config set registry ${answers.verdaccioUrl}`);
execSync(`npm config set //${answers.verdaccioUrl.replace('http://', '')}/:_authToken ${answers.verdaccioAuthToken}`);

for (const pkgName of packageNames) {
  // 获取所有版本
  const versionsStr = execSync(`npm view ${pkgName} versions --json`).toString();
  const versions = JSON.parse(versionsStr);

  for (const version of versions) {
    // 下载包为tarball
    execSync(`npm pack ${pkgName}@${version}`);
    const tarball = `${pkgName.replace('/', '-')}-${version}.tgz`;

    // 发布到Verdaccio
    execSync(`npm publish ${tarball} --access private`);

    // 删除本地tarball
    fs.unlinkSync(tarball);
  }
}

三、关键注意事项

  • 权限验证:旧仓库的authToken必须拥有私有包的读取权限,Verdaccio的authToken必须拥有发布权限。
  • Verdaccio配置:确保Verdaccio的config.yaml中允许私有作用域的包发布,比如:
    packages:
      '@your-scope/*':
        access: $authenticated
        publish: $authenticated
        unpublish: $authenticated
    
  • Dist-Tags保留:如果需要保留原包的dist-tags(如latest),发布后可以执行npm dist-tag add ${pkgName}@${version} ${tag}。
  • 依赖处理:如果迁移的包依赖其他私有包,要确保这些依赖也被迁移,否则用户npm install时会失败。

内容的提问来源于stack exchange,提问作者Dan Scrima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:31:22