fs-extra: 替代 Node.js 內(nèi)置 fs 模塊,更安全、更強(qiáng)大的文件操作庫(kù)
fs-extra 是作為替代 Node.js 內(nèi)置 fs 模塊創(chuàng)建的,當(dāng)你的項(xiàng)目中引入 fs-extra 后,就可以像下面這樣做。
將所有使用 require('fs')
的地方:
改成 require('fs-extra')
:
在 fs-extra 內(nèi)部,除了重新導(dǎo)出(re-exporting)內(nèi)置 fs 模塊的所有方法外,還增加了一些常用而且安全的方法,比如 copy()
、remove()
和 mkdirs()
。
為什么?
按作者的原話說(shuō):“我已經(jīng)厭倦了在我大多數(shù)項(xiàng)目里都引入一遍 mkdirp
、rimraf
和 ncp
”。
mkdirp
、rimraf
和 ncp
是 3 個(gè) npm 包,用來(lái)做不同類型的文件操作:
mkdirp
:用來(lái)創(chuàng)建目錄,支持嵌套嵌套目錄的創(chuàng)建。實(shí)現(xiàn)類似mkdir -p
指令的功能rimraf
:用來(lái)刪除文件/目錄,支持嵌套文件/目錄的刪除。實(shí)現(xiàn) Linux 系統(tǒng)上rm -rf
指令的功能ncp
:cp 就是 copy 簡(jiǎn)寫(xiě),這個(gè)包用來(lái)復(fù)制文件/目錄的,支持嵌套文件/目錄的復(fù)制
之所以有這 3 個(gè)包出現(xiàn),是因?yàn)?Node.js 內(nèi)置 fs 模塊實(shí)現(xiàn)上面 3 個(gè)功能有些麻煩,特別是嵌套文件/目錄的復(fù)制和刪除。
fs-extra 的做法
fs-extra 的作者將上面 3 個(gè)常用(創(chuàng)建目錄、刪除和復(fù)制)的功能統(tǒng)一在一個(gè)包中:
ensureDir
(別名mkdirs()
、mkdirp()
) 替代mkdirp
remove
替代rimraf
copy
替代ncp
這些方法默認(rèn)都是異步的,同步版本需要加上 Sycn
后綴,也就是:ensureDirSync
、removeSync
和 copySync
。
另外,還額外提供了其他的方法:
比如操作 JSON 文件讀寫(xiě)的
writeJson
和readJson
方法比如清空目錄
emptyDir
方法
fs-extra 額外提供的方法很多,我這里挑一些常用的方法做一下講解。跟 fs 模塊的內(nèi)置方法異樣,fs-extra 提供的 API 也會(huì)異步和同步版本,為了簡(jiǎn)單和方便,本文使用同步 API 做下實(shí)驗(yàn)。
準(zhǔn)備工作
我們新建一個(gè)名為 fs-extra-demos
的項(xiàng)目,使用 pnpm 初始化后,在這里進(jìn)行練習(xí)。
按照 fs-extra 依賴:
package.json
啟用 ES Module。
在實(shí)際練習(xí)時(shí),我們經(jīng)常會(huì)用到 __dirname
,但 ES Module 并未提供,下面是獲取方式。
練習(xí)
copySync(src, dest[, options])
用于復(fù)制文件或者目錄,支持嵌套目錄下的復(fù)制。
一、如果 src
地址文件不存在會(huì)報(bào)錯(cuò)
二、當(dāng) src
地址存在,但 dest
參數(shù)(也就是目標(biāo)地址)沒(méi)賦值時(shí)會(huì)報(bào)錯(cuò)
三、復(fù)制文件
四、復(fù)制目錄
再次執(zhí)行也不會(huì)報(bào)錯(cuò),同名文件會(huì)被復(fù)制過(guò)來(lái)的文件覆蓋。
五、復(fù)制目錄(設(shè)置不覆蓋文件,出現(xiàn)同名文件時(shí)報(bào)錯(cuò))
這個(gè)很少使用。我們通常不希望意外的報(bào)錯(cuò)影響我們的代碼流程。
六、復(fù)制目錄的位置存在同名文件會(huì)報(bào)錯(cuò)
同理,復(fù)制文件的位置存在同名目錄也會(huì)報(bào)錯(cuò)。
當(dāng)然,這種情況非常少見(jiàn)。記住一個(gè)原則就能避免這個(gè)錯(cuò)誤,就能安全地使用 copySync
方法:在同一個(gè)目錄結(jié)構(gòu)下,不允許出現(xiàn)同名的目錄或者文件。
removeSync(path)
用于刪除文件或者目錄,支持嵌套目錄下的刪除。
一、刪除文件不存在不會(huì)報(bào)錯(cuò)
二、刪除文件或目錄
目錄中即使有內(nèi)容,也能完全刪除,不會(huì)報(bào)錯(cuò)??傊?,removeSync
方法使用起來(lái)非常安全,不會(huì)報(bào)錯(cuò)。
ensureDirSync(dir[,options])
用于創(chuàng)建目錄,支持嵌套目錄的創(chuàng)建。還有 2 個(gè)別名:mkdirsSync
、mkdirpSync
。
多個(gè)目錄和多層嵌套目錄都 OK。
重復(fù)執(zhí)行上述代碼也不會(huì)報(bào)錯(cuò)。對(duì)于已存在的目錄結(jié)構(gòu),ensureDirSync
方法什么都不做。
ensureFileSync(file)
跟ensureDirSync類似,ensureFileSync用于創(chuàng)建文件。
一、直接創(chuàng)建文件 & 創(chuàng)建嵌套在目錄結(jié)構(gòu)中的文件
在創(chuàng)建嵌套在目錄結(jié)構(gòu)中的文件時(shí),如果父級(jí)目錄不存在,會(huì)自動(dòng)創(chuàng)建。
重復(fù)執(zhí)行上述代碼也不會(huì)報(bào)錯(cuò)。對(duì)于已存在的文件,ensureFileSync
方法什么都不做。
二、在已存在文件的地方創(chuàng)建同名目錄會(huì)報(bào)錯(cuò)
同理,在已存在目錄的地方創(chuàng)建同名文件也會(huì)報(bào)錯(cuò)
當(dāng)然,上面兩種情況很少遇到。還是那個(gè)原則:在同一個(gè)目錄結(jié)構(gòu)下,不允許出現(xiàn)同名的目錄或者文件。
emptyDirSync(dir)
用于清空目錄。支持嵌套目錄中的文件清除。
一、清空目錄
二、如果要清空的目錄不存在,就會(huì)創(chuàng)建這個(gè)目錄
emptyDirSync
方法也超好用,不會(huì)報(bào)錯(cuò)。
readJsonSync(file[, options])
用于讀取 JSON 文件。內(nèi)部使用的是 jsonfile 包提供的方法。
一、讀取不存在的文件會(huì)報(bào)錯(cuò)
二、會(huì)將讀取到的文件內(nèi)容轉(zhuǎn)成 JS 對(duì)象
writeJsonSync(file, object[, options])
用于寫(xiě) JSON 文件。跟 readJsonSync
方法一樣,內(nèi)部使用的是 jsonfile 包提供的方法。
hello.json
文件內(nèi)容:
(注意,有一個(gè)空行 EOF,這是默認(rèn)行為)
當(dāng)然我們也可以使用第 3 個(gè)參數(shù)做格式化:
我們使用了 2 個(gè)空格的縮進(jìn),同時(shí)換行符采用 Windows 系統(tǒng)默認(rèn)的 \r\n
(writeJsonSync
方法默認(rèn)是 ?\n
,更好一些)
hello.json
文件被覆蓋為:
moveSync(src, dest[, options])
用于移動(dòng)文件或者目錄。
一、移動(dòng)不存在的文件
二、移動(dòng)文件或者目錄
三、移動(dòng)目錄的位置存在文件會(huì)報(bào)錯(cuò)
同理,移動(dòng)文件的位置存在目錄也會(huì)報(bào)錯(cuò)
也就是說(shuō),移動(dòng)的問(wèn)題存在不同類型的文件,就會(huì)報(bào)錯(cuò)。
pathExistsSync
判斷指定路徑下的文件或者目錄是否存在。其實(shí)就是 fs.existsSync()
方法的別名。
pathExistsSync
方法用起來(lái)也很安全,不會(huì)報(bào)錯(cuò)。
總結(jié)
總的來(lái)說(shuō),使用 fs-extra 還是很安全的,只要記住一個(gè)原則就好:在涉及寫(xiě)操作的時(shí)候,要確保寫(xiě)入的是同一個(gè)文件類型(文件寫(xiě)文件,目錄寫(xiě)目錄),否則會(huì)報(bào)錯(cuò)。
copySync
:用于文件或目錄的復(fù)制,只要保證復(fù)制的原文件存在就能安全使用removeSync
:用于刪除文件或目錄,可以安全使用,永遠(yuǎn)不會(huì)報(bào)錯(cuò)ensureDirSync
& ensureFileSync:分別用于目錄和文件的創(chuàng)建,當(dāng)目標(biāo)位置如果有目錄或文件存在時(shí),什么都不會(huì)做,正如方法名所言,是用來(lái)“保證(ensure)”這個(gè)位置有目錄或文件的readJsonSync
:讀取 JSON 文件,只要保證復(fù)制的原文件存在就能安全使用writeJsonSync
:寫(xiě) JSON 文件??梢?/span>使用第 3 個(gè)參數(shù)做寫(xiě)入 JSON 數(shù)據(jù)的格式化moveSync
:移動(dòng)文件或目錄,只要保證移動(dòng)的原文件存在就能安全使用pathExistsSync
:判斷文件或目錄是否存在,可以安全使用,永遠(yuǎn)不會(huì)報(bào)錯(cuò)