快速将前端得依赖打为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 |

相关推荐
浩星5 分钟前
electron系列5:深入理解Electron打包
前端·javascript·electron
患得患失9499 分钟前
【前端WebSocket】心跳功能,心跳重置策略、双向确认(Ping-Pong) 以及 指数退避算法(Exponential Backoff)
前端·websocket·算法
英俊潇洒美少年11 分钟前
React 实现 AI 流式打字机对话:SSE 分包粘包处理 + 并发优化
前端·javascript·react.js
chQHk57BN14 分钟前
前端测试入门:Jest、Cypress等测试框架使用教程
前端
遇见你...22 分钟前
前端技术知识点
前端
AC赳赳老秦34 分钟前
OpenClaw image-processing技能实操:批量抠图、图片尺寸调整,适配办公需求
开发语言·前端·人工智能·python·深度学习·机器学习·openclaw
We་ct41 分钟前
LeetCode 172. 阶乘后的零:从暴力到最优,拆解解题核心
开发语言·前端·javascript·算法·leetcode·typescript
军军君0141 分钟前
数字孪生监控大屏实战模板:可视化数字统计展示
前端·javascript·vue.js·typescript·echarts·数字孪生·前端大屏
此刻觐神1 小时前
IMX6ULL开发板学习-03(Linux文件相关命令)
前端·chrome
吴声子夜歌1 小时前
ES6——Iterator和for...of循环详解
前端·javascript·es6