所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

fast-glob 高性能文件匹配利器,让文件处理更高效!

简介

fast-glob 是一个高性能的 Node.js 文件系统 glob 库,用于快速匹配文件路径模式。它提供了比原生 Node.js glob 更快的性能,支持异步和同步操作,是现代前端工具链中广泛使用的文件匹配库。

特点

  • 高性能: 比其他 glob 库快 2-5 倍
  • 灵活的 API: 支持同步、异步、流式操作
  • 丰富的选项: 提供大量配置选项满足不同需求
  • TypeScript 支持: 完整的类型定义
  • 零依赖: 不依赖其他第三方库

安装

npm install fast-glob

或者

yarn add fast-glob

基础用法

异步操作(推荐)

import fg from "fast-glob";

// 基础匹配
const files = await fg(["src/**/*.js", "lib/**/*.js"]);
console.log(files);
// ['src/index.js', 'src/utils/helper.js', 'lib/main.js']

// 排除文件
const files = await fg(["src/**/*.js", "!src/**/*.test.js"]);
console.log(files);
// ['src/index.js', 'src/utils/helper.js'] (排除测试文件)

同步操作

import fg from "fast-glob";

const files = fg.sync(["src/**/*.{js,ts}"]);
console.log(files);
// ['src/index.js', 'src/types.ts', 'src/utils/helper.js']

流式操作

import fg from "fast-glob";

const stream = fg.stream(["src/**/*.js"]);

stream.on("data", (entry) => {
  console.log(entry); // 每个匹配的文件路径
});

stream.on("end", () => {
  console.log("完成");
});

模式语法

基础通配符

// * 匹配任意字符(除了路径分隔符)
await fg("src/*.js"); // src/index.js, src/main.js

// ** 匹配任意目录层级
await fg("src/**/*.js"); // src/utils/helper.js, src/components/Button.js

// ? 匹配单个字符
await fg("src/?.js"); // src/a.js, src/1.js

// [] 字符集匹配
await fg("src/[abc].js"); // src/a.js, src/b.js, src/c.js
await fg("src/[a-z].js"); // src/a.js 到 src/z.js

大括号展开

// 多个扩展名
await fg("src/**/*.{js,ts,vue}");
// 等同于: ['src/**/*.js', 'src/**/*.ts', 'src/**/*.vue']

// 多个目录
await fg("{src,lib}/**/*.js");
// 等同于: ['src/**/*.js', 'lib/**/*.js']

// 复杂组合
await fg("src/**/*.{test,spec}.{js,ts}");
// 匹配: src/utils/helper.test.js, src/components/Button.spec.ts

否定模式

// 排除特定文件
await fg(["src/**/*.js", "!src/**/*.test.js"]);

// 排除目录
await fg(["src/**/*", "!src/node_modules/**"]);

// 多个排除条件
await fg([
  "src/**/*.{js,ts}",
  "!src/**/*.test.{js,ts}",
  "!src/**/*.spec.{js,ts}",
  "!src/temp/**",
]);

配置选项

基础选项

const options = {
  // 基础目录
  cwd: process.cwd(),

  // 返回绝对路径
  absolute: false,

  // 匹配点文件(隐藏文件)
  dot: false,

  // 区分大小写
  caseSensitiveMatch: true,

  // 跟随符号链接
  followSymbolicLinks: true,

  // 忽略错误
  suppressErrors: false,

  // 抛出错误而不是忽略
  throwErrorOnBrokenSymbolicLink: true,
};

const files = await fg(["src/**/*.js"], options);

高级选项

const advancedOptions = {
  // 深度限制
  deep: 5,

  // 只匹配文件
  onlyFiles: true,

  // 只匹配目录
  onlyDirectories: false,

  // 标记为目录的模式
  markDirectories: false,

  // 返回相对路径
  objectMode: false,

  // 统计信息
  stats: false,

  // 唯一结果
  unique: true,

  // 并发限制
  concurrency: Infinity,

  // 忽略父目录
  ignore: ["node_modules/**", ".git/**"],
};

实际应用场景

1. 构建工具中的文件收集

import fg from "fast-glob";
import path from "path";

// 收集所有源文件
async function collectSourceFiles() {
  const patterns = [
    "src/**/*.{js,ts,jsx,tsx}",
    "lib/**/*.{js,ts}",
    "!**/*.test.{js,ts}",
    "!**/*.spec.{js,ts}",
    "!**/node_modules/**",
  ];

  const files = await fg(patterns, {
    cwd: process.cwd(),
    absolute: true,
    onlyFiles: true,
  });

  return files.map((file) => ({
    path: file,
    name: path.basename(file),
    ext: path.extname(file),
    dir: path.dirname(file),
  }));
}

// 使用示例
const sourceFiles = await collectSourceFiles();
console.log(`找到 ${sourceFiles.length} 个源文件`);

2. 静态资源处理

