跳至主要内容

[note] fs-extra 筆記

fs-extra @ github

await fs.emptyDir('/tmp'); // 清空資料夾
const data = await fs.readFile('/tmp/video.webm'); // 讀取檔案

installation

npm install --save fs-extra

常用指令

複製資料夾(copy folders)

// NOTE: src 和 dist 都必需是資料夾
let backupFolders = [
{
src: '/Users/pjchen/Projects/Note/source/_posts',
dist: path.join(__dirname, '/MarkdownNotes'),
},
{
src: '/Users/pjchen/Library/Application Support/Code/User',
dist: path.join(__dirname, '/VSCode'),
},
];

let copyDirs = backupFolders.map((folder) => fse.copy(folder.src, folder.dist));
// Promise.all(copyDirs)

複製單一檔案(copy files)

// NOTE: src 和 dist 都必須要是檔案
let backupFiles = [
{
src: '/Users/pjchen/foo.txt',
dist: path.join(__dirname, '/Other/foo.txt'),
},
{
src: '/Users/pjchen/Projects/.jsbeautifyrc',
dist: path.join(__dirname, '/Other/.jsbeautifyrc'),
},
];

let copyFiles = backupFiles.map((file) => fse.copy(file.src, file.dist));
// Promise.all(copyFiles)

API

outputJson(file, object, [options, callback]), writeJson

keywords: make file, create file, 建立檔案, 新增檔案

outputJson()writeJson() 的用法相同,差別只在於 outputJson() 在資料夾不存在的時候會自動建立:

範例

const fs = require('fs-extra');
const path = require('path');

// 新增檔名及路徑
let file = path.join(__dirname, './outputJson.txt');

// 內容
let content = {
name: 'Po Jung',
age: 29,
gender: 'male',
};

fs.outputJson(file, content)
.then(() => fs.readJson(file))
.then((data) => {
console.log(data.name); // Po Jung
})
.catch((err) => {
console.error(err);
});

搭配 klaw 和 through2 爬資料夾和檔案

  • klaw 的 filter options 在檢查時,會從最上層資料夾開始找(預設情況下),若在該層資料夾就 return false 的話,則不會再進去往該資料夾內繼續找
  • 搭配使用 through2 時,想要保留的項目可以使用 this.push(item),如此才會被 pipe 往後傳
/**
* 這隻檔案只會去讀取 blog 和 docs 的資料夾中副檔名為 .md 的檔案
**/
import klaw from 'klaw';
import through2 from 'through2';
import path from 'path';

type Item = {
path: string;
stats: object;
};

// 在不改變原本搜尋的順序時,只要 return false,就不會再進去該資料夾找檔案
// 這裡只會進去找 blog 和 docs 的資料夾
const includeOnlyMarkdown = (itemPath: string): boolean => {
const relativePath = path.relative(process.cwd(), itemPath);

const availableDirs = ['blog', 'docs'];
const dirs = relativePath.split(path.sep);

return availableDirs.includes(dirs[0]);
};

// 有透過 this.push(item) 的檔案才會被往後傳
// 這裡只會回傳副檔名為 .md 的檔案
const generator = through2.obj(function (item, enc, next) {
if (path.extname(item.path) === '.md') {
this.push(item);
}
next();
});

let items: object[] = [];
const readFiles = async () => {
klaw('./', { filter: includeOnlyMarkdown })
.pipe(generator)
.on('data', (item: Item) => items.push(item.path))
.on('end', () => {
console.dir(items);
});
};

readFiles();