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

dz-script

v0.0.8

Published

frontend tools

Readme

dz-utils

一个轻量级的前端工具库,提供常用的工具函数和实用功能。

npm version license

📦 安装

npm install dz-script

🚀 快速开始

ES6 模块导入

import { animate, delay, isObject, downloadFile } from 'dz-script';

// 使用动画函数
animate(0, 100, (value) => {
  console.log(value);
}, 1000);

// 延迟执行
await delay(2000);

// 类型检查
console.log(isObject({})); // true

// 文件下载
downloadFile('https://example.com/file.pdf', 'document.pdf');

浏览器直接使用

<script src="https://unpkg.com/dz-script/dist/dz-script.js"></script>
<script>
  // 通过全局变量 dzUtils 访问
  dzUtils.animate(0, 100, (value) => {
    console.log(value);
  }, 1000);
</script>

✨ 功能特性

🎨 动画 (Animations)

  • animate: 数字动画函数,支持自定义缓动效果

⏰ 通用工具 (Common)

  • delay: 异步延迟函数
  • deepMerge: 深度合并对象
  • downloadFile: 文件下载工具
  • formatStringToJson: 字符串转JSON
  • serialize: 对象序列化为查询字符串
  • groupBy: 数组分组函数

🔍 类型检查 (Type Checking)

  • isUndefined: 检查是否为 undefined
  • isNull: 检查是否为 null
  • isObject: 检查是否为对象
  • isFunction: 检查是否为函数
  • isArray: 检查是否为数组
  • isEmpty: 检查是否为空值
  • isString: 检查是否为字符串
  • isEmptyArray: 检查是否为空数组
  • isEmptyObject: 检查是否为空对象
  • isNullOrUnDef: 检查是否为 null 或 undefined

📱 正则表达式 (RegExp)

  • REGEXP_PHONE: 手机号码正则
  • REGEXP_EMAIL: 邮箱正则
  • REGEXP_PWD: 密码正则(8-18位数字/字符/符号组合)
  • REGEXP_CODE_SIX: 6位数字验证码正则
  • REGEXP_CODE_FOUR: 4位数字验证码正则
  • REGEXP_URL: URL链接正则
  • REGEXP_IPV4: IPv4地址正则
  • REFEXP_IPV6: IPv6地址正则

💾 存储管理 (Storage)

  • LocalStorage: 本地存储操作
    • setLocal: 设置本地存储
    • getLocal: 获取本地存储
    • removeLocal: 删除本地存储
    • clearLocal: 清空本地存储
  • SessionStorage: 会话存储操作
    • setSession: 设置会话存储
    • getSession: 获取会话存储
    • removeSession: 删除会话存储
    • clearSession: 清空会话存储

📤 文件上传 (Upload)

  • useUploadFile: 文件上传Hook
  • appendData: 组装FormData数据

🔄 自动重载 (Auto Reload)

  • updateWorkerjs: 基于Web Worker的页面自动重载功能

🏷️ HTML处理 (HTML)

  • htmlTransform: HTML字符串转对象结构

📖 API 文档

animate(from, to, callback, duration)

数字动画函数,使用 requestAnimationFrame 实现平滑动画。

import { animate } from 'dz-script';

// 从0到100的动画,持续1秒
animate(0, 100, (value) => {
  element.style.width = value + 'px';
}, 1000);

参数:

  • from (number): 起始值
  • to (number): 结束值
  • callback (function): 回调函数,接收当前动画值
  • duration (number): 动画持续时间(毫秒)

delay(time)

异步延迟函数。

import { delay } from 'dz-script';

// 延迟2秒
await delay(2000);
console.log('2秒后执行');

deepMerge(src, target)

深度合并对象。

import { deepMerge } from 'dz-script';

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 3 }, e: 4 };
const result = deepMerge(obj1, obj2);
// 结果: { a: 1, b: { c: 2, d: 3 }, e: 4 }

downloadFile(url, fileName)

文件下载工具。

import { downloadFile } from 'dz-script';

downloadFile('https://example.com/file.pdf', 'document.pdf');

serialize(params)

将对象序列化为查询字符串。

import { serialize } from 'dz-script';

const params = { name: 'John', age: 30 };
const queryString = serialize(params);
// 结果: "name=John&age=30"

groupBy(arr, generateKey)

数组分组函数。

import { groupBy } from 'dz-script';

const users = [
  { name: 'John', age: 25 },
  { name: 'Jane', age: 25 },
  { name: 'Bob', age: 30 }
];

// 按年龄分组
const grouped = groupBy(users, 'age');
// 结果: { 25: [{ name: 'John', age: 25 }, { name: 'Jane', age: 25 }], 30: [{ name: 'Bob', age: 30 }] }

// 按自定义函数分组
const groupedByLength = groupBy(users, (user) => user.name.length);

存储操作

import { setLocal, getLocal, removeLocal, clearLocal } from 'dz-script';
import { setSession, getSession, removeSession, clearSession } from 'dz-script';

// LocalStorage 操作
setLocal('user', { name: 'John' });
const user = getLocal('user');
removeLocal('user');
clearLocal();

// SessionStorage 操作
setSession('token', 'abc123');
const token = getSession('token');
removeSession('token');
clearSession();

useUploadFile(executeUpload, onError)

文件上传Hook。

import { useUploadFile } from 'dz-script';

const { uploadFun, clear } = useUploadFile(
  (file) => {
    console.log('选择的文件:', file);
    // 处理文件上传逻辑
  },
  (error) => {
    console.error('上传错误:', error);
  }
);