// 处理图片资源
async function processImages() {
  const imagePatterns = [
    "src/assets/**/*.{png,jpg,jpeg,gif,svg,webp}",
    "public/images/**/*.{png,jpg,jpeg,gif,svg,webp}",
  ];

  const images = await fg(imagePatterns, {
    onlyFiles: true,
    stats: true, // 获取文件统计信息
  });

  return images.map((entry) => ({
    path: entry.path,
    size: entry.stats.size,
    modified: entry.stats.mtime,
  }));
}

3. 代码分析工具

// 分析项目结构
async function analyzeProject() {
  const analysis = {
    components: await fg("src/components/**/*.{vue,jsx,tsx}"),
    utils: await fg("src/utils/**/*.{js,ts}"),
    styles: await fg("src/**/*.{css,scss,less,stylus}"),
    tests: await fg("**/*.{test,spec}.{js,ts,jsx,tsx}"),
    configs: await fg("*.config.{js,ts,json}"),
  };

  // 统计信息
  const stats = Object.entries(analysis).map(([type, files]) => ({
    type,
    count: files.length,
    files,
  }));

  return stats;
}

4. 文件监听和热更新

import fg from "fast-glob";
import chokidar from "chokidar";

// 设置文件监听
async function setupFileWatcher() {
  // 获取需要监听的文件
  const watchPatterns = [
    "src/**/*.{js,ts,vue,jsx,tsx}",
    "src/**/*.{css,scss,less}",
  ];

  const filesToWatch = await fg(watchPatterns);

  // 创建监听器
  const watcher = chokidar.watch(filesToWatch, {
    ignored: /node_modules/,
    persistent: true,
  });

  watcher
    .on("change", (path) => console.log(`文件变更: ${path}`))
    .on("add", (path) => console.log(`文件添加: ${path}`))
    .on("unlink", (path) => console.log(`文件删除: ${path}`));

  return watcher;
}

性能优化技巧

1. 使用具体的模式

// ❌ 性能较差
await fg("**/*");

// ✅ 性能更好
await fg("src/**/*.{js,ts,vue}");

2. 合理使用排除模式

// ✅ 推荐:在模式中排除
await fg(["src/**/*.js", "!src/node_modules/**"]);

// ❌ 不推荐:在选项中排除
await fg("src/**/*.js", {
  ignore: ["src/node_modules/**"],
});

3. 限制搜索深度

// 限制搜索深度提高性能
await fg("src/**/*.js", {
  deep: 3, // 最多搜索3层目录
});

4. 使用并发控制

// 控制并发数量避免资源耗尽
await fg("**/*.js", {
  concurrency: 10, // 限制并发为10
});

错误处理

import fg from "fast-glob";

try {
  const files = await fg(["src/**/*.js"], {
    throwErrorOnBrokenSymbolicLink: true,
    suppressErrors: false,
  });

  console.log(`找到 ${files.length} 个文件`);
} catch (error) {
  if (error.code === "ENOENT") {
    console.error("目录不存在");
  } else if (error.code === "EACCES") {
    console.error("权限不足");
  } else {
    console.error("未知错误:", error.message);
  }
}

与其他工具集成

Vite 插件中的使用

// vite.config.js
import { defineConfig } from "vite";
import fg from "fast-glob";

export default defineConfig({
  plugins: [
    {
      name: "custom-file-processor",
      buildStart: async () => {
        // 处理特定文件
        const files = await fg("src/assets/icons/*.svg");
        console.log(`处理 ${files.length} 个 SVG 图标`);
      },
    },
  ],
});

Webpack 配置中的使用

// webpack.config.js
const fg = require("fast-glob");
const path = require("path");

module.exports = async () => {
  // 动态生成入口点
  const entries = await fg("src/pages/*/index.js");
  const entryPoints = {};

  entries.forEach((entry) => {
    const name = path.basename(path.dirname(entry));
    entryPoints[name] = entry;
  });

  return {
    entry: entryPoints,
    // ... 其他配置
  };
};

总结

fast-glob 是一个功能强大且高性能的文件匹配库,特别适合在构建工具、静态分析、文件处理等场景中使用。通过合理使用其丰富的配置选项和模式语法,可以高效地处理各种文件匹配需求。

最佳实践

  1. 优先使用异步 API 以获得更好的性能
  2. 使用具体的模式 而不是过于宽泛的通配符
  3. 合理使用排除模式 提高匹配效率
  4. 设置适当的深度限制 避免不必要的深度搜索
  5. 处理错误情况 确保程序的健壮性

通过掌握这些用法和技巧,您可以在项目中充分发挥 fast-glob 的优势,提高文件处理的效率和性能。

资源下载
下载价格免费
注意:本网站资源属于虚拟产品,不支持退款。请谨慎购买! 购买后资源无法下载,请联系客服QQ:844475003,微信号:th844475003。
原文链接:https://code.ifrontend.net/archives/882,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?