您当前位置:资讯中心 >开发 >浏览文章

fsx 简介:适用于 JavaScript 的现代文件系统 API

来源:不详 日期:2024/1/23 16:48:32 阅读量:(0)

JavaScript 运行时中的文件系统 API 已经很久没有这么好了,这是我试图做出一个更好的文件系统 API 的尝试。

我们今天拥有的 JavaScript API 比十年前要好得多。考虑一下从 XMLHttpRequest 到 fetch()的转变:开发者体验显著改善,允许我们编写更简洁、功能性更强的代码来完成同样的事情。异步编程的 promises 的引入允许了这种变化,以及一系列其他变化,使得 JavaScript 更容易编写。然而,有一个领域几乎没有创新:服务器端 JavaScript 运行时的文件系统 API。

Node.js:当今文件系统 API 的起源

Node.js 最初发布于 2009 年,随之诞生了 fs 模块。fs 模块是围绕 Linux 的核心实用程序构建的,其中的许多方法都反映了它们的 Linux 灵感,如 rmdir 、 mkdir 和 stat 。为此,Node.js 成功创建了一个低级文件系统 API,可以处理开发人员希望在命令行上完成的任何事情。不幸的是,这就是创新的终点。

Node.js 文件系统 API 最大的改变是引入了 fs/promises ,将整个实用程序从基于回调的方法移动到基于 promise 的方法。较小的增量变化包括实现 web 流和确保 reader 也实现了异步迭代器。该 API 仍然使用专有的 Buffer 类来读取二进制数据。(尽管 Buffer 现在是 Uint8Array 的子类,但仍然存在不兼容性,这使得使用 Buffers 有问题。)

即使是 Ryan Dhal 在 Node.js 上的继任者 Deno,也没有在文件系统 API 上做太多的改进,它基本上遵循了与 Node.js 中的 fs 模块相同的模式,尽管它使用了 Uint8Arrays,而 Node.js 使用了 Buffer s,并且在不同的地方使用了异步迭代器,但它仍然采用了与 Node.js 相同的低级 API 方法。

只有 Bun,作为服务器端 JavaScript 运行时生态系统的最新成员,甚至尝试使用 Bun.file() 来更新文件系统 API,这是受 fetch() 的启发。虽然我赞赏这种对如何使用文件的重新思考,但当你处理多个文件时,为每个想要处理的文件创建一个新对象可能会很麻烦(当处理数千个文件时,会有一个巨大的性能损失)。除此之外,Bun 希望你使用 Node.js fs 模块进行其他操作。

一个现代的文件系统 API 会是什么样子?

在花费数年时间在维护 ESLint 的同时与 Node.js fs 模块斗争之后,我问自己,一个现代的文件系统 API 会是什么样子?

  • 通常情况下会很简单。至少 80%的时间,我不是读取文件就是写入文件,或者检查文件是否存在,差不多就是这样,然而这些操作充满了危险,因为我需要检查各种东西以避免错误或记住额外的属性(例如 { encoding: "utf8" } )。
  • 错误将很少发生。我对 fs 模块最大的抱怨就是它抛出错误的频率。在不存在的文件上调用 fs.stat() 会抛出错误,这意味着你实际上需要将每个调用包装在 try-catch 中。为什么?对于大多数应用程序来说,缺少文件并不是不可恢复的错误。
  • 行动将是可观察的。在测试文件系统操作时,我真的只是想要一种方法来验证我期望发生的事情是否确实发生了。我不想与其他一些实用程序建立间谍网络,这些实用程序可能会也可能不会改变我正在观察的方法的实际行为。
  • 模拟很容易。我总是惊讶于模拟文件系统操作的难度。最后我只能使用 proxyquire 之类的东西,否则就需要设置迷宫般的模拟,花上一段时间才能弄好。对于文件系统操作来说,这是一个很常见的需求,竟然还没有解决方案。

带着这些想法,我开始设计 fsx。

FSX 基础知识

fsx库是我围绕现代高级文件系统 API 应该是什么样子的想法的结晶。在这一点上,它专注于支持最常见的文件系统操作,而把较少使用的操作(例如 chmod )抛在后面。(我并不是说这些操作在将来不会被添加,但对我来说,从最常见的情况开始,然后以与初始方法相同的谨慎方式构建更多的功能是很重要的。)

使用 fsx 运行时包

首先,fsx API 在三个运行时包中可用。这些包都包含相同的功能,但绑定到不同的底层 API。这些包是:

  • fsx-node - Node.js 中 fsx API 的绑定
  • fsx-deno - fsx API 的 Deno 绑定
  • fsx-memory - 适用于任何运行时(包括 web 浏览器)的内存实现

所以,开始时,你需要使用最适合你用例的运行时包。为了本文的目的,我将专注于 fsx-node ,但相同的 API 存在于所有运行时包中. 所有运行时包都导出一个 fsx 单例,你可以以类似于 fs的方式使用它。

import { fsx } from "node-fsx";
关键字:
声明:我公司网站部分信息和资讯来自于网络,若涉及版权相关问题请致电(63937922)或在线提交留言告知,我们会第一时间屏蔽删除。
有价值
0% (0)
无价值
0% (10)

分享转发:

发表评论请先登录后发表评论。愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。