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

@imhjh/common

v1.4.4

Published

通用 js/css 库

Readme

@imhjh/common 文档

源码

安装

# npm
npm install @imhjh/common --save-dev
# yarn
yarn add @imhjh/common --save

方法库

通过 import from 导入.

// 使用 dataType 方法
import { dataType } from "@imhjh/common"

dataType

数据类型判断方法.

通过 typeinstanceof 判断数据类型.

可判断 布尔值、字符串、数字、数组、函数、file、blob、json 对象、时间对象、undefined、null.

无法判断的类型返回 false.

type DataType = "boolean" | "string" | "number" | "array" | "function" | "date" | "file" | "blob" | "object" | "undefined" | "null" | false
function dataType(v: any): DataType
// 获取 "字符串" 的类型

const type = dataType("字符串")

console.log(type) // "string"

基于 dataType 衍生出以下函数, 对值类型进行是否判断, 返回 boolean.

type func = (data:any): boolean

isString(data) // 是否为 String

isNumber(data) // 是否为 Number

isBoolean(data) // 是否为 Boolean

isFile(data) // 是否为 File

isBlob(data) // 是否为 Blob

isArray(data) // 是否为 Array

isFunction(data) // 是否为 Function

isDate(data) // 是否为 Date

isObject(data) // 是否为 Object

isUndefined(data) // 是否为 undefined

isNull(data) // 是否为 null

useDebounce

对传入的函数进行封装, 返回一个防抖函数.

默认防抖延迟 0ms, 但内部使用 setTimeout, 因此实际延迟受浏览器最小延迟执行栈执行时间影响.

function useDebounce(fn: Function, delay: number = 0): Function
const searchAjax = () => {
  fetch("/search?str=")
}

const search = useDebounce(searchAjax, 2000)

// search 是一个延迟 2s 执行的防抖函数, 2s 内重复触发只执行最后一次触发.

useThrottle

对传入的函数进行封装, 返回一个节流函数.

内部使用 async / await 关键字, 当传入函数执行完毕后一个流程才算结束.

function useThrottle(fn: Function, delay?: number): Function

不设限制延迟.

函数执行完毕后就可以重新触发.

const getListAjax = async () => {
  await fetch("/getList") // 假设需要 3s
}
// getList 执行后, 3s 后才能重新触发.
const getList = useThrottle(getListAjax, 2000)

设置固定延迟.

内部使用计时器, 函数执行完毕后, 等待setTimeout结束才能重新触发.

const getListAjax = async () => {
  await fetch("/getList") // 假设需要 3s
}
// getList 触发后, 3s + 2s 后才能再触发.
const getList = useThrottle(getListAjax, 2000)

deepClone

通过递归对数据进行深度克隆.

function deepClone<Type>(data: Type): Type
const arr = [1, 2, 3]
const data = { test: 1, arr: arr }
const newData = deepClone(data)

console.log(newData) // { test: 1, arr: [1, 2, 3] }
data === newData // false
data.arr === data.arr // false

uniqueArr

使用 new Arraynew Set 进行数组去重.

非数组则会返回原值.

function uniqueArray<Type>(arr: Type[]): Type[]
const arr = [1, 1, 3, 4, 1]

const newArr = uniqueArr(arr)

console.log(newArr) // [1, 3, 4]

treeToList

树结构转列表.

会在每项数据内插入一个值为父级 id 的键值对(键名默认 parent).

传参不是树或树组成的列表, 返回 false.

// 转换配置
interface TransformConfig {
  key: string
  parent: string
  children: string
  handler: <Type>(item: Type) => void
}

// 输出结果
type TransformResult = { value: object[]; pointers: object } | boolean

function treeToList(tree: any[] | object, config?: TransformConfig): TransformResult
// 树结构, 可以使用多个树结构组成的列表
const tree = {
  id: 1,
  children: [{ id: 2 }, { id: 3 }]
}

// 转换配置 // 以下为默认值
const transformConfig = {
  id: "id", // 唯一标识的字段名
  children: "children", // 子级的字段名
  parent: "parent", // 设置父级 id 的字段名
  handler: (item) => {} // 对每项数据进行二次加工的处理器
}

