如何用 Bun Glob 扫描目录文件并匹配 glob 模式
2026/9/13 2:53:03 网站建设 项目流程

如何用 Bun Glob 扫描目录文件并匹配 glob 模式

【免费下载链接】bunIncredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one项目地址: https://gitcode.com/GitHub_Trending/bu/bun

如果你的任务是遍历一个目录找出符合条件的文件(例如项目里所有.ts文件),或者判断某个路径是否符合给定的通配规则,可以用 Bun 内置的原生 glob 实现Glob类完成:它对目录做的是真正的扫描(scan),对字符串做的是纯匹配(match),两者共用同一套 glob 模式语法。本文的前提是 Bun 已安装并可在PATH中找到(参见 安装文档),脚本用bun run运行即可,无需额外安装依赖。

完整 API 说明见 docs/runtime/glob.mdx,行为对应的测试在 test/js/bun/glob/scan.test.ts 和 test/js/bun/glob/match.test.ts。

准备条件

  • Bun 已安装并在PATH中(Quickstart 的前置要求)。
  • 一个包含待扫描文件的目录。下文示例以当前工作目录.作为扫描根目录。
  • 新建一个 TypeScript 或 JavaScript 脚本文件,例如scan.ts,用bun run scan.ts执行。

扫描目录文件

Globscan方法返回可迭代对象,逐条产出匹配到的路径;scanSync是同步版本。下面的示例递归扫描当前工作目录及其所有子目录,找出*.ts文件:

import { Glob } from "bun"; const glob = new Glob("**/*.ts"); // Scans the current working directory and each of its sub-directories recursively for await (const file of glob.scan(".")) { console.log(file); // 文档示例输出:如 "index.ts" }

同步遍历改用scanSync,返回值为Iterable<string>

import { Glob } from "bun"; const glob = new Glob("**/*.ts"); for (const file of glob.scanSync(".")) { console.log(file); }

scan/scanSyncroot参数可以传目录路径字符串,也可以传一个ScanOptions对象来控制扫描行为。文档给出的接口与选项如下,各选项的@default即默认值:

