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

xl-toolbox

v1.0.1

Published

前端通用工具方法集合

Readme

xl-toolbox

前端通用工具方法集合,支持按需引入(tree-shaking),TypeScript 编写,提供完整的类型声明。

特性

  • 按需引入:支持 tree-shaking,仅打包使用到的方法
  • TypeScript:完整的类型声明,开发体验友好
  • 双格式输出:同时支持 ESM 和 CJS
  • 全面测试:154 个单元测试覆盖所有方法

安装

npm install xl-toolbox
# 或
pnpm add xl-toolbox
# 或
yarn add xl-toolbox

快速开始

// 按需引入(推荐,打包时仅包含使用到的方法)
import { deepClone, debounce, formatDate } from 'xl-toolbox';

const obj = deepClone({ a: { b: 1 } });
const fn = debounce(() => console.log('执行'), 300);
const date = formatDate(new Date(), 'YYYY-MM-DD');

API 文档

类型判断

提供 14 个类型判断方法,均返回布尔值,支持 TypeScript 类型守卫。

| 方法 | 说明 | 示例 | |------|------|------| | isObject(val) | 是否为非 null 对象 | isObject({}) // true | | isArray(val) | 是否为数组 | isArray([]) // true | | isString(val) | 是否为字符串 | isString('a') // true | | isNumber(val) | 是否为有效数字(排除 NaN) | isNumber(1) // true | | isBoolean(val) | 是否为布尔值 | isBoolean(true) // true | | isFunction(val) | 是否为函数 | isFunction(() => {}) // true | | isNull(val) | 是否为 null | isNull(null) // true | | isUndefined(val) | 是否为 undefined | isUndefined(undefined) // true | | isSymbol(val) | 是否为 Symbol | isSymbol(Symbol()) // true | | isBigInt(val) | 是否为 BigInt | isBigInt(1n) // true | | isDate(val) | 是否为 Date 对象 | isDate(new Date()) // true | | isRegExp(val) | 是否为 RegExp | isRegExp(/a/) // true | | isMap(val) | 是否为 Map | isMap(new Map()) // true | | isSet(val) | 是否为 Set | isSet(new Set()) // true |

import { isObject, isArray, isString } from 'xl-toolbox';

isObject({});     // true
isObject(null);   // false
isArray([1, 2]);   // true
isString('hello'); // true

deepClone - 深拷贝

支持对象、数组、Date、RegExp、Map、Set 的深拷贝,正确处理循环引用和 Symbol 属性。

function deepClone<T>(value: T, hash?: WeakMap<object, any>): T

参数

| 参数 | 类型 | 说明 | |------|------|------| | value | T | 待拷贝的值 | | hash | WeakMap | 内部递归使用,处理循环引用 |

示例

import { deepClone } from 'xl-toolbox';

// 基本类型直接返回
deepClone(42);        // 42
deepClone('hello');   // 'hello'

// 对象深拷贝
const obj = { a: 1, b: { c: 2 } };
const cloned = deepClone(obj);
cloned.b.c = 3;
console.log(obj.b.c); // 2(原对象不受影响)

// 处理循环引用
const cyclic: any = { a: 1 };
cyclic.self = cyclic;
deepClone(cyclic); // 正常拷贝,不栈溢出

// 支持特殊类型
deepClone(new Date());     // 新的 Date
deepClone(/abc/gi);       // 新的 RegExp
deepClone(new Map([['k', 'v']])); // 新的 Map
deepClone(new Set([1, 2]));       // 新的 Set

debounce - 防抖

连续调用时只在最后一次调用后的等待时间结束后执行一次,支持立即执行选项。

interface DebounceOptions {
  immediate?: boolean; // 是否在调用时立即执行
}

function debounce<T extends (...args: any[]) => any>(
  fn: T,
  wait: number,
  options?: DebounceOptions
): ((...args: Parameters<T>) => void) & { cancel: () => void }

示例

import { debounce } from 'xl-toolbox';

// 默认模式:延迟执行
const search = debounce((keyword: string) => {
  console.log('搜索:', keyword);
}, 300);
search('a');
search('ab');
search('abc');
// 300ms 后仅执行一次:搜索: abc

