npm 私有依赖路径配置

一、前面的话

最近开发的过程中,发现公司的部分依赖采用了私有依赖,直接采用 npm i 的方式没办法安装,因此记录下解决的过程

二、先删后增法

目前npm镜像配置已经全局配置为淘宝镜像,所以,对于除了私有依赖(后面以lowcode.fsd.frontend代表私有依赖)之外的其他依赖,我们可以直接使用npm i进行快速安装,因此,我将lowcode.fsd.frontend先从package.json文件中删除,执行一次 npm i,待依赖安装完毕后,单独安装lowcode.fsd.frontend

shell 复制代码
npm i -S lowcode.fsd.frontend --registry https://xxxx.xxx.com

依赖是成功装上了,package.json dependences中也有了新加了这一项

json 复制代码
{
    "dependencies": {
        "lowcode.fsd.frontend": "^1.0.180"
     }
}

但是问题来了,后面有人重新拉取依赖后,也得这样安装,不够方便,有没有办法直接通过 npm i 一次性安装成功呢?

三、配置镜像法

通过查阅 npm文档 可知,当依赖通过scope方式注册时,可以为单个依赖单独配置镜像设置(辅助阅读文档npm指定依赖包私有源问题记录 - 掘金 (juejin.cn)),

我以@vue/cli@ant-design/colors进行了测试,测试过程中,.npmrc文件内容如下

shell 复制代码
#设置项目所用的npm镜像
registry=http://192.168.x.xxx:xxxx/

#设置@vue范围包镜像,对诸如@vue/cli,@vue/compiler-sfc等生效
@vue:registry=http://mirrors.cloud.tencent.com/npm/ #腾讯云镜像

#设置@ant-design范围包镜像
@ant-design:registry=http://registry.npmmirror.com #淘宝镜像

package.json内容如下:

json 复制代码
{
  "dependencies": {
    "lowcode.fsd.frontend": "^1.0.180",
    "@ant-design/colors": "^7.0.2",
    "vant": "2.13.1",
    "mockjs": "1.1.0",
    "moment": "2.29.1"
  },
  "devDependencies": {
    "@vue/compiler-sfc": "^3.4.21"
  }
}

执行npm i之后,在生成的package-lock.json中,可以发现镜像生效

但是问题来了,我这里的私有包也没有定义范围啊,该方法行不通!!! [苦涩.jpg]

三、直接指定法

在npm文档关于dependencies的描述中,对于依赖的写法可以设置为 版本号、git、本地路径、tarball等形式,如图

从给出的示例可以看到,当采用http的方式代替依赖版本范围时(示例中 asd 依赖),需要给出依赖tar.gz的地址,这个地址怎么获取呢,这里给出两个方案

  • 方案一: 采用npm命令的形式
shell 复制代码
# npm info 包名,我的包是lowcode.fsd.frontend
npm info lowcode.fsd.frontend

命令结果返回如上图,在图中可以看到dist下的tarball字段,该字段后面的路径对应的就是依赖包地址。当然,因为是私有包,可能会出现下面的报错

遇到这种错误时,可以在项目根目录下临时新建.npmrc文件,在里面定义项目npm采用的镜像地址,如下

shell 复制代码
#设置项目所用的npm镜像
registry=http://192.168.x.xxx:xxxx/

然后再执行info或者view命令就可以了

  • 方案二:从package-lock.json中获取。如果采用先删后增法安装过该依赖,可以搜索依赖名,依赖下resolved字段对应的路径即为tarball路径,示例如图

改写后的package.json如下

json 复制代码
 "dependencies": {
    "lowcode.fsd.frontend": "http://192.168.xx.xxxx:xxxx/lowcode.fsd.frontend/-/lowcode.fsd.frontend-1.0.180.tgz"
  },

当然,这个方法虽然解决了直接通过npm i安装依赖报错的问题,但是,却没办法自动更新版本了,需要手动更新版本号