class Glob { scan(root: string | ScanOptions): AsyncIterable<string>; scanSync(root: string | ScanOptions): Iterable<string>; match(path: string): boolean; } interface ScanOptions { cwd?: string; // 扫描根目录,默认 process.cwd() dot?: boolean; // 是否允许匹配以 . 开头的条目,默认 false absolute?: boolean; // 是否返回绝对路径,默认 false followSymlinks?: boolean; // 是否遍历符号链接目录,默认 false throwErrorOnBrokenSymlink?: boolean; // 遇到断裂符号链接是否抛错,默认 false onlyFiles?: boolean; // 只返回文件,默认 true }

几个常用组合:

// 只扫描指定目录,不递归进入符号链接目录 const glob = new Glob("**/*.ts"); for await (const file of glob.scan({ cwd: "./src" })) { console.log(file); } // 返回绝对路径 const glob2 = new Glob("**/*.js", { absolute: true }); for await (const file of glob2.scan(".")) { console.log(file); } // 默认只返回文件(onlyFiles 默认 true);要连目录一起列出,显式关掉它 const glob3 = new Glob("*", { onlyFiles: false }); for (const file of glob3.scanSync(".")) { console.log(file); }

用 glob.match 匹配字符串

不在文件系统中扫描,而只是判断一个路径是否符合模式时,用match方法,返回boolean。文档给出的示例(返回值均为文档示例):

import { Glob } from "bun"; const glob = new Glob("*.ts"); glob.match("index.ts"); // => true glob.match("index.js"); // => false

Bun 支持的 glob 模式及文档示例如下,可直接用于设计匹配规则:

?— 匹配任意单个字符

const glob = new Glob("???.ts"); glob.match("foo.ts"); // => true glob.match("foobar.ts"); // => false

*— 匹配零个或多个字符,但不跨路径分隔符(/\

const glob = new Glob("*.ts"); glob.match("index.ts"); // => true glob.match("src/index.ts"); // => false

**— 匹配任意数量的字符,包括/

const glob = new Glob("**/*.ts"); glob.match("index.ts"); // => true glob.match("src/index.ts"); // => true glob.match("src/index.js"); // => false

[ab]— 匹配括号内的字符之一,也支持字符区间

const glob = new Glob("ba[rz].ts"); glob.match("bar.ts"); // => true glob.match("baz.ts"); // => true glob.match("bat.ts"); // => false

区间写法如[0-9][a-z];否定写法^!匹配括号内字符之外的一切([^ab][!a-z])。文档示例:

const glob = new Glob("ba[a-z][0-9][^4-9].ts"); glob.match("bar01.ts"); // => true glob.match("baz83.ts"); // => true glob.match("bat22.ts"); // => true glob.match("bat24.ts"); // => false glob.match("ba0a8.ts"); // => false

{a,b,c}— 匹配给定模式中的任意一个

const glob = new Glob("{a,b,c}.ts"); glob.match("a.ts"); // => true glob.match("b.ts"); // => true glob.match("c.ts"); // => true glob.match("d.ts"); // => false

这类花括号模式最多可以嵌套 10 层,且内部可以包含前面介绍过的任意通配符。

!— 在模式开头取反结果

const glob = new Glob("!index.ts"); glob.match("index.ts"); // => false glob.match("foo.ts"); // => true

\— 转义上述特殊字符

const glob = new Glob("\\!index.ts"); glob.match("!index.ts"); // => true glob.match("index.ts"); // => false

这里"\\!index.ts"是 TypeScript 字符串字面量,实际模式是\!index.ts,匹配的文件名以字面!开头。

可选分支:Node.jsfs.glob()兼容写法

如果代码原本按 Node.js 的fs.glob()编写,Bun 也实现了这组函数,可以不改写法直接使用。第一参数支持传入模式数组,选项支持exclude过滤结果:

import { glob, globSync, promises } from "node:fs"; // Array of patterns const files = await Array.fromAsync(promises.glob(["**/*.ts", "**/*.js"])); // Exclude patterns const filtered = await Array.fromAsync( promises.glob("**/*", { exclude: ["node_modules/**", "**/*.test.*"], }), );

文档说明fs.glob()fs.globSync()fs.promises.glob()三个函数都支持:第一参数传模式数组;exclude选项过滤结果。这条路径适合把 Node 项目里的 glob 调用平移到 Bun 环境。

运行与验证

在一个包含若干.ts文件的目录中,把上面「扫描目录文件」一节的示例存为scan.ts,然后执行:

bun run scan.ts

预期现象以当前目录实际存在的文件为准:脚本会逐行打印匹配到的路径。文档 Quickstart 中给出的console.log(file); // => "index.ts"是文档示例输出,表示工作目录下存在index.ts时的单行打印效果,不是固定预期结果。

判断匹配规则是否生效,用match断言最直观:对同一模式分别传入应命中与不应命中的路径,返回true/false与文档示例一致即说明模式写对了(例如*.tsindex.ts返回true,对index.js返回false)。

限制与边界

  • dot默认false:以.开头的条目默认不会匹配,需要时显式传dot: true
  • onlyFiles默认truescan默认只返回文件,不返回目录。
  • followSymlinks默认false:不会遍历符号链接指向的子目录;throwErrorOnBrokenSymlink默认false,遇到断裂符号链接不抛错,需要抛错时显式开启。
  • cwd默认process.cwd():不传ScanOptions时扫描根目录就是进程当前工作目录。
  • 花括号模式{a,b,c}嵌套上限为 10 层。
  • !取反只作用于模式开头;*不跨路径分隔符,跨目录递归必须用**

如果项目里需要把 glob 用于测试文件的并行分组等场景,可参考 docs/guides/test/concurrent-test-glob.mdx 中的 glob 用法说明。

【免费下载链接】bunIncredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one项目地址: https://gitcode.com/GitHub_Trending/bu/bun

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询