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

相关推荐
AiXed18 分钟前
PC微信协议之AES-192-GCM算法
前端·数据库·python
AllData公司负责人20 分钟前
实时开发平台(Streampark)--Flink SQL功能演示
大数据·前端·架构·flink·开源
小满zs44 分钟前
Next.js第五章(动态路由)
前端
清沫1 小时前
VSCode debugger 调试指南
前端·javascript·visual studio code
一颗宁檬不酸1 小时前
页面布局练习
前端·html·页面布局
zhenryx2 小时前
React Native 自定义 ScrollView 滚动条:开箱即用的 IndicatorScrollView(附源码示例)
javascript·react native·react.js·typescript
田梓燊2 小时前
红黑树分析 1
算法
金木讲编程3 小时前
Claude、Agent与Copilot协作生成Angular应用
前端·ai编程
晚风吹长发3 小时前
二分查找算法+题目详解
c++·算法·二分查找
悠悠~飘3 小时前
18.PHP基础-递归递推算法
算法·php