const chalk = require('chalk')
|
const semver = require('semver')
|
const exec = require('./exec-promise')
|
|
// 获取当前安装包版本
|
const getLocalVersion = async (pkg, isDev) => {
|
let lsInfo
|
try {
|
lsInfo = JSON.parse(await exec(`npm ls ${pkg} --json --depth=0 ${isDev ? '--dev' : '--prod'}`))
|
if (lsInfo.dependencies) {
|
lsInfo = lsInfo.dependencies[pkg].version
|
}
|
} catch (e) {
|
lsInfo = false
|
}
|
return lsInfo
|
}
|
|
// pkg: 需要安装的包名, isDev: 是否安装到 dev 依赖, pPackage: 项目的 package 文件
|
const installFuc = async (pkg, version, pPackage = {}, isDev = false) => {
|
if (!pkg) {
|
throw new Error('未传入需要安装的包名')
|
}
|
|
// 参数兼容性处理
|
const originPkg = {}
|
originPkg.dependencies = pPackage.dependencies || {}
|
originPkg.devDependencies = pPackage.devDependencies || {}
|
|
const key = isDev ? 'devDependencies' : 'dependencies'
|
|
// 获取当前安装包版本
|
let v = await getLocalVersion(pkg, isDev)
|
|
// 如果未检测到安装包版本, 属于异常, 则本地先安装一下
|
if (v) {
|
// 检测当前已安装版本是否符合要求
|
if (semver.satisfies(v, version)) {
|
console.log(`当前已存在依赖 ${pkg}@${v}`)
|
return true
|
}
|
} else {
|
console.log(chalk.yellow(`安装依赖 ${pkg}@${version}`))
|
await exec(`npm install ${isDev ? '--save-dev' : ''} ${pkg}@${version}`)
|
v = await getLocalVersion(pkg, isDev)
|
}
|
|
// 本地项目本身无该包
|
if (!originPkg[key][pkg]) {
|
return true
|
}
|
|
// 检测当前已安装版本是否符合要求
|
if (semver.satisfies(v, originPkg[key][pkg])) {
|
console.log(`当前已存在依赖 ${pkg}@${v}`)
|
return true
|
}
|
|
// 不符合要求则按照项目要求回滚
|
await exec(`npm install ${isDev ? '--save-dev' : ''} ${pkg}@${originPkg[key][pkg]}`)
|
|
// 检测回滚后能否符合要求
|
v = await getLocalVersion(pkg, isDev)
|
if (semver.satisfies(v, version)) {
|
console.log(`已更新依赖 ${pkg}@${v}`)
|
return true
|
}
|
|
// 回滚后还是不符合, 说明两版本要求冲突
|
throw new Error(`依赖包 ${pkg} 与本地版本有冲突, 版本要求是 ${version}, 本地项目要求是 ${originPkg[key][pkg]}`)
|
}
|
|
module.exports = installFuc
|