[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 的 filteroptions 在檢查時,會從最上層資料夾開始找(預設情況下),若在該層資料夾就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();