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

fs-async

v1.2.1

Published

Lightweight asynchronous file operation utility for Node.js with zero dependencies

Readme

fs-async

轻量级异步文件操作工具,基于 Node.js 原生 fs/promises 实现,无第三方依赖,支持文件读写、目录管理、路径匹配等核心场景,提供清晰的 TypeScript 类型提示,简化日常异步文件处理流程。

特性

  • 🚀 纯异步非阻塞:基于 fs/promises 开发,避免阻塞事件循环,适配 Node.js 异步生态
  • 📦 零额外依赖:移除 glob 等第三方库,仅依赖 Node.js 原生 API,减少项目体积
  • 🔧 核心功能全覆盖:文件读写、JSON 处理、目录管理、路径匹配、哈希计算等常用操作
  • TypeScript 原生支持:完整类型定义,支持 IDE 自动补全和类型校验,减少运行时错误
  • 🖥️ 跨平台兼容:统一处理 Windows/macOS/Linux 路径分隔符,避免跨平台路径问题

安装

# 安装核心包
npm install fs-async --save

# 低版本 Node.js(<16)如需 TypeScript 类型支持,需手动安装 @types/node
npm install @types/node --save-dev

快速开始

基础示例(ES Module)

// 导入工具(默认导出为 fs 对象,与原生 fs 命名习惯一致)
import fs from 'fs-async';

async function fileOpsDemo() {
  try {
    // 1. 写入文件(自动创建不存在的父目录)
    await fs.write('./data/log.txt', '2024-01-01: 系统启动成功');

    // 2. 读取文件(默认编码 utf-8)
    const logContent = await fs.read('./data/log.txt');
    console.log('日志内容:', logContent); // 输出:2024-01-01: 系统启动成功

    // 3. 写入 JSON 文件(自动格式化,缩进 2 空格)
    await fs.writeJSON('./data/config.json', { 
      theme: 'dark', 
      timeout: 3000 
    });

    // 4. 读取 JSON 文件(自动解析)
    const config = await fs.readJSON('./data/config.json');
    console.log('配置主题:', config.theme); // 输出:dark

    // 5. 复制目录(强制覆盖已存在的目标目录)
    await fs.copy('./data', './data-backup', { force: true });

    // 6. 路径匹配(查找所有 .json 文件)
    const jsonFiles = await fs.expand('**/*.json', { onlyFiles: true });
    console.log('JSON 文件列表:', jsonFiles); // 输出:[ 'data/config.json', 'data-backup/config.json' ]

  } catch (err: any) {
    console.error('文件操作失败:', err.message);
  }
}

fileOpsDemo();

CommonJS 示例

// 导入工具
const fs = require('fs-async');

async function dirOpsDemo() {
  try {
    // 创建嵌套目录
    await fs.mkdir('./temp/docs');

    // 检查路径是否为目录
    const isDir = await fs.isDir('./temp/docs');
    console.log('./temp/docs 是否为目录:', isDir); // 输出:true

    // 清空目录(保留目录本身,删除内容)
    await fs.emptyDir('./temp/docs');

    // 删除目录(递归删除整个目录)
    await fs.remove('./temp');

  } catch (err) {
    console.error('目录操作失败:', err.message);
  }
}

dirOpsDemo();

API 文档

所有方法均返回 Promise,支持 async/await 调用,以下是核心 API 说明:

1. 文件操作

| 方法 | 说明 | 参数 | 返回值 | |------|------|------|--------| | fs.write(file, content, [options]) | 写入文件(自动创建父目录) | file: 目标文件路径content: 写入内容(string/Buffer)options: 可选,fs.WriteFileOptions(含 encoding/flag 等) | Promise<void> | | fs.read(file, [options]) | 读取文件 | file: 文件路径options: 可选,含 encoding(默认 utf-8)/flag | Promise<string | Buffer> | | fs.readJSON<T>(file, [options]) | 读取 JSON 文件并解析 | file: JSON 文件路径options: 可选,同 fs.readoptions | Promise<T>(解析后的 JSON 对象) | | fs.writeJSON(file, data, [spaces]) | 写入 JSON 文件(自动格式化) | file: 目标文件路径data: 要序列化的 JSON 数据spaces: 可选,缩进空格数(默认 2) | Promise<void> | | fs.appendFile(file, content, [options]) | 向文件追加内容 | 参数同 fs.write | Promise<void> | | fs.copy(from, to, [options]) | 复制文件/目录 | from: 源路径to: 目标路径options: 可选,{ force?: boolean; preserveTimestamps?: boolean }force 强制覆盖,默认 false;preserveTimestamps 保留时间戳,默认 false) | Promise<void> | | fs.move(from, to, [options]) | 移动/重命名文件/目录(跨设备自动降级为复制+删除) | from: 源路径to: 目标路径options: 可选,{ force?: boolean }(强制覆盖,默认 false) | Promise<void> | | fs.remove(path) | 删除文件/目录(递归删除,等同于 rm -rf) | path: 要删除的路径 | Promise<void> | | fs.hashFile(file, [algorithm]) | 计算文件哈希值 | file: 文件路径algorithm: 可选,哈希算法(默认 sha256,支持 md5/sha1 等) | Promise<string>(十六进制哈希字符串) |

