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

相关推荐
GIS程序媛—椰子1 小时前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_0011 小时前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端1 小时前
Content Security Policy (CSP)
前端·javascript·面试
木舟10091 小时前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤43911 小时前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢2 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安2 小时前
前端第二次作业
前端·css·css3
啦啦右一2 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落2 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt