🚀 真正实用的前端算法技巧:从 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

相关推荐
IronMurphy2 小时前
【算法四十三】279. 完全平方数
算法
墨染天姬2 小时前
【AI】Hermes的GEPA算法
人工智能·算法
QQ1__8115175152 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态2 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子2 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室2 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI2 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing2 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者2 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册2 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json