背景

今天突然碰到了一个兼容性需求,需要根据不同 macOS 版本,进行不同的兼容性处理。

没想到看似简单的需求,中间也经历了一番波折,好在最后解决了问题。

在此记录一下解决问题的过程,也方便其他有类似需求的同学参考。

获取系统类型

既然需要针对 mac 系统进行兼容性处理,首先需要区分系统类型,好在 node 提供了相关的 API,只需使用 os.platform() 即可直接获取系统类型。

import { platform } from 'os';

console.log(platform()); // 'darwin'

值得一提的是,macOS 对应的名称不是 macOS 而是 darwin

除了可以通过 os 这个包获取系统类型,我们还可以通过 process.platform 来获取。

import { platform } from 'process';

console.log(platform); // 'darwin'

获取系统版本

很多熟悉 node 的同学这时候会说了,可以通过 os.release() 快速获取系统版本。但是,当你执行 os.release() ,你会发现,它的结果并符合常规认知。

比如,我的系统版本是 12.0.1,但是,os.release() 的执行结果却是 21.1.0

查看 node 官方文档可以发现,node 是通过 uname(3) 来确定操作系统的,所以执行结果比较违背常规认知。

通过命令行获取系统版本

既然 os.release() 获取的系统版本很难让人理解,那么有没有什么方案可以直接获取实际的系统版本号呢?

mac 上存在 sw_vers 命令,可以直接获取系统信息。

$ sw_vers
ProductName: macOS
ProductVersion: 12.0.1
BuildVersion: 21A559

可以看到 sw_vers 命令直接获取到了系统版本:12.0.1

如果不需要其他系统信息,我们可以通过添加命令行参数,过滤命令行结果,直接获取系统版本。

$ sw_vers -ProductVersion
12.0.1

由于命令行不区分大小写,所以命令行参数无所谓大小写,你也可以写成 -productversion 或者 -ProductVersion

既然知道命令行怎么写,接下来我们只需要在 node 中调用命令行即可。

import { execSync } from 'child_process';
console.log(execSync('sw_vers -ProductVersion', { encoding: 'utf-8' })); // 12.0.1

优雅地获取系统版本

通过 node 子进程执行命令行命令,可以获取正确的系统版本。但是这种方式有着性能方面的缺陷,需要创建子进程执行命令行,相对于 os.release() 的方式,开销较大。

之前使用 os.release() 的问题在于返回结果比较违反常规认知,但是它的结果其实是正确的,只不过需要进行一次映射。

所以,通过 os.release() 配合映射表即可优雅地获取系统版本。

import os from 'os';

const macVersionMap = new Map([
[21, ['Monterey', '12']],
[20, ['Big Sur', '11']],
[19, ['Catalina', '10.15']],
[18, ['Mojave', '10.14']],
[17, ['High Sierra', '10.13']],
[16, ['Sierra', '10.12']],
[15, ['El Capitan', '10.11']],
[14, ['Yosemite', '10.10']],
[13, ['Mavericks', '10.9']],
[12, ['Mountain Lion', '10.8']],
[11, ['Lion', '10.7']],
[10, ['Snow Leopard', '10.6']],
[9, ['Leopard', '10.5']],
[8, ['Tiger', '10.4']],
[7, ['Panther', '10.3']],
[6, ['Jaguar', '10.2']],
[5, ['Puma', '10.1']],
]); const getMacRelease = (release: string) => {
const macRelease = release ?? os.release();
const firstReleaseVersion = Number(macRelease.split('.')[0]);
const [name, version] = macVersionMap.get(firstReleaseVersion) || [
'Unknown',
'',
]; return {
name,
version,
};
}; console.log(getMacRelease()) // 12

为了方便 mac 新发布系统后依然能够识别,将新系统版本名称识别为 Unknow,新版本识别为空字符串。

此举是学习移动端机型打分平台,如果出现版本为空时,默认为高版本,不影响低版本的兼容性处理。

现在,我们就能够通过 node 优雅地获取系统版本啦。

