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版本可能结果不一致,如有错误,欢迎大家指出。

相关推荐
Vicky&James11 分钟前
WPF到Web的无缝过渡:英雄联盟客户端项目OpenSilver迁移实战
前端·wpf
m0_7482336414 分钟前
RabbitMQ 进阶
android·前端·后端
不想有bug的小菜鸟23 分钟前
vue3使用iframe全屏展示pdf效果
前端·pdf
m0_7482386323 分钟前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
u01005596024 分钟前
前端代理,解决跨域问题讲解
前端
quitv29 分钟前
react脚手架配置别名
前端·javascript·react.js
m0_5287238138 分钟前
前端如何进行性能优化
前端·性能优化
化作繁星40 分钟前
在 Vue 3 中,如何缓存和复用动态组件
前端·vue.js·缓存
一粒沙-1 小时前
iOS 将GIF图分享至微信
前端·ios
graywen1 小时前
从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
前端