🚀 真正实用的前端算法技巧:从 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.3 → 1.2.3)\
    • 去除预发布标签(如 1.2.3-beta → 1.2.3)\
    • 补齐到三位(1.2 → 1.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. ⚠️ 不适用复杂版本规则,若涉及预发布(beta、alpha)或元数据比较,应使用 semver 官方包

🧾 六、结论

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

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

一句话总结 :

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

相关推荐
hetao17338375 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
福兮说6 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
Zootopia6266 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
longlongzihan6 小时前
从LeetCode 70. 爬楼梯看动态规划:如何精准推导状态转移方程?
c++·算法·leetcode·动态规划
郑州光合科技余经理6 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6667 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
2601_960356387 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
凤城老人7 小时前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron
Dovis(誓平步青云)7 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
h_a_o777oah7 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分