html
即使写入 ['.gitignore', '/.gitignore', '.*'],调用 fastGlob(patterns) 仍返回空数组——这不是 Bug,而是设计契约。Unix 系统中以 . 开头的条目默认“不可见”,fast-glob 将此约定内化为默认过滤行为,且该过滤发生在 glob 模式匹配前的文件系统遍历阶段。
fast-glob 的路径发现并非单次正则匹配,而是依赖底层 @nodelib/fs.walk 实现的深度优先路径遍历 + 预筛选策略。其执行流程如下:
(无论模式是否含 .)] B -- 是 --> D[进入目录/文件枚举] D --> E{当前条目名是否以 . 开头?} E -- 否 --> F[加入候选集] E -- 是 --> G[检查模式是否显式声明点文件
如 '.env' 或 '/.git/'] G -- 匹配模式 --> F G -- 不匹配 --> H[丢弃]
dot: true 并非“启用隐藏文件支持”,而是解除对点文件的硬性拦截闸门;它只是允许后续模式匹配逻辑有机会触达这些条目。若未在 pattern 中显式包含点路径片段(如 .env、/.git/config),即使 dot: true,结果仍为空。常见错误配置对比:
{ dot: false }
['.gitignore']❌ 空预遍历阶段直接跳过
{ dot: true }
['*.gitignore']❌ 空
* 不匹配路径分隔符
/,无法穿透到子目录
{ dot: true }
['/.gitignore']✅ 匹配根目录下 .gitignore
/ 显式声明路径层级,且
.gitignore 是完整文件名
隐藏文件匹配失败,70% 源于模式语法与 Unix 路径语义错位。关键规则:
表示零或多个目录层级,但不跨越路径分隔符边界匹配文件名;.*仅匹配当前目录下的隐藏文件,不递归;- 要匹配
.git/hooks/pre-commit,必须用/.git/或精确路径/.git/hooks/pre-commit; /.git*可能误匹配.gitlab-ci.yml,但无法匹配.git/config(因*不含/)。
- 全局启用:
dot: true(必设,否则无后续) - 显式声明:在 patterns 中添加
'.env'、'.gitignore'、'/.git/'等具体路径 - 规避通配歧义:禁用模糊模式如
*.env,改用.env或/.env - 验证路径存在:配合
fs.statSync()或fastGlob的stats: true选项确认条目类型
当项目使用 git worktree 或子模块时,.git 可能是文件而非目录(内容为 gitdir: ../.git/worktrees/mybranch)。此时 /.git/ 会失败——需结合 objectMode: true 获取 stats.isDirectory() 判断,并动态构造模式。这是资深工程中 CI/CD 资源扫描常崩的关键盲区。
对比 glob(Node.js 原生)、micromatch 和 fast-glob:
glob默认dot: false,但dot: true即可匹配.env(无需显式模式);micromatch是纯字符串匹配库,不涉及文件系统遍历,无隐藏文件问题;fast-glob为性能牺牲了直觉性——它将 Unix 隐私契约与高性能 walk 引擎耦合,形成默认隐藏、需双显式(配置 + 模式)、路径语义须严谨的铁三角约束。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/282575.html