ps:因为项目采用svn的管理方式,因此,验证时采用http的方式改写version

四、脚本注入

npm i执行的过程中,会执行 package.jsonscripts中定义的preinstall构子,因此,我们可以通过该钩子实现自动更新tarball地址,脚本代码示例如下,这里以vant作为演示示例

js 复制代码
// script.js
const fs = require('fs');
const path = require('path');
const http = require('https');
const pkgPath = path.join(__dirname, 'package.json');
const moduleName = 'vant'
const tarballUrl = 'https://registry.npmmirror.com/' + moduleName;
// 获取package.json内容
let pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
const oldUrl = pkg.dependencies[moduleName]; 
// oldUrl = https://registry.npmmirror.com/vant/-/vant-1.6.28.tgz 或者^4.1.8
// 更新名为 moduleName 的tarball依赖项
async function updateTarballDependency() {
  // 这里是逻辑去获取新版本tarball的URL,比如通过API请求
  const latestVersion = await getLatestVersion();

  pkg.dependencies[moduleName] = getNewUrl(latestVersion);
  // 更新package.json,并格式化
  const updatedPkgJson = JSON.stringify(pkg, null, 2);
  fs.writeFileSync(pkgPath, updatedPkgJson);
}
// 获取latest对应的版本号
function getLatestVersion() {
  return new Promise((resolve, reject) => {
    const req = http.request(tarballUrl, (res) => {
      res.setEncoding('utf-8');
      const list = [];
      res.on('data', (chunk) => {
        list.push(chunk);
      });
      res.on('end', () => {
        try {
          const json = JSON.parse(list.join(''));
          resolve(json['dist-tags'].latest);
        } catch (error) {
          reject(error);
        }
      });
    });
    req.end();
  });
}

// 返回的是对应版本号的tarball地址
function getNewUrl(version) {
  if (oldUrl.startsWith('http')) {
        // tarball写法
        let urlStrs = oldUrl.split('-');
        let lastItem = urlStrs.pop();
        urlStrs.push(version + lastItem.substring(lastItem.length - 4));
        return urlStrs.join('-');
    } else {
        return tarballUrl + `/-/${moduleName}-${version}.tgz`
    }
}
updateTarballDependency()
  .then(() => console.log('Successfully updated tarball dependency'))
  .catch((err) => console.error('Error updating dependency:', err));

package.json中的修改如下,新增一个脚本

json 复制代码
"scripts": {
     "preinstall": "node ./scripts.js"
 },

最后,依赖下载完之后,查看package-lock.json,可以看到,vant的版本更新为了latest对应的版本

这里附上之前的package.json

json 复制代码
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "preinstall": "node ./scripts.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "vant": "https://registry.npmmirror.com/vant/-/vant-1.6.28.tgz"
  }
}

五、写在最后

文中使用的node版本为14.16.0,对应的npm版本为6.14.11,不同的npm版本可能结果不一致,如有错误,欢迎大家指出。

相关推荐
gyratesky3 分钟前
用4种方法实现内发光的多边形区域
前端·数据可视化
敲代码的彭于晏31 分钟前
前端上传与下载基础:Blob、File与ArrayBuffer详解
前端
緑水長流36 分钟前
什么是Promise?什么是async和await?
前端·javascript·vue.js
Mintopia36 分钟前
Three.js 相机(Camera)的使用详解
前端·javascript·three.js
wordbaby39 分钟前
PC 屏幕自适应的流行方案解析
前端
Mintopia40 分钟前
Node.js 中path模块的深度解析与实战应用
前端·javascript·node.js
程序员小续41 分钟前
git rebase 和git merge使用及区别
前端·git·后端
静待一世花开41 分钟前
React基础学习
前端
华科云商xiao徐42 分钟前
使用Scrapy编写图像下载程序示例
前端
WillaWang42 分钟前
html结构中图片下方的间隙
前端