快速将前端得依赖打为tar包(yarn.lock版本)并且推送至nexus私有依赖仓库(笔记)

第一步

创建js文件 文件名为downloadNpmPackage.js

javascript 复制代码
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

const fs = require("fs");
const path = require("path");
const request = require("request");

// 设置依赖目录
const downUrl = "./npm-dependencies-tgz";
if (!fs.existsSync(downUrl)) {
  fs.mkdirSync(downUrl);
}

// 读取 yarn.lock 文件内容
const yarnLockPath = "./yarn.lock";
if (!fs.existsSync(yarnLockPath)) {
  console.error("未找到 yarn.lock 文件,请确保在项目根目录。");
  process.exit(1);
}
const yarnLockContent = fs.readFileSync(yarnLockPath, "utf8");

// 正则匹配所有 resolved URL
const resolvedPattern = /resolved\s+"([^"]+)"/g;
let match;
const tgz = [];

// 从 yarn.lock 提取所有下载地址
while ((match = resolvedPattern.exec(yarnLockContent)) !== null) {
  const url = match[1];
  // 过滤出 tarball 链接(一般 ending with .tgz 或 npm registry 的地址)
  if (url.endsWith(".tgz") || url.includes("registry.npmjs.org")) {
    tgz.push(url);
  }
}

if (tgz.length === 0) {
  console.log("未在 yarn.lock 中找到任何可下载的依赖链接。");
  process.exit(0);
}

console.log(`共解析到 ${tgz.length} 个依赖包,将开始下载。`);

// 重试次数和状态变量
const retryTimes = 3;
let currentTryTime = 0;
let currentDownIndex = 0;
const downloadFailTgz = [];

// 下载进度显示
function showProgress(received, total, filePath) {
  const percentage = ((received * 100) / total).toFixed(2);
  process.stdout.write(`\r${filePath} 下载进度:${percentage}% (${received}/${total} 字节)`);
  if (received >= total) {
    console.log(`\n${filePath} 下载完成!`);
  }
}

// 依赖下载函数
function doDownload(url) {
  const filename = path.basename(url.split("?")[0]);
  const outputDir = path.join(downUrl, filename);

  const req = request({
    method: "GET",
    uri: url,
    timeout: 60000
  });

  // 获取内容长度
  req.on("response", (data) => {
    const totalBytes = parseInt(data.headers["content-length"]);
    let receivedBytes = 0;
    // 监听下载过程
    data.on("data", (chunk) => {
      receivedBytes += chunk.length;
      showProgress(receivedBytes, totalBytes, filename);
    });
  });

  // 管道写入文件
  const writeStream = fs.createWriteStream(outputDir);

  req.pipe(writeStream);

  req.on("error", (err) => {
    console.error(`\n${filename} 下载失败:`, err);
    handleRetryOrFail();
  });

  writeStream.on("finish", () => {
    // 当前文件下载成功,继续下一个
    currentDownIndex++;
    currentTryTime = 0;
    startNextDownload();
  });

  writeStream.on("error", (err) => {
    console.error(`\n${filename} 写入错误:`, err);
    handleRetryOrFail();
  });

  function handleRetryOrFail() {
    if (currentTryTime < retryTimes) {
      currentTryTime++;
      console.log(`\n${filename} 重试第 ${currentTryTime} 次...`);
      doDownload(url);
    } else {
      console.warn(`\n${filename} 下载失败,已重试 ${retryTimes} 次`);
      downloadFailTgz.push(url);
      currentDownIndex++;
      currentTryTime = 0;
      startNextDownload();
    }
  }
}

// 开始下一次下载
function startNextDownload() {
  if (currentDownIndex < tgz.length) {
    console.log(`开始下载第 ${currentDownIndex + 1}/${tgz.length} 个依赖`);
    doDownload(tgz[currentDownIndex]);
  } else {
    // 全部下载完成
    if (downloadFailTgz.length === 0) {
      console.log("【完成】所有依赖均下载成功!");
    } else {
      console.warn("【完成】部分依赖下载失败,请手动下载:");
      downloadFailTgz.forEach((url) => console.log(url));
    }
  }
}

// 启动第一个下载
startNextDownload();

放置在与yarn.lock同级目录下 然后再这个目录下打开终端执行 node downloadNpmPackage.js

等待即可

第二步

准备一份名为UploadnpmPackage.sh得文件将以下内容复制进去

bash 复制代码
#!/bin/bash

# 解析参数
while getopts ":r:u:p:" opt; do
    case $opt in
        r) REPO_REGISTRY="$OPTARG" ;; # 例如:http://xxx/xxx/xxx/
        u) USERNAME="$OPTARG" ;;       # npm账号(可选,若需要登录)
        p) PASSWORD="$OPTARG" ;;       # npm密码
        *) echo "用法: $0 -r <registry_url> [-u <用户名>] [-p <密码>]"; exit 1 ;;
    esac
done

# 检查必填参数
if [[ -z "$REPO_REGISTRY" ]]; then
    echo "请提供仓库地址参数 -r"
    exit 1
fi

# 若提供了用户名密码,提前登录(可选)
if [[ -n "$USERNAME" && -n "$PASSWORD" ]]; then
    npm set //$(echo "$REPO_REGISTRY" | sed 's|^https*://||')/:_authToken "$PASSWORD"
    # 或者登录
    # npm login --registry=$REPO_REGISTRY
fi

# 查找所有 .tgz 文件
find . -type f -name '*.tgz' | while read -r file; do
    echo "开始上传:$file"
    # 进入包所在目录,执行 npm publish
    # 如果包路径不同,可以考虑进去目录再执行
    # 这里假设包就是当前目录或子目录
    npm publish "$file" --registry="$REPO_REGISTRY"
    if [[ $? -eq 0 ]]; then
        echo "成功上传:$file"
    else
        echo "上传失败:$file"
    fi
    echo ""
done

将这个文件放在刚才打出来的那个包里与其他tag包再同一个目录下

然后再npm-dependencies-tgz 这个目录上右键走git bash

执行以下命令 红色部分替换为你自己得

|---------------------------------------------------------------------------------------------------------------------------------|
| sh UploadnpmPackage.sh -u admin -p nexusAdmin2023 -r http://172.24.105.249:8089/service/rest/v1/components?repository=npm-local |

相关推荐
前端大卫2 小时前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘2 小时前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare2 小时前
浅浅看一下设计模式
前端
Lee川2 小时前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix3 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人3 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl3 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅3 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人3 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼3 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端