const { value, pointers } = treeToList(tree, transformConfig)

value
/* 转换后的列表
  [
    { id: 1, children: [<id: 2对象>, <id:3 对象>] },
    { id: 2, parent: 1 },
    { id: 3, parent: 1 }
  ]
*/

pointers
/* 使用唯一标识 id 作为 key 的 json 对象
  {
    "1": { id: 1, children: [] },
    "2": { id: 2, parent: 1 },
    "3": { id: 3, parent: 1 }
  }
*/

listToTree

列表转树结构.

传参不是列表返回 false.

// 转换配置
interface TransformConfig {
  key: string
  parent: string
  children: string
  handler: <Type>(item: Type) => void
}

// 输出结果
type TransformResult = { value: object[]; pointers: object } | boolean

function listToTree(list: any[], config?: TransformConfig): TransformResult
const list = [{ id: 1 }, { id: 2, parent: 1 }, { id: 3, parent: 1 }, { id: 4 }]

// 转换配置 // 以下为默认值
const transformConfig = {
  id: "id", // 唯一标识的字段名
  parent: "parent", // 指向父级唯一标识的字段名
  children: "children", // 设置子级的字段名
  handler: (item) => {} // 对每项数据进行二次加工的处理器
}

const { value, pointers } = listToTree(list, transformConfig)

value
/* 转换后的列表
  [
    { 
      id: 1, 
      children: [ { id: 2, parent: 1 }, { id: 3, parent: 1 } ]
    },
    { id: 4 }
  ]
*/

pointers
/* 使用唯一标识 id 作为 key 的 json 对象
  {
    "1": { id: 1, children: [<对象2>, <对象3>] },
    "2": { id: 2, parent: 1 },
    "3": { id: 3, parent: 1 }
    "4": { id: 4 }
  }
*/

useDate

时间解析工具.

将传入的时间参数按照指定的 format 格式进行解析.

| 格式 | 含义 | 格式 | 含义 | | :----: | :------------------ | :--: | :-------------------- | | YYYY | 年 | | | | MM | 月, 补 0 | M | 月, 不补 0 | | DD | 日, 补 0 | D | 日, 不补 0 | | HH | 时, 补 0, 24 小时制 | H | 时, 不补 0, 24 小时制 | | ss | 分, 补 0 | s | 分, 不补 0 | | mm | 秒, 补 0 | m | 秒, 不补 0 | | WW | 第几周, 补 0 | W | 第几周, 不补 0 |

WWW 表示的是一个时间范围, 因此必须且只能与 YYYY 一起使用.

type TimeType = Date | number | string
type ConvertedData = {
  time: TimeType
  format: string
}
interface DateItem {
  $Y: number // 年
  $M: number // 月
  $D: number // 日
  $H: number // 时
  $m: number // 分
  $s: number // 秒
  $W: number // 周
  timestamp: number // 毫秒数
  date: Date // 时间对象
}
type ParseResult = DateItem | DateItem[] | false
export function useDate(arg1?: ConvertedData): ParseResult
export function useDate(arg1?: TimeType, arg2?: string): ParseResult
export function useDate(arg1?: ConvertedData | TimeType, arg2?: string): ParseResult

默认参数 new Date()"YYYY-MM-DD HH:mm:ss".

// 假设当前时间为 2022-01-01 00:00:00

useDate()
// 相当于
useDate(new Date(), "YYYY-MM-DD HH:mm:ss")
// 相当于
useDate({ time: new Date(), format: "YYYY-MM-DD HH:mm:ss" })

/* 输出结果为
  {
    $Y: 2022
    $M: 0
    $D: 10
    $H: 0
    $m: 0
    $s: 0
    $W: 1
    timestamp: 1641744000000
    date: new Date(2022, 0, 10, 0, 0, 0)
    format: "2022-1-10 00:00:00" // 基于 format 拼接的字符串
  }
*/

使用 Date 对象进行解析.

const date = new Date(1641744000000)

useDate(date, "YYYY-MM-DD")

使用毫秒数进行解析.

useDate(1641744000000, "YYYY-MM-DD")

