第一步
?創建js文件 文件名為downloadNpmPackage.js
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得文件將以下內容復制進去
#!/bin/bash# 解析參數
while getopts ":r:u:p:" opt; docase $opt inr) 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" ]]; thenecho "請提供倉庫地址參數 -r"exit 1
fi# 若提供了用戶名密碼,提前登錄(可選)
if [[ -n "$USERNAME" && -n "$PASSWORD" ]]; thennpm 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; doecho "開始上傳:$file"# 進入包所在目錄,執行 npm publish# 如果包路徑不同,可以考慮進去目錄再執行# 這里假設包就是當前目錄或子目錄npm publish "$file" --registry="$REPO_REGISTRY"if [[ $? -eq 0 ]]; thenecho "成功上傳:$file"elseecho "上傳失敗:$file"fiecho ""
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 |