2. 目录操作

| 方法 | 说明 | 参数 | 返回值 | |------|------|------|--------| | fs.mkdir(dirPath) | 创建目录(递归创建,等同于 mkdir -p) | dirPath: 目标目录路径 | Promise<void> | | fs.readDir(dir, [options]) | 读取目录内容 | dir: 目录路径options: 可选,{ withFileTypes?: boolean }withFileTypes 为 true 时返回 fs.Dirent 对象数组,否则返回文件名数组) | Promise<string[] | fs.Dirent[]> | | fs.emptyDir(dir) | 清空目录(保留目录本身,删除所有子内容) | dir: 目录路径 | Promise<void> | | fs.isDir(path) | 判断路径是否为目录 | path: 路径 | Promise<boolean> | | fs.isFile(path) | 判断路径是否为文件 | path: 路径 | Promise<boolean> | | fs.exists(...paths) | 判断路径是否存在(支持多参数拼接路径,如 fs.exists('src', 'utils', 'file.ts')) | paths: 路径片段(可多个) | Promise<boolean> |

3. 路径工具

| 方法 | 说明 | 参数 | 返回值 | |------|------|------|--------| | fs.expand(patterns, [options]) | 路径匹配(支持 */** 模式,替代 glob) | patterns: 匹配模式(string 或 string 数组,如 '**/*.ts'options: 可选,{ cwd?: string; dot?: boolean; onlyFiles?: boolean; onlyDirs?: boolean }cwd 工作目录,默认当前目录;dot 匹配隐藏文件,默认 false;onlyFiles/onlyDirs 仅匹配文件/目录) | Promise<string[]>(匹配的路径数组) | | fs.isPathAbsolute(path) | 判断路径是否为绝对路径 | path: 路径 | Promise<boolean> | | fs.doesPathContain(ancestor, ...paths) | 判断祖先路径是否包含所有子路径 | ancestor: 祖先路径paths: 子路径(可多个) | Promise<boolean> | | fs.createSymlink(target, linkPath, [options]) | 创建符号链接 | target: 链接指向的目标路径linkPath: 链接文件路径options: 可选,{ type?: 'file' | 'dir' | 'junction' }(链接类型,默认 file) | Promise<void> | | fs.realpath(path) | 获取符号链接指向的真实路径 | path: 符号链接路径 | Promise<string> |

错误处理

所有方法抛出的错误均包含清晰的描述信息,可通过 try/catch 捕获并处理:

try {
  await fs.read('./nonexistent.txt');
} catch (err: any) {
  console.error('错误类型:', err.name); // 输出:Error
  console.error('错误信息:', err.message); // 输出:文件不存在:./nonexistent.txt
}

常见错误场景:

  • 路径不存在:文件不存在:xxx/目录不存在:xxx
  • 路径已存在:目标已存在(设 force: true 覆盖):xxx
  • 类型不匹配:路径是目录:xxx/路径是文件:xxx

注意事项

  1. fs.remove 风险提示fs.remove 等同于 rm -rf,会递归删除目录所有内容,请谨慎使用,避免误删重要文件。
  2. 跨设备移动fs.move 在跨设备(如 C 盘到 D 盘)时会自动降级为“复制+删除”,确保操作成功。
  3. 路径匹配能力fs.expand 支持基础的 *(匹配单层任意字符)和 **(匹配多层目录)模式,复杂场景可自行扩展。

版本兼容

  • 支持 Node.js 14+(推荐 Node.js 16+,原生支持完整的 fs/promises API)
  • TypeScript 4.5+(如需类型校验)