国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

fsx 簡介:適用于 JavaScript 的現代文件系統 API

開發 前端
JavaScript 運行時中的文件系統 API 已經很久沒有這么好了,這是我試圖做出一個更好的文件系統 API 的嘗試。

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";

使用 fsx 讀取文件

文件是通過使用返回特定數據類型的方法來讀取的:

  • fsx.text(filePath) 讀取給定的文件并返回一個字符串。
  • fsx.json(filePath) 讀取給定的文件并返回一個 JSON 值。
  • fsx.arrayBuffer(filePath) 讀取給定的文件并返回一個 ArrayBuffer 。

這里有一些例子:

// read plain text
const text = await fsx.text("/path/to/file.txt");

// read JSON
const json = await fsx.json("/path/to/file.json");

// read bytes
const bytes = await fsx.arrayBuffer("/path/to/file.png");

如果文件不存在,每個方法都會返回 undefined 而不是拋出錯誤。這意味著您可以使用 if 語句而不是 try-catch,并且可以選擇使用 nullish 合并運算符來指定默認值,如下所示:

// read plain text
const text = (await fsx.text("/path/to/file.txt")) ?? "default value";

// read JSON
const json = (await fsx.json("/path/to/file.json")) ?? {};

// read bytes
const bytes =
  (await fsx.arrayBuffer("/path/to/file.png")) ?? new ArrayBuffer(16);

我覺得這種方法在 2024 年比不斷擔心不存在的文件出錯更有 JavaScript 風格。

使用 fsx 寫文件

要寫文件,調用 fsx.write() 方法。這個方法接受兩個參數:

  • filePath:string - 寫入的路徑
  • value:string|ArrayBuffer - 寫入文件的值

這里有一個例子:

// write a string
await fsx.write("/path/to/file.txt", "Hello world!");

const bytes = new TextEncoder().encode("Hello world!").buffer;

// write a buffer
await fsx.write("/path/to/file.txt", buffer);

作為額外的好處,fsx.write() 將自動創建任何尚不存在的目錄。這是我經常遇到的另一個問題,我認為它應該在現代文件系統 API 中“正常工作”。

使用 fsx 檢測文件

要確定一個文件是否存在,使用 fsx.isFile(filePath) 方法,如果給定的文件存在,則返回 true ,否則返回 false 。

if (await fsx.isFile("/path/to/file.txt")) {
  // handle the file
}

與 fs.stat() 不同,如果文件不存在,這個方法會返回 false ,而不是拋出錯誤。

try {
  const stat = await fs.stat(filePath);
  return stat.isFile();
} catch (ex) {
  if (ex.code === "ENOENT") {
    return false;
  }

  throw ex;
}

刪除文件和目錄

fsx.delete() 方法接受一個參數,即要刪除的路徑,并且對文件和目錄都有效。

// delete a file
await fsx.delete("/path/to/file.txt");

// delete a directory
await fsx.delete("/path/to");

fsx.delete() 方法故意過于激進:它會遞歸地刪除目錄,即使它們不是空的(實際上是 rmdir -r)。

fsx 日志

fsx 的一個關鍵特性是,由于其內置的日志系統,很容易確定哪些方法被調用,并使用了哪些參數。要啟用 fsx 實例的日志記錄,請調用 logStart() 方法并傳入一個日志名稱。當你完成日志記錄時,請調用 logEnd() 并傳入相同的名稱來檢索日志條目的數組。

fsx.logStart("test1");

const fileFound = await fsx.isFile("/path/to/file.txt");

const logs = fsx.logEnd("test1");

每個日志條目都是一個包含以下屬性的對象:

  • timestamp - 創建日志的數字時間戳
  • type - 描述日志類型的字符串
  • data - 與日志相關的附加數據

對于方法調用,日志條目的 type 是 call ,而 data 屬性是一個對象,包含:

  • methodName - 被調用的方法的名稱
  • args - 傳遞給方法的參數數組。

對于前面的例子, logs 將包含一個條目:

// example log entry

{
    timestamp: 123456789,
    type: "call",
    data: {
        methodName: "isFile",
        args: ["/path/to/file.txt"]
    }
}

了解這一點后,您可以輕松地在測試中設置日志記錄,然后檢查調用了哪些方法,而無需使用第三方間諜庫。

使用 fsx impls

fsx 的設計是這樣的,抽象的核心功能包含在 fsx-core 包中,每個運行時包都擴展了該功能,使用特定于運行時的文件系統操作實現,這些操作被包裝在一個稱為 impl 的對象中。

  1. fsx 單例
  2. 一個構造函數,可以創建 fsx 的另一個實例(比如 fsx-node 中的 NodeFsx )
  3. 一個構造函數,可以創建運行時包的 impl 實例(如 node-fsx 中的 NodeFsxImpl )。

這可以讓您只使用所需的功能。

fsx 中的 base impls 和 active impls

每個 fsx 實例都有一個 base 類實現,它定義了 fsx 對象在生產環境中的行為。active impls 是在任何給定時間使用的實現,它可能也是 base 類實現,也可能不是。你可以調用 fsx.setImpl()來改變 active impls。

