**:跨目录通配
01 页的 * 只在一段之内匹配,跨目录全靠 ** (globstar): 当它单独占一个路径段时,匹配零个或多个路径段。注意是「零个」起步——**/*.md 连根目录的 README.md 也命中,src/**
连 src 自身也算。而一旦与字面量混写 (a**b),双星就失去跨段语义,退化为普通 *。
在下面这棵典型前端项目树上换 pattern,看命中范围怎么伸缩。先对比前三个预设:*.md(只看根)→ **/*.md(不限深度)→ docs/**/*.md(限定在 docs)。
1 · 零个也算:** 匹配空序列
** 匹配「零个或多个段」,这个零是高频考点:**/*.js = *.js ∪ */*.js ∪ */*/*.js ∪ …,所以根目录的 js 也在内;同理 src/** 把 src 这个目录自身也包含进来(glob
工具默认目录也算匹配结果,要只取文件得用 node-glob 的 nodir 选项)。对照 src/* 与 src/** 两个预设:单星只到直接子级,双星覆盖全部后代。
2 · 必须单独成段,否则退化
** 的跨段语义有个前提:**整段恰好是 `` 才生效——src/**/x.ts ✓。写成 a**b、**.js 这种混写,node-glob、VS Code 与本仓库实现都把它当普通 * 处理(两颗星折叠成一颗):**.js 就是 *.js,照样不跨目录。另外
** 与相邻段之间的 / 不能省,src** ≠ src/**。
它也有不进的地方: ** 默认不进 dot 目录 (.git/、.vscode/),也不追 symlink(node-glob 默认只跟一层、follow:true 才全跟,防环)。前者是 dot 规则在目录维度的体现,04 页有开关可试。另外 ** 是开销最大的通配——它要求实现遍历整棵子树,放在 pattern 开头 () 时尤其注意范围。