// 触发文件选择
uploadFun();

// 清理上传元素
clear();

updateWorkerjs(options)

页面自动重载功能,基于Web Worker实现,用于检测页面资源更新并自动重载。

实现原理

  1. HTML解析: 使用自定义的HTML解析器将页面HTML转换为对象结构
  2. 脚本检测: 递归查找页面中的script标签,获取其src属性作为版本标识
  3. Web Worker: 在后台线程中定期检查页面资源是否更新
  4. 事件机制: 通过事件系统通知主线程进行页面重载

核心流程

import { updateWorkerjs } from 'dz-script';

const worker = new updateWorkerjs({
  pollingTime: 15, // 轮询间隔(秒)
  path: window.location.origin, // 页面路径
  scriptUrl: 'https://example.com/reload.js' // Worker脚本地址
});

worker.on('update', () => {
  console.log('检测到更新,准备重载页面');
  location.reload();
});

worker.on('close', () => {
  console.log('Worker已关闭');
});

// 关闭Worker
worker.close();

参数说明

  • pollingTime (number): 轮询间隔时间,默认15秒
  • path (string): 要监控的页面路径,默认为当前页面
  • scriptUrl (string): Worker脚本地址,默认为远程地址

工作原理详解

  1. 初始化阶段:

    • 获取当前页面的HTML内容
    • 解析HTML结构,提取script标签的src属性
    • 创建Web Worker实例
  2. 监控阶段:

    • Worker线程定期请求页面HTML
    • 比较新旧script标签的src属性
    • 如果发现变化,发送update消息
  3. 更新阶段:

    • 主线程接收update事件
    • 触发页面重载
    • 清理Worker资源

技术实现细节

核心组件

updateWorkerjs 类:

class updateWorkerjs {
  pollingTime: number;        // 轮询间隔时间
  private myWork: any;        // Web Worker实例
  path: string;               // 监控的页面路径
  private eventMap: any;      // 事件映射表
  scriptUrl: string;          // Worker脚本地址
}

HTML解析器:

export type htmlObjType = {
  nodeName: string;
  text?: string;
  src?: string;
  children: htmlObjType[];
};
实现流程

第一阶段:初始化

async createWorkerjs() {
  // 1. 获取当前页面HTML
  const htmlObj = await this._getHtmlObj();
  
  // 2. 提取script标签的src作为版本标识
  const currentHash = this._getCurrentHash(htmlObj);
  
  // 3. 创建Web Worker
  if (window.Worker) {
    const workjsTemplate = await this._getScript();
    const localWorkerUrl = window.URL.createObjectURL(
      new Blob([workjsTemplate], {
        type: 'application/javascript',
      })
    );
    this.myWork = new Worker(localWorkerUrl);
    
    // 4. 向Worker发送初始配置
    this.myWork.postMessage({
      pollingTime: this.pollingTime,
      location: this.path || window.location.origin,
      currentHash,
    });
  }
}

第二阶段:HTML获取与解析

async _getHtmlObj(): Promise<htmlObjType> {
  const res = await fetch(window.location.origin, {
    method: 'GET',
  });
  const data = await res.text();
  return htmlTransform(data);
}

第三阶段:版本标识提取

_getCurrentHash(htmlObj: htmlObjType): string {
  for (const child of htmlObj.children) {
    if (child?.nodeName === 'script' && child?.src) {
      return child.src;  // 返回第一个script标签的src
    }
    
    // 递归查找子节点
    const result = this._getCurrentHash(child);
    if (result !== null) {
      return result;
    }
  }
  return null;
}

第四阶段:事件处理

this.myWork.onmessage = async (e: any) => {
  const message = e.data;
  if (message === 'update') {
    this.emit('update');  // 触发更新事件
    this.close();         // 关闭Worker
  } else if (message === 'cancel') {
    this._error('do not find a script tag');
    this.close();
  }
};
事件系统

事件类型:

  • update: 检测到更新时触发
  • close: Worker关闭时触发

事件注册:

on(event: string, handler: (e: any) => void) {
  this.eventMap.get(event).add(handler);
}

事件触发:

emit(event: string) {
  this.eventMap.get(event).forEach((handler: Function) => {
    handler(this, this);
  });
}

使用场景

  • 开发环境: 代码修改后自动刷新浏览器
  • 生产环境: 检测静态资源更新
  • CDN更新: 监控CDN资源变化

技术特点

优势:

  1. 非阻塞: 使用Web Worker,不阻塞主线程
  2. 精确检测: 基于script标签src变化,准确度高
  3. 可配置: 支持自定义轮询间隔和监控路径
  4. 事件驱动: 基于事件系统,易于扩展

限制:

  1. 浏览器兼容性: 需要支持Web Worker
  2. 依赖script标签: 需要页面包含script标签
  3. 网络依赖: 需要能够访问监控的页面

注意事项

  • 需要浏览器支持Web Worker
  • 依赖script标签的src属性作为版本标识
  • 建议在生产环境中谨慎使用
  • 轮询间隔建议根据实际需求设置,避免过于频繁的请求

🛠️ 开发

安装依赖

npm install

构建

# 构建库文件
npm run build

# 监听模式构建
npm run watch:bundle
npm run watch:lib

测试

npm test

代码检查

npm run lint

📄 许可证

MIT License - 查看 LICENSE 文件了解详情。

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📞 联系方式