将本地前端工程中的npm依赖上传到Nexus

【问题背景】

用Nexus搭建了内网的依赖仓库,需要将前端工程中node_modules中的依赖上传到Nexus上,但是node_modules中的依赖已经是解压后的状态,如果直接机械地将其简单地打包上传到Nexus,那么无法通过npm install下载使用。故有此文。

【解决思路】

前端工程中的所有npm依赖信息已经记录在package-lock.json文件中,包括依赖的下载地址,所以可以直接根据package-lock.json中记录的依赖地址逐个下载依赖的原始包,然后再上传到Nexus对应的仓库中。

【前置条件】

  1. Nexus上已创建好hosted类型的npm仓库,假设起名为:npm-local
  2. 本地前端工程所在PC可以连接互联网
  3. 本地前端工程已执行npm install且已生成package-lock.json

【编写脚本】

下述的NodeJS脚本可以下载package-lock.json文件中的依赖,将该脚本保存到一个名为downloadNpmPackage.js的文件中:

javascript 复制代码
const fs = require('fs');
const path = require('path');
const request = require('request');
// 指定根据package-lock.json中记录的信息下载依赖
const packageLock = require('./package-lock.json');
// 指定将依赖下载到当前目录下的npm-dependencies-tgz目录
const downUrl = './npm-dependencies-tgz';

if (!fs.existsSync(downUrl)) {
  fs.mkdirSync(downUrl);
}

// 收集依赖的下载路径
const tgz = [];
for (let pkg in packageLock.dependencies) {
  let tgzUrl = packageLock.dependencies[pkg]['resolved'];
  tgz.push(tgzUrl);
}

// 逐个下载
tgz.forEach((url) => {
  const outUrl = url.split('/').pop()
  let outUrl2 = [outUrl]
  if(outUrl.indexOf('?') !== -1){
    outUrl2 = outUrl.split('?')
  }
  const outputDir = path.join(downUrl, outUrl2[0])
  let receivedBytes = 0;
  let totalBytes = 0;
  const req = request({
    method: 'GET',
    uri: url
  });
  req.on('response', function(data) {
    totalBytes = parseInt(data.headers['content-length']);
  });
  req.on('data', function(chunk) {
    receivedBytes += chunk.length;
    showProgress(receivedBytes, totalBytes, outUrl2[0]);
  });
  req.pipe(fs.createWriteStream(outputDir));
});

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

下述Bash脚本可以将下载好的前端依赖上传到Nexus上,将该脚本保存到名为UploadnpmPackage.sh的文件中。

bash 复制代码
#!/bin/bash

# 获取命令行参数
while getopts ":r:u:p:" opt; do
    case $opt in
        r) REPO_URL="$OPTARG"
        ;;
        u) USERNAME="$OPTARG"
        ;;
        p) PASSWORD="$OPTARG"
        ;;
    esac
done
 
# find 并批量上传
find . -type f -name '*.tgz'  | sed "s|^\./||" | xargs -I '{}' \
curl -u "$USERNAME:$PASSWORD" -X 'POST' -v \
  ${REPO_URL} \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'npm.asset=@{};type=application/x-compressed' ;

【上传依赖】

1.将NodeJs脚本downloadNpmPackage.js置于前端工程目录下且与package-lock.json文件同级:

2.在当前目录运行Node命令:

|----------------------------|
| node downloadNpmPackage.js |

等待程序下载依赖包:

下载完成后会在package-lock.json同级目录生成一个名为npm-dependencies-tgz的文件夹:

里面存放的是当前工程所有依赖的tgz文件:

将npm-dependencies-tgz文件夹打包成tar压缩包。

3.z至此上一步压缩的tar包和名为UploadnpmPackage.sh的shell脚本如下,可以将这俩发给负责依赖上传的同事,由他们完成后面的上传操作。

4.上传依赖的同事收到上述两个文件后,解压npm-dependencies-tgz.tar压缩包,得到npm-dependencies-tgz目录,将UploadnpmPackage.sh剪切到npm-dependencies-tgz目录下与所有tgz依赖包同级:

5.若是linux操作系统,则需要使用如下命令将脚本中的换行符进行转换:

|------------------------------|
| dos2unix UploadnpmPackage.sh |

若没有dos2unix则需要安装一下:sudo yum install dos2unix。如果是windows则跳过本步。

6.在npm-dependencies-tgz目录下使用如下命令运行脚本UploadnpmPackage.sh将依赖包上传到nexus上,注意红字部分根据Nexus的实际情况填写:

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

7.登录Nexus网页,查看到npm-local仓库下已经存在刚才上传的依赖了:

【使用依赖】

1.完成上述上传操作后,查看并复制npm-local仓库地址:

9.CI工具中配置依赖拉取地址为上述复制的地址:http://172.24.105.249:8089/repository/npm-local/。或者离线编译前端源码时可以使用如下命令设置npm仓库地址:

|--------------------------------------------------------------------------|
| npm config set registry=http://172.24.105.249:8089/repository/npm-local/ |

10.到此便可正常运行npm install安装依赖了。

相关推荐
Rverdoser2 分钟前
制作网站的价格一般由什么组成
前端·git·github
拉不动的猪3 分钟前
深入理解 JavaScript 中的静态属性、原型属性与实例属性
前端·javascript·面试
linda261810 分钟前
链接形式与跳转逻辑总览
前端·javascript
怪可爱的地球人15 分钟前
骨架屏
前端
用户6778471506218 分钟前
前端将html导出为word文件
前端
前端付豪20 分钟前
如何使用 Vuex 设计你的数据流
前端·javascript·vue.js
李雨泽23 分钟前
通过 Prisma 将结构推送到数据库
前端
前端小万27 分钟前
使用 AI 开发一款聊天工具
前端·全栈
咖啡の猫44 分钟前
Vue消息订阅与发布
前端·javascript·vue.js
GIS好难学1 小时前
Three.js 粒子特效实战③:粒子重组效果
开发语言·前端·javascript