🚀 真正实用的前端算法技巧:从 semver-compare 到智能版本排序

背景

如图,真实的场景中,数据会返回很多版本号,需要和当前版本做比较,筛选出比当前版本更新的版本,以及对版本进行排序等。

其实在前端工程中,我们经常需要比较不同版本号,例如判断:

  • 某个包是否有新版本;
  • 数据结构或配置文件版本是否落后;
  • 更新提示是否应该展示。

大多数人第一反应可能是使用 semver 包,但其实有时候我们只需要一个简单的比较函数 ,而不需要完整的语义化解析。这时 semver-compare 就是一个极佳选择。


🧩 一、库介绍

semver-compare 是一个极小的 npm 库(仅十几行代码),功能非常单一:

👉 比较两个语义化版本号(SemVer),返回 -1 / 0 / 1

bash 复制代码
pnpm add semver-compare

⚙️ 二、源码解析

来看源码(几乎是整个库的全部内容):

js 复制代码
// semver-compare/index.js
module.exports = function cmp (a, b) {
    var pa = a.split('.');
    var pb = b.split('.');
    for (var i = 0; i < 3; i++) {
        var na = Number(pa[i]);
        var nb = Number(pb[i]);
        if (na > nb) return 1;
        if (nb > na) return -1;
        if (!isNaN(na) && isNaN(nb)) return 1;
        if (isNaN(na) && !isNaN(nb)) return -1;
    }
    return 0;
};

核心逻辑:

  1. 将版本号字符串按 . 拆分为数组
  2. 逐段转成数字并比较
  3. 如果前两段相等,继续比较后面的
  4. 若全部相等则返回 0
  5. 如果 A > B 返回 1,反之 -1

简单、高效、无依赖。


📖 三、语义化版本(SemVer)简要回顾

语义化版本号的基本格式是:

复制代码
MAJOR.MINOR.PATCH

例如:

复制代码
1.4.2

其意义是:

  • MAJOR:破坏性更新(不兼容变更)
  • MINOR:新增功能但兼容
  • PATCH:修复 bug

可附加:

  • 预发布版本:1.4.2-beta
  • 元数据:1.4.2+build2025

🧠 四、示例代码解析

js 复制代码
const normalizeVersion = (v) => {
  const base = String(v || "")
    .trim()
    .replace(/^v/i, "")
    .split("-")[0]; // 去掉 'v' 前缀与预发布标签
  const parts = base.split(".").map((n) => n.replace(/[^\d]/g, ""));
  const clean = parts.filter(Boolean);
  while (clean.length < 3) clean.push("0"); // 补齐到 x.y.z
  return clean.slice(0, 3).join(".");
};

const result =
  versions
    ?.sort((a, b) =>
      semverCompare(
        normalizeVersion(a?.version),
        normalizeVersion(b?.version)
      )
    )
    .filter(
      (item) =>
        semverCompare(
          normalizeVersion(data?.version),
          normalizeVersion(item?.version)
        ) < 0
    ) || [];

🔍 拆解:

  1. normalizeVersion()
    • 清洗版本号:去掉前缀 v(如 v1.2.31.2.3)\
    • 去除预发布标签(如 1.2.3-beta1.2.3)\
    • 补齐到三位(1.21.2.0
  2. 排序与过滤
    • 使用 semverCompare 对所有版本进行排序;
    • 再筛选出「比当前版本新的」版本。

🧩 举例

js 复制代码
const versions = [{version: "v1.0.0"}, {version: "1.2.0"}, {version: "1.1.5-beta"}];
const data = {version: "1.0.5"};

const result = versions
  .sort((a, b) => semverCompare(normalizeVersion(a.version), normalizeVersion(b.version)))
  .filter(item => semverCompare(normalizeVersion(data.version), normalizeVersion(item.version)) < 0);

console.log(result.map(r => r.version)); 
// => ["1.1.5-beta", "1.2.0"]

🪄 五、适用场景

  1. 版本排序 将一组版本按新旧排序
  2. 检测新版本 比较当前版本是否落后
  3. 更新提示系统 App、插件、配置管理等
  4. 构建时依赖检查 判断依赖库最小版本是否满足要求
  5. ⚠️ 不适用复杂版本规则,若涉及预发布(betaalpha)或元数据比较,应使用 semver 官方包

🧾 六、结论

semver-compare 是一个 极轻量但实用 的库:

  • 适合运行时比较;
  • 特别适合 "检测新版本 / 排序版本列表" 的场景;
  • 若未来涉及更复杂规则,可平滑迁移到 semver 官方包。

一句话总结

小场景选 semver-compare,大项目选 semver

相关推荐
海梨花3 小时前
【力扣Hot100】刷题日记
算法·leetcode·1024程序员节
云枫晖3 小时前
Webpack系列-Output出口
前端·webpack
用户268001379193 小时前
有哪些高效的Python库可以用于解析淘宝评论的JSON数据?
前端·api
brzhang3 小时前
A Definition of AGI:用人的智力模型去量 AI,这事靠谱吗?
前端·后端·架构
一 乐3 小时前
宠物管理|宠物店管理|基于SSM+vue的宠物店管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·宠物
咖啡の猫3 小时前
Vue插件
前端·javascript·vue.js
韩劳模3 小时前
Canvas、SVG实现不规则区域高亮的方案说明
前端
DuHz4 小时前
使用稀疏采样方法减轻汽车雷达干扰——论文阅读
论文阅读·算法·汽车·信息与通信·信号处理
张可爱4 小时前
20251026-从网页 Console 到 Python 爬虫:一次 B 站字幕自动抓取的实践与复盘
前端·python