npm包比较最新版本算法,并支持比较先行版本

709 阅读1分钟

npm包的版本包格式

{major} . {minor} . {patch} - {pre-release}
{主版本号} . {次版本号} . {修补版本号} - {先行版本类型}.{先行版本编号}

  • 主版本号:新增了一些不向下兼容的API和功能
  • 次版本号:新增了一些向下兼容的功能
  • 修补版本号:对一些bug的修复
  • 先行版本号:一些实验性的功能发布 - alpha测试、beta预发|灰度、tc最接近正式版

vue的发布版本号: image.png

算法实现如下:

本算法对一个npm包的不同版本进行了比较

/**
 * 比较插件的两个版本v1,v2大小
 * .e.g '3.1.7-alpha.19'
 * @param v1 { string } {major}.{minor}.{patch}-{pre-release}
 * @param v2 { string } {major}.{minor}.{patch}-{pre-release}
 * @return {number} 1大 0相等 -1小
 */
const compareVersionLatest = (v1: string, v2: string): number => {
  const [v1Main, v1PreRelease] = v1.split('-')
  const [v2Main, v2PreRelease] = v2.split('-')

  // 比较版本主体的大小
  const v1List = v1Main.split('.')
  const v2List = v2Main.split('.')
  const len1 = v1List.length
  const len2 = v2List.length
  const minLen = Math.min(len1, len2)
  let curIdx = 0
  for (curIdx; curIdx < minLen; curIdx += 1) {
    const v1CurNum = parseInt(v1List[curIdx])
    const v2CurNum = parseInt(v2List[curIdx])
    if (v1CurNum > v2CurNum) {
      return 1
    } else if (v1CurNum < v2CurNum) {
      return -1
    }
  }
  if (len1 > len2) {
    for (let lastIdx = curIdx; lastIdx < len1; lastIdx++) {
      if (parseInt(v1List[lastIdx]) != 0) {
        return 1
      }
    }
    return 0
  } else if (len1 < len2) {
    for (let lastIdx = curIdx; lastIdx < len2; lastIdx += 1) {
      if (parseInt(v2List[lastIdx]) != 0) {
        return -1
      }
    }
    return 0
  }

  // 如果存在先行版本,还需要比较先行版本的大小
  if (v1PreRelease && !v2PreRelease) {
    return 1
  } else if (!v1PreRelease && v2PreRelease) {
    return -1
  } else if (v1PreRelease && v2PreRelease) {
    const [gama1, time1] = v1PreRelease.split('.')
    const [gama2, time2] = v2PreRelease.split('.')
    if (gama1 > gama2) return 1
    if (gama2 > gama1) return -1
    if (parseInt(time1) > parseInt(time2)) return 1
    if (parseInt(time2) > parseInt(time1)) return -1
  }
  return 0
}