Node.js 檔案系統進階:內建 Glob 匹配與文件監控實戰
在過去的開發經驗中,當我們需要「找出一目錄下所有的 .js 檔案」或是「監聽整個資料夾的變動」時,通常會直覺地安裝 glob 或 chokidar 套件。然而,隨著 Node.js 版本的演進,這些功能現在都已經內建在 node:fs 模組中了。
這篇文章將帶你掌握如何利用原生 API 實現高效的文件處理。
內建 Glob 匹配 (v22+)
從 Node.js 22.0.0 開始,node:fs 模組提供了原生的 glob 同步與非同步方法。這讓搜尋特定模式的檔案路徑變得極其簡單。
1. 基本用法
假設我們想搜尋 src 目錄下所有的快照檔案(例如 .spec.js):
const { glob, globSync } = require('node:fs/promises');
async function findFiles() {
// 找出所有 sub-directory 中的 .js 檔案
const files = await glob('src/**/*.js');
for await (const entry of files) {
console.log('找到檔案:', entry);
}
}
findFiles();
2. 排除特定路徑 (Exclude)
你可以透過 exclude 參數排除不感興趣的目錄(如 node_modules):
const files = await glob('**/*.ts', {
exclude: (path) => path.includes('node_modules') || path.includes('dist'),
});
原生檔案監控:Recursive Watch
監控檔案變動是開發熱重載 (Hot Reload) 或自動化工具的核心。雖然 fs.watch 存在已久,但早期在不同作業系統上的支援度不一。現在,Node.js 提供了更穩定的遞迴監控支援。
遞迴監聽整個目錄
不需要再手動巡覽資料夾,只需要設定 { recursive: true }:
const fs = require('node:fs');
// 監控整個 project/src 資料夾
const watcher = fs.watch('./src', { recursive: true }, (eventType, filename) => {
if (filename) {
console.log(`事件類型: ${eventType}`);
console.log(`變動檔案: ${filename}`);
}
});
watcher.on('error', (err) => {
console.error('監控發生錯誤:', err);
});
console.log('正在監控檔案變動中...');
實務技巧:高效遍歷子目錄 (Recursive Readdir)
如果你不需要模式匹配 (Glob),只是單純想列出所有檔案,使用 readdir 並配合 recursive 選項會比遞迴函數更高效。
const { readdir } = require('node:fs/promises');
async function listAllFiles() {
const files = await readdir('./content', { recursive: true });
console.log('所有檔案清單:', files);
}
為什麼要用原生 API 取代套件?
- 減少依賴地獄:減少
node_modules的體積,降低供應鏈安全風險。 - 降低維護成本:不需要追蹤第三方套件的重大更新 (Breaking Changes) 或棄用訊息。
- 優化啟動效能:減少了解析大量第三方程式碼的時間,對於 CLI 工具尤為明顯。
版本提醒:原生 Glob 功能目前在 Node.js 22 中仍處於實作穩定期。如果你需要在 Node.js 18 或 20 環境下使用,建議先檢查版本相容性,或繼續使用成熟的第三方套件。
總結
glob讓你像在終端機一樣靈活地搜尋檔案。fs.watch({ recursive: true })是建立本地開發工具的最佳拍檔。- 掌握原生
fs的現代特性,能讓你的 Node.js 程式更純粹且更具前瞻性。