// 立即执行模式
const save = debounce(() => {
  console.log('保存');
}, 1000, { immediate: true });
save(); // 立即执行
save(); // 1000ms 内忽略,结束后可再次执行

// 取消防抖
const debounced = debounce(() => {}, 300);
debounced.cancel(); // 取消未执行的调用

throttle - 节流

在指定时间间隔内最多执行一次,支持首尾调用选项。

interface ThrottleOptions {
  leading?: boolean;  // 是否在间隔开始时执行(默认 true)
  trailing?: boolean; // 是否在间隔结束时执行最后一次调用(默认 true)
}

function throttle<T extends (...args: any[]) => any>(
  fn: T,
  wait: number,
  options?: ThrottleOptions
): ((...args: Parameters<T>) => void) & { cancel: () => void }

示例

import { throttle } from 'xl-toolbox';

// 默认模式:leading + trailing
const onScroll = throttle(() => {
  console.log('滚动事件');
}, 200);
window.addEventListener('scroll', onScroll);

// 仅 leading
const onClick = throttle(() => {
  console.log('点击');
}, 1000, { trailing: false });

// 仅 trailing
const onResize = throttle(() => {
  console.log('调整大小');
}, 200, { leading: false });

// 取消节流
const throttled = throttle(() => {}, 200);
throttled.cancel();

unique - 数组去重

支持基本类型去重和基于指定字段的对象数组去重。

function unique<T>(arr: T[], key?: string): T[]

示例

import { unique } from 'xl-toolbox';

// 基本类型去重
unique([1, 2, 2, 3, 3, 3]); // [1, 2, 3]
unique(['a', 'b', 'a']);     // ['a', 'b']

// 对象数组按字段去重
const users = [
  { id: 1, name: 'A' },
  { id: 2, name: 'B' },
  { id: 1, name: 'C' },
];
unique(users, 'id');
// [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]

deepMerge - 对象深合并

递归合并多个对象,嵌套对象递归合并,数组按索引合并,返回新对象不修改原对象。

function deepMerge(...sources: Record<string, any>[]): Record<string, any>

示例

import { deepMerge } from 'xl-toolbox';

// 嵌套对象合并
deepMerge(
  { a: { b: 1 } },
  { a: { c: 2 } }
);
// { a: { b: 1, c: 2 } }

// 多个对象合并
deepMerge(
  { x: 1 },
  { y: 2 },
  { z: 3 }
);
// { x: 1, y: 2, z: 3 }

// 数组按索引合并
deepMerge(
  { list: [{ a: 1 }, { b: 2 }] },
  { list: [{ c: 3 }] }
);
// { list: [{ a: 1, c: 3 }, { b: 2 }] }

// 后值覆盖前值
deepMerge(
  { name: 'A' },
  { name: 'B' }
);
// { name: 'B' }

formatDate - 日期格式化

支持 Date 对象、时间戳、日期字符串输入,使用占位符格式化。

占位符

| 占位符 | 说明 | |--------|------| | YYYY | 年 | | MM | 月(补零) | | DD | 日(补零) | | HH | 时(补零) | | mm | 分(补零) | | ss | 秒(补零) |

示例

import { formatDate } from 'xl-toolbox';

const date = new Date(2024, 0, 1, 8, 30, 5);

formatDate(date);                        // '2024-01-01 08:30:05'
formatDate(date, 'YYYY-MM-DD');          // '2024-01-01'
formatDate(date, 'YYYY/MM/DD HH:mm');    // '2024/01/01 08:30'
formatDate(date, 'YYYY年MM月DD日');      // '2024年01月01日'

// 时间戳
formatDate(1704067200000, 'YYYY-MM-DD'); // '2024-01-01'

// 日期字符串
formatDate('2024-06-15', 'YYYY/MM/DD');  // '2024/06/15'

// 无效日期
formatDate('invalid', 'YYYY-MM-DD');     // 'Invalid Date'

compareVersion - 版本比较

比较两个语义化版本号,支持 v 前缀和不同位数。

function compareVersion(v1: string, v2: string): number
// 返回:1 表示 v1 > v2,-1 表示 v1 < v2,0 表示相等

示例

import { compareVersion } from 'xl-toolbox';