使用字符串配合格式化字符串进行解析.

字符串格式下, time 与 format 不匹配时返回 false

// 未配置解析的时间使用以下默认值
// YYYY、MM、DD 当前时间
// HH、mm、ss、ms 都是 0
useDate("2022-01-10", "YYYY-MM-DD")

// 解析错误返回 false
useDate("2022-10-10", "YYYY-MM") // false

周的字符串解析只能实现解析出第几周, 因此只能用 YYYYMM(M) 配合使用, 不能配合其他格式.

// 以当年 `第一个周一` 开始为 `第一周`
const [start, end] = useDate("2022 第 10 周", "YYYY 第 WW 周")

// start: 指向 2022-03-07 00:00:00 的 DateItem
// end: 指向 2022-03-13 23:59:59 的 DateItem

BlobToFile

Blob 转 File

// 参考 File 构造函数
function BlobToFile(
  blob: Blob, // blob 对象
  name: string, // 文件名
  options?: { type?: string; lastModified?: number }
): File

FileToBlob

File 转 Blob

// 参考 Blob 构造函数
function FileToBlob(
  file: File, // 文件对象
  options?: { type?: string; endings: "transparent" | "native" }
): Blob

BlobToBase64

Blob 转 base64

function BlobToBase64(blob: Blob): Promise<string>

Base64ToBlob

base64 转 Blob

function Base64ToBlob(base64: string): Blob

FileToBase64

File 转 base64

function FileToBase64(file: File): Promise<string>

Base64ToFile

base64 转 File

function Base64ToFile(base64: string, name: string): File

copyText

将文本复制到剪切板

function copyText(text: string): Promise<void>

样式库

// PC端引入
import "@imhjh/common/css/index.css"

// 移动端引入:去除移动端不适配的样式
import "@imhjh/common/css/index.mobile.css"

弹性布局相关

示例 .父级(--子级){0,3}.

可配合 0-3 个子级, 按 align-itemsjustify-contentflex-warp 的顺序拼接.

容器样式

  • 父级

    | 名称 | 对应属性 | | :--------- | :-------------------------------------- | | flex | display: flex | | flex-col | display: flex; flex-direction:column; |

  • align-items 子级

    | 名称 | 对应属性 | | :---- | :------------------------- | | a-s | align-items: flex-start; | | a-c | align-items: center; | | a-e | align-items: flex-end; | | a-b | align-items: baseline; |

  • justify-content 子级

    | 名称 | 对应属性 | | :----- | :-------------------------------- | | j-s | justify-content: flex-start; | | j-c | justify-content: center; | | j-e | justify-content: flex-end; | | j-sb | justify-content: space-between; | | j-sa | justify-content: space-around; | | j-se | justify-content: space-evenly; |

  • flex-grow 子级

    | 名称 | 对应属性 | | :----- | :----------------- | | wrap | flex-wrap: wrap; |

部分类名对应的属性

.flex {
  display: flex;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

.flex-col--wrap {
  display: flex;
  flex-direction: column;

  flex-wrap: wrap;
}

.flex-col--a-c--wrap {
  display: flex;
  flex-direction: column;

  align-items: center;

  flex-wrap: wrap;
}

.flex-col--a-c--j-c--wrap {
  display: flex;
  flex-direction: column;

  align-items: center;

  justify-content: center;

  flex-wrap: wrap;
}

项目样式

  • flex-grow

    .grow-0 ~ .grow-10 对应 flex-grow: 0; ~ flex-grow: 10;

  • flex-shrink

    .shrink-0 ~ .shrink-10 对应 flex-shrink: 0; ~ flex-shrink: 10;

尺寸样式

.w-0p ~ .w-1000p 对应 width: 0; ~ width: 1000px;

.h-0p ~ .h-1000p 对应 height: 0; ~ height: 1000px;

.w-0pct ~ .w-100pct 对应 width: 0%; ~ width: 100%;

.h-0pct ~ .h-100pct 对应 height: 0%; ~ height: 100%;

文本省略

.elli-1 ~ .elli-10: 仅保留 1-10, 其余行省略.

.elli-1-hover ~ .elli-10-hover: 移入时取消省略.