npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@142vip/utils

v0.0.1-alpha.57

Published

通用型基础工具集合,对常用模块的二次集成

Readme

@142vip/utils

NPM version

通用型基础工具集合,对常用模块的二次集成

安装

# npm
npm install @142vip/utils -D
# pnpm
pnpm i @142vip/utils

说明

@142vip/utils 同时提供 Node 服务端和浏览器客户端可消费的工具能力。

  • 默认从 @142vip/utils 导入时: 浏览器构建工具会优先命中 browser-safe 导出,避免把 node:fschild_process 等 Node 运行时能力打进前端包。
  • Node 运行时从 @142vip/utils 导入时: 仍然可以拿到完整能力,兼容现有服务端用法。
  • 如果业务需要显式约束运行时: 可以使用 @142vip/utils/browser@142vip/utils/node

使用

浏览器 / 通用场景

适合浏览器、SSR 前端、同构代码中直接使用的能力,优先从根入口导入即可:

import { vipDayjs, vipDocSite, vipLodash, vipQs, VipSemver } from '@142vip/utils'

const version = VipSemver.valid('1.2.3')
const query = vipQs.stringify({ page: 1, size: 10 })
const date = vipDayjs().format('YYYY-MM-DD')
const base = vipDocSite.getBase('core-x')

// 外部 JSON 边界:避免 `value as Record<string, unknown>`
const payload = vipLodash.toJsonRecord(apiResponse)
if (vipLodash.isJsonRecord(nested)) {
  console.log(nested.items)
}

const names = vipLodash.compactMap(users, user => user.nickname)

console.log(version, query, date, base)

当前浏览器安全导出的能力主要包括:

  • VipColor
  • VipConsolevipLogger
  • VipDayjsvipDayjs(日期模板见 DateFormatTemplate
  • VipSemver
  • VipNanoIdvipNanoId
  • VipQsvipQs
  • VipYaml
  • vipDataTransform
  • vipLodash(lodash 原生 + 扩展;见下节)
  • VipDocSitevipDocSite
  • enums 目录下的枚举与类型(含 TimeDurationMsTimeDurationSec 等,浏览器 / 服务端均可使用)

vipLodash(lodash 扩展 · 不覆盖原生)

vipLodash = lodash 全量方法(去掉 VERSION)+ 少量 新增 扩展键。实现为对象展开:先 ...lodashBase,再 ...vipLodashExtensions不会改写 pick / map / isPlainObject 等原生行为。

| 扩展方法 | 说明 | |----------|------| | isJsonRecord | 平面对象守卫(语义同 isPlainObject + TS 收窄) | | toJsonRecord | unknownJsonRecord,非对象返回 {} | | compactMap | mapcompact 去 falsy |

扩展方法通过 vipLodash.xxx 调用,根入口不单独 export。新增扩展时禁止与 lodash 已有方法同名。

import type { JsonRecord } from '@142vip/utils'
import { vipLodash } from '@142vip/utils'

vipLodash.pick(obj, ['a']) // lodash 原生
vipLodash.compactMap(list, item => item.name) // 扩展

时间跨度枚举

毫秒与秒两套枚举,适用于 TTL、缓存过期、轮询间隔等场景:

// 浏览器 / 同构:根入口或 browser 子路径
import { TimeDurationMs, TimeDurationSec } from '@142vip/utils'
import { TimeDurationMs } from '@142vip/utils/browser'

// 仅需枚举、避免带入其他工具时
import { TimeDurationMs, TimeDurationSec } from '@142vip/utils/enums'

// Node 服务端
import { TimeDurationSec } from '@142vip/utils/node'

const cacheTtl = TimeDurationMs.FIVE_MINUTE
const redisExpire = TimeDurationSec.ONE_DAY

日期格式模板枚举

定义在 dayjs 模块内,配合 vipDayjs.formatDateToStr 使用:

import { DateFormatTemplate, vipDayjs } from '@142vip/utils'

vipDayjs.formatDateToStr(new Date()) // YYYY-MM-DD HH:mm:ss
vipDayjs.formatDateToStr(new Date(), DateFormatTemplate.DATE) // YYYY-MM-DD
vipDayjs.formatDateToStr(new Date(), DateFormatTemplate.DATE_DOT) // YYYY.MM.DD
vipDayjs.formatDateToStr(new Date(), DateFormatTemplate.DATE_SLASH) // YYYY/MM/DD
vipDayjs.formatDateToStr(new Date(), DateFormatTemplate.MONTH_DAY_TIME) // MM/DD HH:mm
vipDayjs.formatDateToStr(new Date(), DateFormatTemplate.DATETIME_CN) // YYYY年MM月DD日 HH:mm:ss
vipDayjs.formatMonthDay(new Date()) // 8月9日
vipDayjs.formatMonthDay(new Date(), 'en') // Aug 9
vipDayjs.formatToISOStr() // ISO-8601 UTC
vipDayjs.isBeforeByTtl(cachedAtMs, TimeDurationMs.ONE_MINUTE) // 是否在 1 分钟内

Node 服务端场景

Node 服务端可以继续直接使用根入口,保留现有完整能力:

import { VipExecutor, VipInquirer, VipPackageJSON } from '@142vip/utils'

async function bootstrap() {
  const packageJSON = VipPackageJSON.getPackageJSON()
  console.log(packageJSON.name)

  const { stdout } = await VipExecutor.execCommand('node -v')
  console.log(stdout)

  const result = await VipInquirer.promptCheckBox(['dev', 'test', 'prod'])
  console.log(result)
}

void bootstrap()

下面这些能力依赖 Node 运行时,不适合浏览器直接引入:

  • VipExecutor
  • VipPackageJSON
  • VipNodeJS
  • VipDocker
  • VipGit
  • VipMonorepo
  • VipNpm
  • VipInquirer
  • VipJSON
  • VipConfig
  • VipCommander

显式指定入口

如果项目本身是复杂 monorepo、SSR 或自定义构建链路,建议按运行时显式导入:

import { vipDocSite, VipSemver } from '@142vip/utils/browser'
import { VipExecutor, VipPackageJSON } from '@142vip/utils/node'

这样可以减少构建工具对条件导出的差异处理,导入语义也更明确。

升级说明

当前版本对导出结构做了运行时分流,但保持了原有 Node 场景的根入口兼容:

  • 已有 Node 服务端代码通常不需要改动。
  • 浏览器客户端如果之前因为 @142vip/utils 根入口触发 Node 内置模块报错,现在可以直接继续使用根入口。
  • 如果业务代码强依赖特定运行时,推荐改成 @142vip/utils/browser@142vip/utils/node,让依赖边界更清晰。

参考

证书

MIT

Copyright (c) 2019-present, @142vip 储凡

仅供学习参考,商业使用请保留作者版权信息,作者不保证也不承担任何软件的使用风险。