@bwt-st/utils
v0.2.1
Published
Tree-shakable, framework-agnostic utility functions for BWT-ST projects.
Readme
@bwt-st/utils
面向 BWT-ST 项目的无框架工具函数库,使用 ESM 命名导出并声明 sideEffects: false。适合表单校验、URL 处理、日期处理、浏览器能力判断和常用数据转换。
安装
pnpm add @bwt-st/utils导入方式
推荐从根入口集中导入,现代打包器会根据实际使用情况进行 Tree Shaking:
import {
clamp,
formatDate,
isEmail,
isMobileDevice,
withQuery,
} from '@bwt-st/utils'也可以按类目使用子路径:
import { formatDate } from '@bwt-st/utils/date'
import { isMobileDevice } from '@bwt-st/utils/browser'根入口和类目子路径都只导出命名 API,不提供默认导出。业务项目应避免动态拼接导入路径,以便构建工具分析依赖并移除未使用代码。
API 类目
array:数组处理
chunk 按大小切分数组;unique 按 Set 规则去重;uniqueBy 按计算键去重;groupBy 按计算键分组。
chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]
uniqueBy(users, (user) => user.id)async:异步控制
sleep 延迟指定时间;withTimeout 为 Promise 增加超时限制。超时只会拒绝返回的 Promise,不会取消底层异步任务。
await sleep(300)
await withTimeout(loadUser(), 5_000)browser:浏览器能力
公开函数:isBrowser、getDeviceType、isMobileDevice、isTabletDevice、isDesktopDevice、isTouchDevice、isIOS、isAndroid、canUseClipboard、copyText、readClipboardText、getViewportSize、isOnline、downloadBlob。
if (isMobileDevice()) {
enableCompactLayout()
}
await copyText('复制内容')设备识别只适合控制交互体验,不应作为权限或安全判断依据。浏览器能力函数在 SSR 或能力不可用时返回 false、null 或失败结果,不会假设浏览器对象始终存在。
data:数据校验
公开函数:isEmptyString、isBlank、isNonEmptyString、isEmptyArray、isNonEmptyArray、isEmptyObject、isNonEmptyObject、isEmptyValue、hasKeys、hasValues、isArrayOf、isRecordOf、isValidDate、isInteger、isPositiveNumber、isNonNegativeNumber、isInRange、isSafeInteger、isJsonString。
isEmptyValue(null) // true
isEmptyValue(0) // false
isInRange(80, 0, 100) // trueisEmptyValue 只将 null、undefined、空白字符串、空数组和空普通对象视为空;0、false 和 NaN 会被视为有值。
date:日期处理
公开函数:isDate、isValidDate、startOfDay、endOfDay、addDays、differenceInDays、isSameDay、formatDate。
formatDate(new Date('2026-01-02T09:05:06'), 'YYYY-MM-DD HH:mm:ss')
// '2026-01-02 09:05:06'
addDays('2026-01-01', 7)日期函数支持 Date、日期字符串和毫秒时间戳,并按本地自然日处理。格式化令牌支持 YYYY、MM、DD、HH、mm、ss 和 SSS。日期输入无效时会抛出 TypeError。
function:函数控制
公开函数:noop、identity、once、debounce。
const search = debounce((keyword: string) => requestSearch(keyword), 300)
search('web')
search.cancel()once 只执行原函数一次并缓存返回值;debounce 返回的函数带有 cancel() 方法,等待时间必须是非负有限数值。
number:数值处理
公开函数:clamp、roundTo。
clamp(120, 0, 100) // 100
roundTo(12.345, 2) // 12.35clamp 要求 min <= max;roundTo 的小数位数必须是非负整数。
object:对象处理
公开函数:pick、omit。
const user = { id: 1, name: 'Ada', token: 'secret' }
pick(user, ['id', 'name'])
omit(user, ['token'])两个函数都只处理自有属性、返回新对象且不会修改输入对象。
string:字符串处理
公开函数:capitalize、camelCase、truncate。
capitalize('hello') // 'Hello'
camelCase('user_name') // 'userName'
truncate('前端基础能力库', 6) // '前端基...'truncate 的 length 表示最终字符串最大长度,后缀也计入长度。
type:类型判断
公开函数:isDefined、isNil、isString、isNumber、isFiniteNumber、isArray、isRecord、isPlainObject、hasOwn。
const value: unknown = getValue()
if (isRecord(value) && hasOwn(value, 'name') && isString(value.name)) {
console.log(value.name)
}这些函数同时提供 TypeScript 类型收窄。注意 isNumber 会将 NaN 和正负无穷判断为 number;需要有限数值时使用 isFiniteNumber。
url:URL 处理
公开函数:joinUrl、stringifyQuery、withQuery、getQueryParam、setQuery、removeQuery、parseQuery、parseUrl、resolveUrl、getUrlOrigin、isSameOrigin。
withQuery('/users?page=1', {
status: 'active',
tag: ['a', 'b'],
})
// '/users?page=1&status=active&tag=a&tag=b'
isSameOrigin('https://example.com/a', 'https://example.com/b') // true查询参数中的 null 和 undefined 会被忽略,数组会生成多个同名参数。解析相对 URL 时需要提供绝对 baseUrl;无效 URL 通常返回 null,resolveUrl 解析失败时会抛出 TypeError。
regex:正则格式校验
公开函数:isMobilePhone、isEmail、isHttpUrl、isUrl、isIdCard、isLandlinePhone、isIntegerString、isDecimalString、isNumericString、isRmbAmount、isRmbCurrency、isUsdAmount、isUsdCurrency、isChinesePostalCode、isIPv4、isHexColor、isUsername。
isMobilePhone('13800138000') // true
isEmail('[email protected]') // true
isRmbCurrency('¥1,234.56') // true所有校验函数只判断格式,不证明手机号、邮箱、身份证或地址真实有效。规则面向中国大陆常见企业项目;金额默认只接受非负数且最多两位小数。
兼容性
- Node.js
>=20.19.0 - 支持 ESM 和现代 Tree Shaking 的构建工具
browser类目在 SSR 中可以安全导入,但浏览器能力不可用时会返回保守结果- 详细的参数、返回值和逐函数示例可参阅仓库的
docs/utils/类目文档
