103 个工具只用了 2 个布局组件:UtlKit 架构设计

17 阅读3分钟

103 个工具只用了 2 个布局组件:UtlKit 架构设计

📚 本文是 UtlKit 技术系列第 2 篇系列索引 →


103 个工具,但不需要 103 套 UI。好的架构设计让开发效率翻倍。

整体架构

项目整体架构图

architecture.png

目录结构

src/
├── app/
│   ├── layout.tsx          # 根布局:Sentry、字体、主题
│   ├── page.tsx            # 首页:分类标签 + 工具网格
│   ├── page.client.tsx     # 首页客户端逻辑
│   ├── tools/
│   │   ├── json-formatter/
│   │   │   ├── page.tsx      # 页面 + SEO metadata
│   │   │   └── formatter.tsx # 工具核心逻辑
│   │   ├── hash-generator/
│   │   ├── base64/
│   │   └── ... (共 103 个)
│   ├── about/page.tsx
│   ├── contact/page.tsx
│   ├── privacy/page.tsx
│   └── terms/page.tsx
├── components/
│   ├── ConverterLayout.tsx  # 转换类工具共享布局
│   ├── ToolSection.tsx      # 计算器类工具共享布局
│   ├── Header.tsx           # 顶栏:导航 + 搜索 + 语言 + 主题
│   ├── Footer.tsx
│   ├── Breadcrumbs.tsx
│   ├── ThemeProvider.tsx
│   └── AdSlot.tsx
├── lib/
│   ├── tools.ts             # 工具元数据(103 个工具的 name/icon/category)
│   ├── i18n/
│   │   ├── en.ts            # 英文翻译 ~2200 行
│   │   └── zh-CN.ts         # 中文翻译 ~2200 行
│   ├── md5.ts               # 纯 JS MD5 实现
│   ├── sentry-release.ts
│   └── tool-seo.ts
└── styles/
    └── globals.css          # Tailwind + CSS 自定义属性

组件抽象:80% 的工具共享布局

103 个工具抽象为两类核心布局:

1. ConverterLayout — 输入→处理→输出型

JSON 格式化、Base64、Hash 等工具都用这个布局:

┌─────────────────────────────────┐
│  输入区         │  输出区        │
│  textareatextarea     │
│                 │               │
│  [转换按钮][复制按钮]    │
└─────────────────────────────────┘

2. ToolSection — 表单→计算→结果型

BMI、复利、贷款等计算器类工具:

┌────────────────────────┐
│  [输入项1]              │
│  [输入项2]              │
│  [输入项3]              │
│                        │
│  [计算按钮]             │
│                        │
│  ─── 结果 ───          │
│  结果展示区             │
└────────────────────────┘

通过这两个共享布局 + 少量自定义逻辑,103 个工具的开发效率大幅提高。每个工具只需要写核心转换逻辑,UI 统一由布局组件处理。

浏览器内运行的取舍

最大的取舍:不能用 Node.js 生态

Node.js 有成熟的格式化/压缩库,但浏览器里没有 fsnetchild_process

想要的库依赖 Node.js替代方案
terser (JS 压缩)fs自写正则压缩
html-minifier-terserfs自写正则压缩
xml-formatter minify⚠️ ESM/CJS自写正则压缩
js-beautify (格式化)❌ 支持浏览器✅ 直接用
csso (CSS 压缩)❌ 纯 JS✅ 直接用

结论:格式化用现成库,压缩用自写正则。

详细分析见系列第 5 篇 → Node.js 库在浏览器里跑不了的教训

加密:Web Crypto API 的限制

浏览器原生支持 SHA-256/384/512、AES-GCM、HMAC,但不支持 MD5

MD5 已经被证明不安全,但实际使用场景仍然大量存在(文件校验、旧系统兼容等)。

解决方案:自己实现 MD5(约 100 行纯 JS,bitwise operations)。

详细分析见系列第 7 篇 → Web Crypto API 实现浏览器端加密

i18n:中英文双语的设计

src/lib/i18n/
├── en.ts       (2208 行)
└── zh-CN.ts    (2207 行)

使用方式:

const { t } = useI18n()
<button>{t('btn.copy')}</button>  // "Copy" / "复制"

关键设计决策:

  • 不用 next-intl — 静态导出模式下 SSR 安全有问题
  • localStorage + Context — 简单、可控
  • 所有页面 title 双语 — SEO 对中英文都友好
  • 工具 name 也有双语 — 搜索、面包屑、sitemap

从 0 到 1 到 100

这两篇文章覆盖了"从 0 到 1"的设计和选型。后续文章记录的是"从 1 到 100"过程中踩的坑:

篇目标题核心问题
1React 19 静态导出报 Hydration MismatchSSR/CSR 不一致
2Cloudflare Pages 白页:index.txt 的坑content negotiation 机制
3Node.js 库在浏览器跑不了fs 依赖、ESM/CJS 互操作
4Sentry Source Map 从 0% 到完整解析tree-shake、HTTP API、区域检测
5Web Crypto API 做客户端加密MD5 缺失、AES-GCM、HMAC
6免费性能监控:PageSpeed CI0 成本持续监控 Core Web Vitals
7Cloudflare 缓存命中率 7%→90%3 条 Cache Rules + 本地化优化
8暗色模式完美切换三层优先级策略
9多语言站点的 6 个坑[locale] 路径前缀方案

📚 本文是 UtlKit 技术系列第 2 篇系列索引 →


项目信息

  • 网站: utlkit.com
  • 技术栈: Next.js 15 + React 18 + TypeScript + Tailwind CSS
  • 部署: Cloudflare Pages
  • 工具数: 103 个,8 个分类
  • 成本: ¥0/月

如果觉得有帮助,欢迎关注系列更新。有建设性意见欢迎评论。