import { fsx } from "fsx-node";

fsx.setImpl({
  json() {
    throw Error("This operation is not supported");
  },
});

// somewhere else

await fsx.json("/path/to/file.json"); // throws error

在此示例中,基本實現被替換為自定義實現,該自定義實現在調用 fsx.json() 方法時會引發錯誤。這使得您可以輕松地模擬測試方法,而不必擔心它可能如何影響整個包含的 fsx 對象。

交換 impls 進行測試

假設你有一個名為 readConfigFile() 的函數,它使用了來自 node-fsx 的 fsx 單例來讀取名為 config.json 的文件,當測試這個函數時,你不想讓它實際訪問文件系統,你可以把 fsx 的實現換成 fsx-memory 提供的內存文件系統實現,如下:

import { fsx } from "fsx-node";
import { MemoryFsxImpl } from "fsx-memory";
import { readConfigFile } from "../src/example.js";
import assert from "node:assert";

describe("readConfigFile()", () => {

    beforeEach(() => {
        fsx.setImpl(new MemoryFsxImpl());
    });

    afterEach(() => {
        fsx.resetImpl();
    });

    it("should read config file", async () => {

        await fsx.write("config.json", JSON.stringify({ found: true });

        const result = await readConfigFile();

        assert.isTrue(result.found);
    });

});

這就是使用 fsx 在內存中模擬整個文件系統是多么容易。您不必像模塊加載器攔截那樣擔心導入所有測試模塊的順序,也不需要經歷包含模擬庫的過程以確保一切正常。您只需更換測試的 impl,然后再重置它。通過這種方式,您可以以更高性能且不易出錯的方式測試文件系統操作。

命名注意事項

不幸的是,在我發布 fsx 的時候,亞馬遜發布了一款名為 FSx[2] 的產品。如果它獲得任何支持,我可能會重命名這個庫,歡迎提出建議。

希望得到結論和反饋

長期以來,我們一直在使用 JavaScript 運行時中笨拙的低級文件系統 API。fsx 庫是我嘗試重新想象現代文件系統 API 的樣子,如果我們花一些時間關注最常見的情況,并改進 JavaScript 語言目前提供的人體工學設計。通過從頭開始重新思考,我認為 fsx 為我們提供了一種更愉快的文件系統體驗。

基礎庫只關注我最常用的方法,但我計劃在了解和思考用例后添加更多方法。您今天就可以試用,歡迎反饋。我很想知道你的想法!

責任編輯:華軒 來源: 獨立開發者張張
相關推薦

2021-03-18 10:46:00

Linux監控工具命令

2018-10-24 10:43:13

2022-03-14 08:00:00

KoolKits工具開發

2009-11-29 17:10:01

NetgearLinux系統路由器

2010-04-30 15:51:48

Unix系統

2011-12-08 09:43:56

虛擬化vmwareVMware Fusi

2023-11-30 08:55:15

LinuxLibreOffic

2022-11-17 10:45:46

Linux文件備份系統

2022-09-02 17:47:46

Linux筆記應用

2020-05-14 17:54:54

查看器 Linux 系統

2019-08-15 15:48:30

Linux系統軟件

2012-09-12 14:40:19

Lustre文件系統

2020-10-10 09:19:58

JavaScript開發技術

2018-01-09 11:09:42

RESTSOAP開源

2023-03-08 12:35:59

綜合布線

2019-08-23 11:00:00

云計算網絡安全

2013-02-21 10:13:25

2021-12-13 12:56:26

Linux瀏覽器

2011-05-13 09:56:23

Ubuntu 11.0

2021-11-03 10:14:31

PowerEdge
點贊
收藏

51CTO技術棧公眾號

久久久国产成人精品| 久久精品日韩一区二区三区| 国产剧情一区二区| 操日韩av在线电影| 日韩在线电影一区| av网站在线播放| 欧美日韩水蜜桃| 欧美一卡二卡在线| 内衣办公室在线| 亚洲高清三级视频| 美女胸又www又黄的网站| 中文天堂在线一区| 国产经典av| 一区二区三区.www| 天天干夜夜干| 午夜精品免费在线观看| 激情视频在线观看免费| 欧美一级欧美一级在线播放| heyzo中文字幕在线| 精品久久久av| 黄色小视频大全| 亚洲成av人片www| 黄色成人在线网站| 97人人做人人爱| 日韩一区国产在线观看| 欧美日本三级| 欧美性xxxxx极品娇小| 三级理论午夜在线观看| 欧美精品xxxxbbbb| 日本美女久久| 亚洲一区电影777| 性欧美xxxx大乳国产app| 欧美一区二区三区在线免费观看 | 日韩电影免费在线看| 国产激情久久久| 欧美aaaaa级| 欧美日韩在线影院| 亚洲一区二区三区精品在线观看| 欧美一级本道电影免费专区| 久热在线中文字幕色999舞| 97成人在线| 国产 高清 精品 在线 a| 成人99免费视频| www 日韩| 国产精品视频专区| 不卡影院免费观看| 国产区在线观看| 国产精品扒开腿做爽爽爽男男 | 日韩在线免费| 四虎免费在线观看视频| 999日本视频| 亚洲国产一区二区三区a毛片| 欧美日韩亚洲精品一区二区三区| a级网站在线观看| 中文字幕亚洲区| 超级碰碰久久| 欧美日韩在线精品一区二区三区| 亚洲综合激情另类小说区| 成人香蕉社区| 污污视频网站免费观看| 色阁综合伊人av| 夫妻av一区二区| 91超碰在线播放| 亚洲精品日韩在线观看| 欧美一卡在线观看| 三级不卡在线观看| 国产精品久久久久久久久婷婷| 国产66精品久久久久999小说 | 91亚洲精品视频| 国产成人精品在线视频| 国内精品一区二区| 久久亚洲道色| 日韩无套无码精品| 国内免费久久久久久久久久久| 国产色婷婷亚洲99精品小说| 未满十八勿进黄网站一区不卡| 国产一级片黄色| 成人精品福利视频| 欧美午夜精品电影| 国产成人亚洲综合a∨猫咪| 99热这里只有精品首页 | 国产日韩欧美一区在线| 国产成人精品视频在线| 国产精品久久久久久久app| 国产一区二区三区在线观看视频 | 正在播放一区二区三区| 国产乱淫av一区二区三区| 黄网站app在线观看下载视频大全官网| 国产一区二区三区日韩欧美| 国产精品66部| 一区二区美女| av电影免费在线看| 日本a级片免费| 青青草原亚洲| 欧美在线视频免费| 亚洲精品98久久久久久中文字幕| 欧美激情综合五月色丁香小说| 成人羞羞视频在线看网址| caoprom在线| 伊人中文字幕在线| 青青草原成人网| 免费在线观看一区二区| 91成人免费观看| 九色综合狠狠综合久久| 亚洲小说欧美另类激情| 欧美人与物videos另类| 国产专区精品| 91精品美女在线| 精品国产乱码久久久久久浪潮| 亚洲精品亚洲人成人网在线播放| 麻豆精品视频在线观看| 欧美一区影院| 国产精品一区二区av日韩在线 | 色婷婷国产精品久久包臀 | 9999热视频在线观看| 亚州av电影免费在线观看| 国产免费又粗又猛又爽| 一区二区三区我不卡| 亚洲乱码国产乱码精品精98午夜 | 国产精品免费视频观看| 黄色免费网站在线观看| 国产精品污www一区二区三区| 亚洲成人性视频| 亚洲综合精品自拍| 成人一区二区视频| 成人激情黄色小说| 日欧美一区二区| 精油按摩中文字幕久久| 精品一区二区久久| k8久久久一区二区三区| 91社区在线播放| 国产亚洲一区二区三区在线观看| 9色porny自拍视频一区二区| 最新国产の精品合集bt伙计| 国产精品午夜春色av| 亚洲国产精品一区二区www| 欧美性猛交xxxx富婆弯腰| 69堂国产成人免费视频| av网站一区二区三区| 高清欧美精品xxxxx| 日韩三级在线| 91精品啪在线观看国产60岁| 精品视频在线免费观看| 羞羞视频在线观看欧美| 欧美久久天堂| 免费网站在线观看视频| 日韩一区二区三区久久| jizz在线观看视频| 国产成人精品123区免费视频| 97国产精品| 国产999精品久久久久久绿帽| 国产欧美一区二区三区在线看蜜臀| 亚洲国产欧美一区二区三区丁香婷| 日韩欧美久久久| 欧美一级视频在线观看| 欧美日韩一区综合| 2018av男人天堂| 牛牛精品一区二区| 欧美成人自拍| 国产欧美日韩视频一区二区 | 国产精品免费aⅴ片在线观看| 国产精品电影观看| 美女精品视频一区| 日韩丝袜美女视频| 成人动漫精品一区二区| 国产精品啊啊啊| 我不卡神马影院| 日韩精品免费专区| 国产91精品在线观看| 亚洲狠狠爱一区二区三区| 播播国产欧美激情| 一区二区不卡在线观看| 亚洲有码转帖| 国内自拍欧美| 国产日韩欧美在线一区| 中文字幕日本精品| 久久男人资源站| 国内精彩免费自拍视频在线观看网址| 亚洲美女黄色| 欧美一区二区三区的| 欧美高清一区二区| 成人日批视频| 蜜桃av噜噜一区| 亚洲欧美日韩国产中文| 黄黄视频在线观看| 亚洲一卡二卡| 成人欧美一区二区三区在线湿哒哒| 日韩国产精品久久| 日韩大尺度黄色| 国产视色精品亚洲一区二区| 国产精国产精品| 国产精品免费看久久久香蕉| 国产第一区电影| 全部a∨一极品视觉盛宴| 欧美好骚综合网| 欧美性色黄大片手机版| 久久综合给合久久狠狠色| 8x8ⅹ拨牐拨牐拨牐在线观看| 久久视频这里只有精品| 精品日产卡一卡二卡麻豆|