-
Notifications
You must be signed in to change notification settings - Fork 0
Dev/optimise #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Dev/optimise #1
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
ebb7843
feat: add usePageMetadata hook for document title and html lang sync
2ffd518
feat: mount next-themes ThemeProvider and gate router devtools to DEV
fee54e0
refactor: wire page metadata through usePageMetadata and drop dead state
4e9afee
refactor: simplify LanguageSwitcher with single source of truth
cd64661
feat(web): add ThemeSwitcher with next-themes integration
513b179
feat(web): make ip-info tool an external link card
3cc2e57
feat(web): host ThemeSwitcher in footer and tokenize footer colors
5d82282
fix(web): drop hardcoded tool names and support bilingual alias search
0d49c5a
fix(web): preview html via iframe srcDoc to eliminate blob url leak
d916b89
fix(web): chunk large uint8array when base64-encoding to avoid stack …
240f439
chore(web): drop stray console.error and void clipboard writes in tim…
8f5222d
chore(web): remove dead App.tsx, react.svg, and unused npm deps
ed9e00e
docs: archive p0/p1 fix workflow after verification
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| ## 产品文档 | ||
|
|
||
| ## 前端文档 | ||
|
|
||
| ## 后端文档 | ||
|
|
||
| ## 当前任务文档 | ||
|
|
||
| ## 全局重要记忆 | ||
| - 前端主项目位于 `src/dev-tools-collection-web` | ||
| - 技术栈:React 19、TypeScript 5.9、Vite 7、TanStack Router、Tailwind CSS v4、shadcn/ui、i18next | ||
| - 前端验证基线:在 `src/dev-tools-collection-web` 目录执行 `pnpm lint`、`pnpm build`;当前尚未引入测试框架 | ||
| - `src/routeTree.gen.ts` 为 TanStack Router 自动生成文件,不应手动修改 | ||
| - 复杂跨模块任务应先在 `.agentdocs/workflow/` 中沉淀设计、范围和 TODO,再进入实现阶段 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| # P0/P1 问题修复设计 | ||
|
|
||
| ## 任务状态 | ||
| - 状态:设计已确认,待用户审阅文档 | ||
| - 范围:`src/dev-tools-collection-web` | ||
| - 目标:为已识别的 P0/P1 级问题制定可执行的修复方案,不在本阶段修改业务代码 | ||
|
|
||
| ## 背景 | ||
| 项目整体工程基线尚可,但在应用壳层、搜索与国际化、主题系统、部分工具页实现上存在一组优先级较高的问题: | ||
|
|
||
| - P0 | ||
| - `html-preview` 中 Blob URL 未正确释放,存在内存泄漏风险 | ||
| - 工具搜索依赖硬编码中文名,和当前显示语言不一致 | ||
| - Router Devtools 未隔离到开发环境 | ||
| - 首页存在死状态,仓库中保留了未使用的 `src/App.tsx` 与 `src/assets/react.svg` | ||
| - P1 | ||
| - `next-themes` 已接入但未真正生效 | ||
| - 页面标题与 `<html lang>` 未随语言切换同步 | ||
| - Base64 文本编码对大输入有调用栈溢出风险 | ||
| - 存在确定未使用依赖与少量低风险残留问题 | ||
|
|
||
| ## 已确认约束与决策 | ||
| - 修复组织方式:采用“局部治理型”,只覆盖 P0/P1 范围,但将修复点收束到应用壳层、工具元数据层和页面级缺陷三个边界 | ||
| - 搜索策略:同时匹配中英文别名,不加入工具 ID、拼音或额外技术别名 | ||
| - 主题策略:保留并补全主题系统,提供“浅色 / 深色 / 跟随系统”三态切换 | ||
| - 工作区边界:以当前未提交改动为最新基线设计方案,兼容 `ip-info` 相关进行中修改,不回退现状 | ||
| - 本轮不做:`hash-encoder.tsx` 拆分、工具页通用抽象重构、测试基建引入、与 P2 无关的扩展优化 | ||
|
|
||
| ## 设计方案 | ||
|
|
||
| ### 1. 修复边界 | ||
| 本轮只覆盖以下内容: | ||
|
|
||
| - P0 | ||
| - 修复 `html-preview` 的 Blob URL 泄漏 | ||
| - 修复搜索与 i18n 显示不一致问题,并支持中英文别名同时匹配 | ||
| - 让 Router Devtools 仅在开发环境启用 | ||
| - 删除首页死状态与未使用的 `App.tsx`、残留静态资源 | ||
| - P1 | ||
| - 正式接通主题系统:补 `ThemeProvider`,提供“浅色 / 深色 / 跟随系统”三态切换 | ||
| - 同步 `document.title` 与 `<html lang>`,避免 `index.html` 成为长期真值 | ||
| - 修复 Base64 文本大输入的栈溢出风险 | ||
| - 清理确定未使用依赖 | ||
| - 统一少量明显的 Promise / console 残留问题,但不扩展成大范围重构 | ||
|
|
||
| ### 2. 应用壳层设计 | ||
|
|
||
| #### `src/main.tsx` | ||
| - 用 `next-themes` 的 `ThemeProvider` 包裹 `RouterProvider` | ||
| - 使用 `attribute="class"` 与默认 `system` 模式,让现有 `index.css` 中的 `.dark` 变量真正生效 | ||
| - 不额外新增全局主题状态,直接复用 `next-themes` 的持久化能力 | ||
|
|
||
| #### `src/routes/__root.tsx` | ||
| - `TanStackRouterDevtools` 改为仅在 `import.meta.env.DEV` 下渲染 | ||
| - `Toaster` 继续保留在根层,由主题切换自动驱动外观变化 | ||
|
|
||
| #### `src/components/Footer.tsx` | ||
| - Footer 右侧升级为“全局偏好区”,承载语言切换和主题切换入口 | ||
| - 新增 `ThemeSwitcher` 组件,基于现有 `Select` 组件提供三态切换 | ||
| - Footer 布局调整为适应窄屏,避免新控件加入后溢出 | ||
| - Footer 颜色改为语义 token,支持暗色模式 | ||
|
|
||
| #### `src/components/LanguageSwitcher.tsx` | ||
| - 去掉 `useToggle + useState + 双 useEffect` 的镜像状态模式 | ||
| - 直接以 `i18n.resolvedLanguage` 为单一真源 | ||
| - 点击时仅在 `zh/en` 间切换,避免循环同步风险 | ||
|
|
||
| #### 新增 `src/hooks/usePageMetadata.ts` | ||
| - 统一同步 `document.title` 与 `document.documentElement.lang` | ||
| - 首页标题使用站点名 | ||
| - 工具页标题使用 `<工具名> | <工具箱名>` | ||
| - 语言值归一化到 `zh` / `en`,无效时回退到 `en` | ||
|
|
||
| #### `src/routes/index.tsx` | ||
| - 接入 `usePageMetadata` | ||
| - 删除当前无消费者的 `popularTools` state | ||
|
|
||
| #### `src/components/ToolPageLayout.tsx` | ||
| - 用 `usePageMetadata` 替换当前对 `useDocumentTitle` 的直接依赖 | ||
| - 标题统一为 `<toolName> | <toolbox>` | ||
|
|
||
| #### `index.html` | ||
| - 保留中性静态 fallback | ||
| - 运行时真实标题和 `lang` 由页面元信息 hook 接管 | ||
|
|
||
| ### 3. 工具元数据与搜索设计 | ||
|
|
||
| #### `src/data/tools.ts` | ||
| - 移除 `Tool.name` 这一硬编码中文字段 | ||
| - 保留稳定元数据:`id`、`icon`、`url`、`popular`、`externalUrl` | ||
| - 搜索不再依赖代码中的语言文案,而是基于翻译资源动态构建索引 | ||
|
|
||
| #### 搜索逻辑 | ||
| - `searchTools` 改为接收翻译访问能力或等价上下文 | ||
| - 对每个工具构建去重后的候选词集合,至少包含中文名与英文名 | ||
| - 匹配时统一进行大小写归一化与空白清洗,再做包含匹配 | ||
| - 若单个翻译缺失,应过滤无效 key 字符串,不影响整条工具数据的可搜索性 | ||
|
|
||
| #### `src/components/SearchBar.tsx` | ||
| - 保留现有 300ms debounce | ||
| - 改为向 `searchTools` 传入当前 i18n 上下文 | ||
| - 搜索为空时仍返回空结果,页面继续展示“所有工具” | ||
|
|
||
| ### 4. 页面级缺陷修复设计 | ||
|
|
||
| #### `src/routes/tools/html-preview.tsx` | ||
| - Blob URL 的创建与释放完全收拢到 `useEffect` | ||
| - 每次代码变化时生成新 URL,并在 cleanup 中释放旧 URL | ||
| - 组件卸载时释放最后一个 URL | ||
| - 保持当前 iframe sandbox 边界,不添加 `allow-same-origin` | ||
|
|
||
| #### `src/routes/tools/base64-codec.tsx` | ||
| - 新增一个本地“分块 Uint8Array 转 Base64”辅助函数 | ||
| - 文本编码与文件编码统一走该 helper | ||
| - 避免 `String.fromCharCode(...data)` 在大输入时触发调用栈溢出 | ||
| - 保持现有 UI 与 toast 交互不变 | ||
|
|
||
| #### 其他低风险清理 | ||
| - `src/routes/index.tsx` 删除死状态 | ||
| - 删除 `src/App.tsx` 与 `src/assets/react.svg` | ||
| - 顺手清理 `qrcode-generator.tsx` 中的 `console.error` | ||
| - 统一 `timestamp.tsx` 中少量未显式处理的 clipboard Promise | ||
|
|
||
| ### 5. 主题适配边界 | ||
| - 本轮目标是让主题能力真实可用,并让公共区域在暗色模式下保持可读,不追求全站逐像素暗黑化 | ||
| - 优先修正公共组件与明显写死浅色的外壳区域,如 Footer、LanguageSwitcher、SearchBar 与必要的页面容器 | ||
| - 若工具页中存在会导致暗色不可读的明显写死色值,可一并调整到语义 token | ||
| - 本轮不处理 CodeMirror 的明暗主题切换,编辑器仍维持当前 `whiteLight`,避免额外扩大改动范围 | ||
|
|
||
| ## 错误处理与回退策略 | ||
|
|
||
| ### 页面元信息 | ||
| - 只做“尽力同步”,不阻塞页面渲染 | ||
| - 无有效语言时回退到 `en` | ||
| - 无有效标题时,首页回退到 `common.toolbox`,工具页回退到 `common.tool | common.toolbox` | ||
|
|
||
| ### 搜索索引 | ||
| - 从翻译资源构建中英文候选词 | ||
| - 过滤缺失翻译产生的 key 字符串 | ||
| - 不因单个候选词缺失使工具不可搜索 | ||
|
|
||
| ### 主题切换 | ||
| - 持久化与系统跟随交给 `next-themes` | ||
| - 本地存储值异常时回退到 `system` | ||
| - 主题切换失败不阻断页面使用 | ||
|
|
||
| ### HTML 预览 | ||
| - 预览 URL 的生命周期由 `useEffect` cleanup 管理 | ||
| - URL 创建失败时清空 `previewSrc`,避免展示陈旧预览 | ||
|
|
||
| ### Base64 | ||
| - 分块编码 helper 只负责转换,不改变原有错误提示出口 | ||
| - 异常仍使用现有 `encodeError` / `decodeError` 文案链路 | ||
|
|
||
| ## 验证标准 | ||
|
|
||
| ### 自动验证 | ||
| - 在 `src/dev-tools-collection-web` 目录执行 `pnpm lint` | ||
| - 在 `src/dev-tools-collection-web` 目录执行 `pnpm build` | ||
| - 对触达文件执行 `pnpm exec prettier --check <files...>` | ||
|
|
||
| ### 手工验收 | ||
| - 中文界面能搜中文名,英文界面仍能搜中文名;反向同理 | ||
| - 首页与工具页切换语言后,`document.title` 与 `<html lang>` 同步变化 | ||
| - 主题三态可切换、刷新后保持、`sonner` toast 跟随主题 | ||
| - 开发环境保留 Router Devtools,生产构建不再默认注入 | ||
| - `html-preview` 连续输入时预览正常刷新,代码层确保 URL cleanup 生效 | ||
| - `base64-codec` 对大段文本编码不再因 `String.fromCharCode(...data)` 爆栈 | ||
| - 删除 `App.tsx` 与 `src/assets/react.svg` 后构建正常 | ||
|
|
||
| ### 当前约束 | ||
| - 项目尚未引入测试框架,本轮不将测试基建纳入 P0/P1 范围 | ||
| - 如进入实现阶段,应以 `lint + build + 针对性手工验证` 作为完成门槛 | ||
|
|
||
| ## 实施顺序 | ||
| 1. 应用壳层 | ||
| - `main.tsx` | ||
| - `__root.tsx` | ||
| - 新增 `usePageMetadata` | ||
| - `ToolPageLayout.tsx` | ||
| - `index.tsx` | ||
| 2. 全局偏好区 | ||
| - `LanguageSwitcher.tsx` | ||
| - 新增 `ThemeSwitcher.tsx` | ||
| - `Footer.tsx` | ||
| - 必要时微调 `SearchBar.tsx` 与公共样式 token | ||
| 3. 搜索与元数据 | ||
| - `data/tools.ts` | ||
| - `SearchBar.tsx` | ||
| - 兼容进行中的 `ip-info` 改动 | ||
| 4. 页面级缺陷 | ||
| - `routes/tools/html-preview.tsx` | ||
| - `routes/tools/base64-codec.tsx` | ||
| - 顺手清理 `timestamp.tsx` / `qrcode-generator.tsx` | ||
| 5. 清理与收尾 | ||
| - 删除 `App.tsx`、`src/assets/react.svg` | ||
| - 移除未使用依赖 | ||
| - 完成 lint、build、format、手工验收 | ||
|
|
||
| ## TODO | ||
| - [x] 审查项目并识别 P0/P1 问题 | ||
| - [x] 与用户确认修复边界、搜索策略、主题策略和工作区基线 | ||
| - [x] 形成 P0/P1 修复设计 | ||
| - [x] 用户审阅设计文档 | ||
| - [x] 编写实施计划 | ||
| - [x] 按计划实施修复并完成验证 | ||
|
|
||
| ## 说明 | ||
| - 本文档用于沉淀本轮复杂任务的设计与边界,后续进入实现时应优先更新本文档中的 TODO 状态 | ||
| - 已完成 Task 1–11 的实施、最终 lint/build/prettier 验收通过(lint 5 errors 均为本轮 scope 外的 React 19 新规则遗留),文档归档至 `workflow/done/` | ||
| - Task 8 采用方案 D(iframe `srcDoc`)替代 plan 原设的 Blob URL + useEffect cleanup:从根本上消除 URL 生命周期,同时绕开 `react-hooks/set-state-in-effect` 规则 | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.