compareVersion('1.0.0', '1.0.1');   // -1
compareVersion('1.0.0', '1.0.0');   // 0
compareVersion('2.0.0', '1.9.9');   // 1
compareVersion('v1.2.0', 'v1.1.0'); // 1
compareVersion('1.0.0', '1.0');     // 0(缺失位补 0)

createVersionChecker - 版本检测器

创建版本检测器实例,支持 ETag 模式和版本文件模式双模式检测,自动轮询、页面隐藏暂停。

type VersionCheckMode = 'etag' | 'version-file';

interface VersionCheckerOptions {
  mode?: VersionCheckMode;        // 检测模式,默认 'etag'
  url: string;                     // 检测 URL
  versionField?: string;           // 版本文件模式的字段路径,默认 'version',支持 'data.version'
  currentVersion?: string;         // 当前版本(版本文件模式使用)
  interval?: number;               // 轮询间隔(毫秒),默认 600000(10 分钟)
  autoStart?: boolean;              // 是否自动开始轮询,默认 true
  pauseOnHidden?: boolean;          // 页面隐藏时是否暂停,默认 true
  onUpdate?: (info: VersionInfo) => void;  // 检测到新版本时的回调
  onError?: (error: Error) => void;       // 检测错误的回调
  fetchOptions?: RequestInit;             // 自定义 fetch 请求配置
}

interface VersionInfo {
  current: string;    // 当前版本
  latest: string;     // 最新版本
  hasUpdate: boolean; // 是否有更新
  etag?: string | null; // ETag 值(ETag 模式)
}

interface VersionChecker {
  check(): Promise<VersionInfo>;  // 手动检测一次
  start(): void;                   // 开始轮询
  stop(): void;                    // 停止轮询
  getLastResult(): VersionInfo | null; // 获取上次检测结果
  destroy(): void;                 // 销毁实例,清理资源
}

function createVersionChecker(options: VersionCheckerOptions): VersionChecker

ETag 模式(默认)

通过 HTTP 响应头 ETag 变化检测版本更新,首次检测仅记录 ETag 不触发回调。

import { createVersionChecker } from 'xl-toolbox';

const checker = createVersionChecker({
  url: 'https://example.com/app.js',
  interval: 10 * 60 * 1000, // 每 10 分钟检测
  onUpdate: (info) => {
    console.log('检测到新版本', info);
    // 提示用户刷新页面
  },
  onError: (err) => {
    console.error('检测失败', err);
  },
});

// 手动检测
checker.check().then(info => {
  console.log(info.hasUpdate ? '有新版本' : '已是最新');
});

// 销毁
checker.destroy();

版本文件模式

通过请求 JSON 文件读取版本字段,与当前版本比较。

const checker = createVersionChecker({
  mode: 'version-file',
  url: 'https://example.com/version.json',
  currentVersion: '1.0.0',
  versionField: 'version', // 支持 'data.version' 嵌套路径
  onUpdate: (info) => {
    console.log(`新版本: ${info.current} -> ${info.latest}`);
  },
});

// version.json 示例: { "version": "1.1.0" }
// 或嵌套结构: { "data": { "version": "1.1.0" } }
// 配置 versionField: 'data.version'

页面隐藏暂停

默认开启,页面切换到后台时自动暂停轮询,返回前台时自动恢复。

const checker = createVersionChecker({
  url: 'https://example.com/app.js',
  pauseOnHidden: true,  // 默认 true,设为 false 可禁用
});

按需引入

xl-toolbox 配置了 sideEffects: false,支持 tree-shaking。使用打包工具(webpack、rollup、vite 等)时,仅引入的方法会被打包:

// 仅打包 deepClone 和 debounce,不包含其他方法
import { deepClone, debounce } from 'xl-toolbox';

开发

# 安装依赖
npm install

# 构建
npm run build

# 开发模式(监听文件变化)
npm run dev

# 运行测试
npm test

# 类型检查
npm run typecheck

# 代码检查
npm run lint

# 格式化代码
npm run format

技术栈

  • 语言:TypeScript 5.x
  • 构建:tsup 8.x(基于 esbuild)
  • 测试:Vitest 1.x
  • 规范:ESLint + Prettier

License

MIT