NoSignups (FckSignups)
细读 NoSignups 搜索源码:ASCII 分词、子串匹配与分数平局
用边界输入解释 tokenize 和 matchScore,区分运行时数据验证、TypeScript 类型与 README 说明。
你将学会
- ASCII 分词可能把有意义的输入变成空查询。
- includes 匹配子串,重复词会重复计数。
- JSON-LD 文件不承担目录运行时验证。
开始前需要
- 基础 JavaScript 和 JSON 知识
- 一个无敏感任务样本与目录测试记录
解释本章边界,并用建议样例或审查记录进行核验。
先看结论
- ASCII 分词可能把有意义的输入变成空查询。
- includes 匹配子串,重复词会重复计数。
- JSON-LD 文件不承担目录运行时验证。
按字面理解分词正则
tokenize 把输入转为小写,以 a-z、0-9 和加号之外的字符切分,再移除空项。因此 video-editor 与 video_editor 变成相同的两个词,c++ 保留加号;带重音字母会成为分隔点,而不是自动规范化,纯中文查询则没有词。行为由正则决定,不会随界面语言自动变化。
这很重要,因为零个词会被当作没有搜索条件。读者输入有意义的中文查询,可能得到整个当前分类,而不是“不支持该查询”的明确提示。多语言分支应先规定 Unicode 词、重音和技术标识符的目标行为;没有测试样例就改正则,可能反而破坏 C++ 等程序语言名称。
子串匹配不是完整词匹配
matchScore 把名称、描述和标签拼成小写文本,用相同的非 ASCII 分隔规则替换为空格,然后统计 haystack.includes 命中的查询词。因此 art 能匹配 cart 中的子串;重复查询词没有去重,art art 可以因同一子串两次满足条件而得两分。这些例子来自函数体,不是线上搜索性能测试。
钩子只保留分数等于查询词数量的记录。搜索 video editor 要求两个词都在合并文本某处出现,却不要求相邻或位于同一字段。过滤后所有分数相同,星标决定分组前的排序。未来改变这一规则,应被说明为产品选择,而不是宣称某种新排序必然更适合所有读者。
类型不会自动检查下载对象
loadTools 将解析的 JSON 断言为 ToolsData,但 TypeScript 在运行时会移除该断言。此路径捕获 HTTP 和 JSON 解析失败,并没有证明工具 ID 唯一、分类存在、URL 协议受支持或每条记录都有 tags 数组。名为 schema.js 的文件提供网站 JSON-LD,也不是目录验证器。
修改前可以建立小型样例矩阵:缺少 tags、重复 id、未知分类和非拉丁文字搜索,并规定每种情况应拒绝、修复还是明确提示。下方示例只复现独立分词逻辑,不是完整上游钩子;它通过测试,不能证明整个应用或公共目录已经通过验证。
实施步骤
- 1
阅读固定提交中的 tokenize 与 matchScore。
- 2
运行独立分词样例并核对预期。
- 3
改搜索前补充子串、重复词和异常记录案例。
可复制示例
const tokenize = text => text.toLowerCase()
.split(/[^a-z0-9+]+/).filter(Boolean);
for (const query of ["video-editor", "c++", "café", "视频编辑", "art art"]) {
console.log(JSON.stringify(query), tokenize(query));
}
// 独立逻辑样例,不是完整 React 钩子。常见问题
搜索按完整单词匹配吗?
不是。已检查实现对合并文本调用 includes,因此较短词可能命中较长词内部。
schema.js 会验证 tools.json 吗?
不会。它导出注入 HTML 的 WebSite 结构化数据;加载器使用的是类型断言,不是逐条运行时验证。
资料来源
- README.md来源核查 2026-09-07
- package.json来源核查 2026-09-07
- vite.config.mts来源核查 2026-09-07
- src/hooks/useTools.ts来源核查 2026-09-07
- src/components/Home/Tools/Tools.tsx来源核查 2026-09-07
- src/components/Home/Tools/ToolCard/ToolCard.tsx来源核查 2026-09-07
- src/types/index.ts来源核查 2026-09-07
- src/constants/fallbackData.ts来源核查 2026-09-07
- src/data/schema.js来源核查 2026-09-07
- cloudflare-worker/worker.ts来源核查 2026-09-07
- cloudflare-worker/urlHandlers/handleSubmitTool.ts来源核查 2026-09-07
- cloudflare-worker/utils.ts来源核查 2026-09-07