fix(explorer): 文件名搜索跳过 node_modules 等噪声目录

右侧文件窗口的全局文件名搜索会深度优先遍历整个工作区,原先只跳过
.git。含大型 node_modules 的仓库会先把 10 万条访问预算耗尽,导致
docs/ 等后序目录里的真实文件搜不到。

搜索改为跳过依赖、包管理存储和常见构建缓存目录(不匹配也不下降),
并补回归测试钉住 node_modules / dist 内的命中不会泄漏。
This commit is contained in:
leokuang
2026-08-23 02:50:37 +08:00
parent d9b8f15d9e
commit d0f194b67a
3 changed files with 61 additions and 12 deletions
+25 -3
View File
@@ -1,9 +1,10 @@
/**
* fs-search: the host's recursive file-name search behind the editor side
* panel's search box. Matches are case-insensitive name substrings, reported
* RELATIVE to the root ('/'-separated); `.git` directories are skipped,
* symlinked directories are never descended (cycle safety), and the
* maxMatches/maxVisited budgets stop a runaway walk with `truncated: true`.
* RELATIVE to the root ('/'-separated); noise directories (`.git`,
* `node_modules`, build caches) are skipped, symlinked directories are
* never descended (cycle safety), and the maxMatches/maxVisited budgets
* stop a runaway walk with `truncated: true`.
*/
import { describe, expect, it } from 'vitest'
import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from 'node:fs'
@@ -86,6 +87,27 @@ describe('fs-search', () => {
}
})
it('never descends into node_modules or other noise directories', async () => {
const dir = makeFixture()
try {
mkdirSync(join(dir, 'node_modules', 'left-pad'), { recursive: true })
mkdirSync(join(dir, 'web', 'dist'), { recursive: true })
writeFileSync(join(dir, 'node_modules', 'left-pad', 'guide.md'), 'dep')
writeFileSync(join(dir, 'web', 'dist', 'bundle.js'), 'build')
writeFileSync(join(dir, 'web', 'app.ts'), 'src')
// A match hidden behind node_modules / dist must not appear; project
// files after those forests must still be reachable within budget.
expect((await searchFiles(dir, 'guide')).matches).toEqual(['docs/guide.md'])
expect((await searchFiles(dir, 'left-pad')).matches).toEqual([])
expect((await searchFiles(dir, 'bundle')).matches).toEqual([])
expect((await searchFiles(dir, 'app.ts')).matches).toEqual(['web/app.ts'])
expect((await searchFiles(dir, 'node_modules')).matches).toEqual([])
expect((await searchFiles(dir, 'dist')).matches).toEqual([])
} finally {
rmSync(dir, { recursive: true, force: true })
}
})
it('an empty (or whitespace) query matches nothing without walking', async () => {
const dir = makeFixture()
try {