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

相关推荐
小行星1255 分钟前
前端把dom页面转为pdf文件下载和弹窗预览
前端·javascript·vue.js·pdf
Lysun00114 分钟前
[less] Operation on an invalid type
前端·vue·less·sass·scss
J总裁的小芒果30 分钟前
Vue3 el-table 默认选中 传入的数组
前端·javascript·elementui·typescript
Lei_zhen9632 分钟前
记录一次electron-builder报错ENOENT: no such file or directory, rename xxxx的问题
前端·javascript·electron
咖喱鱼蛋35 分钟前
Electron一些概念理解
前端·javascript·electron
yqcoder36 分钟前
Vue3 + Vite + Electron + TS 项目构建
前端·javascript·vue.js
鑫宝Code1 小时前
【React】React Router:深入理解前端路由的工作原理
前端·react.js·前端框架
Mr_Xuhhh2 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
永乐春秋3 小时前
WEB攻防-通用漏洞&文件上传&js验证&mime&user.ini&语言特性
前端
鸽鸽程序猿3 小时前
【前端】CSS
前端·css