痛点:现有方案的局限
在 JavaScript 项目中处理单位转换时,你是否遇到过这样的困扰?
方案一:专用库
bytes只能处理文件大小filesize同样局限- 需要格式化时间、长度、货币?再装一个库
方案二:通用转换库
- 每个转换都要手动定义
- 代码臃肿,配置繁琐
javascript
// 老方式:繁琐且不灵活
const bytes = require('bytes')
const filesize = require('filesize')
// 时间、长度、货币还需要别的库...
如果只需要定义一次单位链,就能获得智能格式化和简洁的 API,会怎样?
解决方案:smart-unit
 
smart-unit 是一个轻量级的 TypeScript 优先库,提供自动单位选择的单位转换功能。专为追求优雅而不牺牲功能的开发者设计。
bash
npm install smart-unit
核心概念:简洁而强大
smart-unit 的精髓在于声明式单位链定义。只需定义一次单位和转换比例,剩下的交给库来处理。
文件大小格式化
javascript
import { SmartUnit } from 'smart-unit'
const fileSize = new SmartUnit(['B', 'KB', 'MB', 'GB', 'TB'], {
baseDigit: 1024,
})
console.log(fileSize.format(1024)) // "1KB"
console.log(fileSize.format(1536)) // "1.5KB"
console.log(fileSize.format(1024 * 1024 * 100)) // "100MB"
console.log(fileSize.format(1024 * 1024 * 1024 * 5)) // "5GB"
注意 format(1536) 自动选择了 "1.5KB" 而不是 "1536B" 或 "0.0015MB"。库会智能选择最易读的单位。
长度单位(可变比例)
并非所有单位系统都使用一致的基数。公制长度单位的比例各不相同:
javascript
const length = new SmartUnit(['mm', 10, 'cm', 100, 'm', 1000, 'km'])
console.log(length.format(1500)) // "1.5m"
console.log(length.format(1500000)) // "1.5km"
console.log(length.format(25)) // "2.5cm"
通过指定单独的比例(10、100、1000),可以准确建模任何单位层级。
双向转换:解析与格式化
smart-unit 不仅用于展示,还能将格式化字符串解析回基础值:
javascript
const time = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h'])
console.log(time.parse('90s'), 'ms') // 90000 ms
console.log(time.parse('2.5h'), 'ms') // 9000000 ms
console.log(time.parse('30m'), 'ms') // 1800000 ms
这种双向能力使其非常适合配置文件、用户输入和数据序列化。
高精度模式:突破 JavaScript 极限
JavaScript 的 number 类型安全整数上限是 2^53 - 1(约 9 千万亿)。对于金融计算或科学应用,这是致命缺陷。
smart-unit 集成 decimal.js 实现任意精度运算:
javascript
const bigLength = new SmartUnit(['pm', 1000, 'nm', 1000, 'μm', 1000, 'mm', 1000, 'm'], {
useDecimal: true,
})
console.log(bigLength.format('1000')) // "1nm"
console.log(bigLength.format('1000000')) // "1μm"
// BigInt 支持 - 超越 JS 安全整数限制
const bigNumber = 123456789012345678901234567890n
console.log('格式化结果:', bigLength.format(bigNumber))
金融计算
货币和金融数据经常超出安全整数限制,同时需要精确的十进制处理:
javascript
const currency = new SmartUnit(['', 'K', 'M', 'B', 'T'], {
baseDigit: 1000,
useDecimal: true,
fractionDigits: 2,
})
console.log(currency.format('12345678901234567890')) // "12345678.90T"
fractionDigits: 2 确保货币值保持一致的十进制位数。
对比优势
| 特性 | bytes | filesize | smart-unit |
|---|---|---|---|
| 文件大小 | ✅ | ✅ | ✅ |
| 自定义单位 | ❌ | ❌ | ✅ |
| 双向转换 | ❌ | ❌ | ✅ |
| 高精度 | ❌ | ❌ | ✅ |
| BigInt 支持 | ❌ | ❌ | ✅ |
| TypeScript | 部分 | 部分 | ✅ 原生支持 |
| 包体积 | ~1KB | ~2KB | ~2KB |
smart-unit 用专用库的体积,提供通用库的灵活性。
测试覆盖
项目包含 66 条单元测试,覆盖各种边界情况:
- BigInt 输入处理
- Decimal.js 高精度计算
- 边界值和异常处理
- 多种单位链配置
确保在生产环境中的稳定性和可靠性。
实际应用场景
数据传输速率
javascript
const bitrate = new SmartUnit(['bps', 'Kbps', 'Mbps', 'Gbps'], {
baseDigit: 1000,
fractionDigits: 1,
})
bitrate.format(1500000) // "1.5Mbps"
频率
javascript
const freq = new SmartUnit(['Hz', 'kHz', 'MHz', 'GHz'], {
baseDigit: 1000,
fractionDigits: 2,
})
freq.format(2400000000) // "2.40GHz"
存储容量(自定义阈值)
javascript
const storage = new SmartUnit(['B', 'KB', 'MB', 'GB', 'TB'], {
baseDigit: 1024,
threshold: 0.9, // 在下一单位的 90% 时切换
})
TypeScript 原生设计
smart-unit 使用 TypeScript 编写,提供完整的类型安全:
typescript
import { SmartUnit } from 'smart-unit'
import type { Decimal } from 'decimal.js'
// 普通模式 - 返回 number
const regular = new SmartUnit(['B', 'KB', 1024])
const num: number = regular.parse('1KB')
// 高精度模式 - 返回 Decimal
const precise = new SmartUnit(['B', 'KB', 1024], { useDecimal: true })
const dec: Decimal = precise.parse('1KB')
类型推断无缝工作,API 设计有意保持简洁,降低认知负担。
快速开始
bash
npm install smart-unit
javascript
import { SmartUnit } from 'smart-unit'
// 定义一次,随处使用
const size = new SmartUnit(['B', 'KB', 'MB', 'GB'], { baseDigit: 1024 })
size.format(1024 * 1024 * 100) // "100MB"
size.parse('2.5GB') // 2684354560
在线体验
直接在浏览器中体验 smart-unit:
总结
smart-unit 用优雅的方案解决了普遍存在的问题。无论是格式化文件上传、解析用户输入、处理金融数据,还是构建科学应用,它都在简洁性和功能性之间取得了完美平衡。
核心要点:
- 用极简语法定义任意单位链
- 自动选择最优单位
- 双向转换(格式化和解析)
- 高精度模式支持 BigInt
- TypeScript 原生,包体积最小
- 66 条单元测试全覆盖,稳定性有保障
在下一个项目中试试看,你的单位转换代码会感谢你的。
相关链接:
- GitHub: github.com/flycran/sma...
- npm: www.npmjs.com/package/sma...
- 协议: MIT
