团队项目如何规范统一npm 包管理器

406 阅读2分钟

团队项目如何规范统一npm 包管理器

起因:

团队之间协作的项目可能由于npm包管理器不同,导致package.lock.yml文件导致失效,导致项目安装的依赖版本可能会有差异,导致项目会出现莫名其妙的问题,所以为了避免此种情况发生,统一项目管理依赖包工具便有了需求

原理

preinstall 是 npm 的一个钩子,它允许开发者在 npm 安装依赖之前执行一些自定义的操作,例如检测环境变量、执行安装前的自动化脚本等

开始

  1. 首先在package.json中添加
"scripts": {
  "preinstall": "node scripts/check-pnpm.js pnpm"
},

这里我项目强制使用pnpm管理工具来管理项目依赖包

  1. 在根目录下新建scripts文件 然后在文件下创建check-pnpm.js
mkdir scripts && touch check-pnpm.js
  1. 了解node 进程参数 process.argv和 procee.env?.npm_config_user_agent
`process.argv` 属性返回数组,其中包含启动 Node.js 进程时传入的命令行参数。 第一个元素将是 [`process.execPath`](https://nodejs.cn/api/process.html#)。 如果需要访问  第二个元素将是正在执行的 JavaScript 文件的路径。 其余元素将是任何其他命令行参数。

例如 我们执行如下命令

node scripts/check-pnpm.js pnpm

我们把process.argv打印出来的信息如下

// process.argv参数如下
[
'/usr/local/bin/node',
'/Users/mjr/work/node/process-args.js'
'pnpm',
]

我们执行如下代码

pnpm run preinstall

会打印如下信息

// 当前使用的包管理器信息
pnpm/8.5.1 npm/? node/v16.18.1 darwin x64 
  1. 完整代码check-pnpm.js如下
import boxen from 'boxen' // 控制台打印边框样式
const SPECIFY_PM = 'pnpm' // 所指的的依赖包管理工具
// 获取我们传递的参数<[pnpm]>
const argv = process.argv.slice(2)
const boxenOpts = { borderColor: 'red', borderStyle: 'double', padding: 1 }
// 没有传递参数给与提示并终止运行
if(argv.length === 0) {
    console.log(boxen(`请指定项目选择<<<<${SPECIFY_PM}>>>>为包管理器`, boxenOpts))
    process.exit(1) // 退出进程
}

// 我们传递的参数值
const PARAMS_PM = argv[0]

// 乱传参数给与提示并终止运行 或者传入参数不是pnpm
if(PARAMS_PM!==SPECIFY_PM) {
    console.log(boxen(`${PARAMS_PM}不是本项目指定的包管理工具. 本项目包依赖管理工具只能是${SPECIFY_PM}`, boxenOpts))
    process.exit(1)
}

// 当前使用的包管理器
const CURRENT_PM = getCurrentPmByUserAgent(process.env?.npm_config_user_agent).name
// 当前使用的包管理器和我们约束的不一样 抛出一条错误日志并终止运行
if(CURRENT_PM !== SPECIFY_PM) {
    console.error(boxen(`你现在正在使用${CURRENT_PM} 但是本项目请使用 ${SPECIFY_PM}`, boxenOpts))
    process.exit(1)
}

function getCurrentPmByUserAgent(userAgent) {
    if(!userAgent) {
        console.log(boxen('请传入 userAgent', boxenOpts))
    }
    const spec = userAgent.split(' ')[0]
    const [name, version] = spec.split('/')

    return { name, version }
}

缺点

npm 包管理工具 preinstall 和install 两个生命周期在执行过程中是有版本差异的 npm v7+ 执行顺序是先执行install 后执行 preinstall npm v7以下 执行顺序是preinstall, install

这个是他们bug,npm issue

参考链接

  1. only-allow