聊聊 node 如何优雅地获取 mac 系统版本的更多相关文章

  1. Delphi 10.3版本获取windows系统版本和CPU信息

    procedure TForm1.Button1Click(Sender: TObject); var mm:TRegistry; cpu:string; begin mm:=TRegistry.Cr ...

  2. 获取iOS系统版本 --- UIDevice

    UIDevice类是一个单例,其唯一的实例( [UIDevice currentDevice] ) 代表了当前使用的设备. 通过这个实例,可以获得设备的相关信息(包括系统名称,版本号,设备模式等等). ...

  3. 查看mac系统版本

    打开终端, 输入命令 uname -a 回车 x86_64 表示系统为64位 i686 表示系统32位的

  4. Node.js获取mac网卡地址

    一.关于getmac node.js没有直接获取mac网卡地址的模块,此时我们需要借助于第三方模块getmac.getmac 可以帮助我们 获取当前机器上的mac地址.gatmac 下载地址为:htt ...

  5. 通过JAVA代码获取手机的一些基本信息(本机号码,SDK版本,系统版本,手机型号)

    代码如下: package com.zzw.getPhoneInfos; import android.app.Activity; import android.content.Context; im ...

  6. mac 下获取 os x 的系统版本,使用 oc cocoa

    mac 下获取 os x 的系统版本,使用 oc cocoa 1: #import <CoreServices/CoreServices.h> SInt32 major, minor, b ...

  7. C# 获取Windows系统:Cpu使用率,内存使用率,Mac地址,磁盘使用率

    一.获取CPU使用率: #region 获取CPU使用率         #region AIP声明          [DllImport("IpHlpApi.dll")]   ...

  8. Node+GitLab实现小程序CI系统

    为什么要实现自动部署 小程序开发迭代里,有以下几个个头痛的问题, 如何准确并快速的的把小程序上传去后台,并让测试人员进行测试? 测试同事找开发要二维码,效率较低 本地生成的二维码会出现携带本地代码.未 ...

  9. 新买苹果电脑,mac系统中小白应该了解哪些东西?

    本文旨在分享新买了mac电脑,应该做哪些设置,帮助苹果电脑小白轻松上手使用mac电脑,当然,新电脑肯定是需要安装各种软件,这里,小编推荐一下可以看看小编写的mac软件装机必备Mac 装机必备软件推荐, ...

随机推荐

  1. JVM的垃圾回收算法有哪些

    常用的垃圾回收算法有如下四种:标记-清除.复制.标记-整理和分代收集. 标记-清除算法从算法的名称上可以看出,这个算法分为两部分,标记和清除.首先标记出所有需要被回收的对象,然后在标记完成后统一回收掉 ...

  2. windows 访问 CentOS 的防火墙及其 网关开放

    1.防火墙开放端口 firewall-cmd --zone=public --add-port=8848/tcp --permanent firewall-cmd --list-ports 开放cen ...

  3. springboot 定时任务 session报错问题

    一.自定义类 LocalVariable package com.lh.mes.base.thread; import java.util.Optional; public class LocalVa ...

  4. Thymeleaf+Spring使用自己的工具类

    第一种.提供思路,继承SpringStandardDialect,重写getExpressionObjectFactory方法,设置expressionObjectFactory的实际对象,并在Tem ...

  5. Leetcode刷题之链表中箭头转移和内容转移

    链表中箭头转移和内容转移 链表中特别注意xxx.next=xxx 和xxx=xxx的区别 xxx.next=xxx表示将指针(箭头)转移 xxx=xxx表示将内容转移 Leetcode206翻转链表 ...

  6. H5: 表单验证失败的提示语

    前言     前端的童鞋在写页面时, 都不可避免的总会踩到表单验证这个坑. 这时候, 我们就要跪了, 因为要写一堆js来检查. 但是自从H5出现后, 很多常见的表达验证, 它都已经帮我们实现了, 让我 ...

  7. 一个很好用的 vue-picker组件

    vue-picker a picker componemt for vue2.0 走了一圈 github 都没有找到自己想要的移动端的 vue-picker的组件,于是自己就下手,撸了一个出来,感受下 ...

  8. 设计模式-观察者模式Observe的实现

    using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> / ...

  9. python计算项目净现值和内部回报率

     代码: import numpy as np from numpy import irr import warnings def project(number, period_list): rate ...

  10. CCF201409-3 字符串匹配

    问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符:当选项关闭时,表示同一个字母的大写和小写 ...