1. 项目背景与核心价值
作为一名长期活跃在开发者社区的独立开发者,我经常遇到这样的困境:想要快速完成某个小功能,却需要反复搜索各种零散工具,或者为了简单需求搭建复杂环境。这种低效的体验促使我萌生了打造一个"一站式工具网站"的想法——把日常开发中最常用的那些小而美的功能整合起来,让每个工具都像瑞士军刀上的组件一样即开即用。
这个工具站的核心定位是解决开发者80%的日常碎片化需求:比如代码格式化、JSON解析、正则测试、时间戳转换等高频场景。不同于那些大而全的臃肿平台,我刻意保持每个工具的极简主义设计,确保三步之内必达核心功能。举个例子,当你在调试API时突然需要解析一段混乱的JSON,不用再打开新标签页搜索在线解析器,直接在我的工具站一键美化,连缩进都帮你自动对齐。
2. 技术架构与关键设计
2.1 前端技术选型
采用Vue3 + TypeScript的组合拳,搭配Naive UI组件库实现清爽的界面。特别值得分享的是动态加载方案:通过Webpack的魔法注释实现路由级代码分割(() => import(/* webpackChunkName: "json-tools" */ './views/JsonTools.vue')),使得整个站点即使包含20+工具,首屏加载仍能控制在1秒内。以下是核心配置示例:
// vite.config.js export default defineConfig({ build: { rollupOptions: { output: { manualChunks(id) { if (id.includes('node_modules')) { return 'vendor' } if (id.includes('tools/')) { return id.split('tools/')[1].split('/')[0] } } } } } })2.2 状态管理优化
为了避免Vuex在多工具场景下的状态污染,我为每个工具模块设计了独立的Pinia store。比如时间戳转换工具的状态管理这样实现:
// stores/timestamp.ts export const useTimestampStore = defineStore('timestamp', { state: () => ({ input: '', format: 'YYYY-MM-DD HH:mm:ss', result: '' }), actions: { convert() { try { this.result = dayjs(this.input).format(this.format) } catch (e) { this.result = 'Invalid timestamp' } } } })3. 特色功能实现细节
3.1 智能粘贴板增强
开发中最烦人的就是不同工具间的数据传递。我在所有输入框都实现了智能粘贴检测:
- 自动识别JSON/XML内容并高亮语法
- 识别到URL时询问是否要发起请求
- 时间戳自动转换本地时区
关键实现逻辑:
const detectContentType = (text) => { if (/^{.*}$/.test(text.trim()) || /^\[.*\]$/.test(text.trim())) { return 'json' } if (/^<[a-z]+>.*<\/[a-z]+>$/i.test(text.trim())) { return 'xml' } if (/^\d{10,13}$/.test(text)) { return 'timestamp' } return 'text' }3.2 零配置工具联动
当用户在JSON工具中格式化数据后,可以直接点击"转Base64"按钮跳转到编码工具,且数据会自动传递过去。这是通过URL hash实现的轻量级状态共享:
// 在工具A中设置跳转 const shareToToolB = () => { const encoded = btoa(JSON.stringify(data)) router.push(`/tool-b#payload=${encoded}`) } // 在工具B中获取 onMounted(() => { if (location.hash.includes('payload=')) { const payload = location.hash.split('=')[1] input.value = JSON.parse(atob(payload)) } })4. 性能优化实战记录
4.1 工具冷启动加速
通过预加载策略提升用户体验:
- 首页加载时通过
<link rel="prefetch">预加载前3个热门工具 - 鼠标悬停在导航菜单时预加载对应工具包
- 对超过50KB的依赖(如monaco-editor)启用Web Worker加载
实测数据:
| 优化前 | 优化后 |
|---|---|
| 首屏2.1s | 首屏0.8s |
| 工具切换1.4s | 工具切换0.3s |
4.2 内存管理技巧
由于包含代码编辑器等重型组件,内存泄漏是常见问题。我的解决方案是:
- 为每个工具组件实现
deactivate生命周期钩子 - 使用WeakMap存储临时状态
- 对monaco-editor等组件强制在路由离开时执行dispose()
onBeforeUnmount(() => { if (editor) { editor.dispose() editor = null } clearAllIntervals() // 清理所有可能存在的定时器 })5. 开发者专属功能设计
5.1 命令行模式
为重度键盘用户设计了全局快捷键:
- Ctrl+K 打开命令面板
- /json 直接跳转到JSON工具
- /ts 进入时间戳转换 实现原理是监听document的keydown事件:
const COMMANDS = { '/json': '/tools/json', '/ts': '/tools/timestamp' } document.addEventListener('keydown', (e) => { if (e.ctrlKey && e.key === 'k') { openCommandPalette() } else if (e.key === '/' && !e.target.matches('input, textarea')) { startCommandInput() } })5.2 私有化部署方案
很多团队希望内网部署,我提供了两种方案:
- Docker一键部署(含nginx配置)
FROM node:16 WORKDIR /app COPY . . RUN npm install && npm run build EXPOSE 3000 CMD ["npx", "serve", "-s", "dist"] - 静态导出模式(通过
npm run generate输出纯HTML版本)
6. 踩坑经验与解决方案
6.1 剪贴板权限问题
现代浏览器对clipboardAPI的限制越来越严格,我的渐进式解决方案:
- 优先使用navigator.clipboard(需要HTTPS)
- 降级到document.execCommand('copy')
- 终极方案:显示"点击复制"按钮并自动选中文本
const safeCopy = async (text) => { try { await navigator.clipboard.writeText(text) } catch (err) { const textarea = document.createElement('textarea') textarea.value = text document.body.appendChild(textarea) textarea.select() document.execCommand('copy') document.body.removeChild(textarea) } }6.2 移动端适配陷阱
工具类网站往往忽视移动端,我总结的必做事项:
- 禁用iOS的自动缩放:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> - 输入框防遮挡方案:
const adjustViewport = () => { if ('visualViewport' in window) { window.visualViewport.addEventListener('resize', () => { document.activeElement.scrollIntoView({ block: 'center' }) }) } } - 避免300ms点击延迟:
<meta name="viewport" content="width=device-width">
7. 数据统计与持续迭代
通过自定义埋点收集工具使用情况(注意GDPR合规):
const track = (event, payload = {}) => { if (process.env.NODE_ENV === 'production') { navigator.sendBeacon('/api/event', JSON.stringify({ event, payload, ua: navigator.userAgent, path: location.pathname })) } }根据数据反馈发现两个有趣现象:
- 下午3-5点是JSON工具使用高峰(推测与API调试时段相关)
- 正则测试工具60%用户会重复使用3次以上
基于这些发现,我为高频工具增加了"历史记录"功能,使用indexedDB本地存储最近5次操作。
8. 安全防护实践
即使静态网站也需要基础防护:
- CSP策略:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' cdn.example.com; style-src 'self' 'unsafe-inline'"> - 对编码类工具做输入过滤:
const sanitize = (str) => { return str.replace(/[^\w\s-]/g, '').substring(0, 1000) } - 定期使用Snyk检查依赖漏洞
9. 未来扩展方向
目前正在实验两个新特性:
- 工具插件系统:允许用户通过npm包形式贡献自定义工具
// my-tool-plugin.js export default { name: 'My Cool Tool', icon: '⚡', component: defineAsyncComponent(() => import('./Tool.vue')) } - Figma插件集成:设计稿中的测量数据可直接发送到网站工具处理
这个项目的魅力在于它永远有改进空间——每次我自己使用时发现不便之处,就是下一个迭代的起点。最近在考虑加入AI辅助功能,比如让ChatGPT帮忙编写正则表达式,但前提是必须保持现有工具的极简气质。毕竟,好的工具应该像空气一样,使用时感受不到存在,缺了它却寸步难行。