- 后端
- 前端
- CRM
- 人工智能
- AI Agent
【免费下载链接】crm
Comp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.
在 Comp AI CRM(Agentic-first 开源 CRM)这类基于 Next.js/React 的前端工程中,localStorage是承载用户偏好、主题、缓存数据的最常用浏览器存储手段,但也是最容易被滥用的全局状态之一。本指南以仓库内 Vercel React Best Practices 技能中的client-localstorage-schema规则为核心,讲解如何通过版本化 Key、try-catch 防护、最小字段存储三件套,构建可演进、可迁移、不易泄漏敏感数据的前端存储层;读完你将直接获得一套可复制到项目中的本地存储读写工具与 v1→v2 数据迁移模板。
规则出处:它在整个技能体系中的位置
本主题来源于仓库内置技能 vercel-react-best-practices 的规则文件 client-localstorage-schema.md。该技能由 Vercel 工程团队维护,共含 70 条规则、8 大分类,按影响优先级排序(见 SKILL.md 与 _sections.md):
| 优先级 | 分类 | 影响级别 | 前缀 |
|---|---|---|---|
| 4 | Client-Side Data Fetching(客户端数据获取) | MEDIUM-HIGH | client- |
| 7 | JavaScript Performance(JS 性能) | LOW-MEDIUM | js- |
本规则属于第 4 类「客户端数据获取」,在该技能编译文档 AGENTS.md 中编号为4.4 Version and Minimize localStorage Data,影响级别为MEDIUM,官方影响描述为 "prevents schema conflicts, reduces storage size"(防止 schema 冲突、降低存储体积)。
规则文件采用统一的 frontmatter + 正反例模板结构(参考 _template.md),核心主张一句话概括:
给 localStorage 的 Key 加版本前缀,且只存 UI 真正需要的字段。这能防止 schema 冲突、减小存储体积,并避免意外存储 token、PII 与内部标志位。
反模式:无版本、无错误处理的全量存储
先看规则明确指出的问题代码——它几乎是新手最常见写法:
// No version, stores everything, no error handling localStorage.setItem('userConfig', JSON.stringify(fullUserObject)) const data = localStorage.getItem('userConfig')这段代码存在三个隐患:
- 无版本信息:当配置结构(schema)随产品迭代变化时,旧数据与新代码解析逻辑不匹配,轻则丢失字段、重则
JSON.parse直接抛错导致页面崩溃; - 全量存储:把 20+ 字段的完整用户对象整包塞进
localStorage,其中往往混有 token、内部标志位等不应落地的数据; - 无 try-catch:一旦
setItem/getItem抛异常(隐私模式、配额超限、存储被禁用),异常会冒泡到调用链,可能中断整个初始化流程。
正确姿势一:Key 版本化 + try-catch 读写封装
规则给出的正例是一个VERSION常量 + 读写函数封装:
const VERSION = 'v2' function saveConfig(config: { theme: string; language: string }) { try { localStorage.setItem(`userConfig:${VERSION}`, JSON.stringify(config)) } catch { // Throws in incognito/private browsing, quota exceeded, or disabled } } function loadConfig() { try { const data = localStorage.getItem(`userConfig:${VERSION}`) return data ? JSON.parse(data) : null } catch { return null } }要点拆解:
- Key 采用
userConfig:v2命名空间 + 版本后缀:不同版本的同一份数据互不覆盖、可共存,为迁移留出余地; setItem的异常场景:Safari/Firefox 等浏览器的无痕/隐私模式会直接抛异常;存储配额(通常约 5MB,但 Safari 旧版仅约 2.5MB)超限时同样抛错;用户关闭站点数据时也会失败。规则原文特别强调:"Always wrap in try-catch:getItem()andsetItem()throw in incognito/private browsing (Safari, Firefox), when quota exceeded, or when disabled."——读写两侧都必须包裹;getItem的防御:返回null表示无数据,JSON.parse失败(数据损坏或 schema 不兼容)时也回退为null,保证读取永不抛错;- 返回值约定:
loadConfig()返回T | null,调用方据此做默认值兜底,这是"降级优先"的健壮设计。
正确姿势二:v1→v2 数据迁移模式
版本化带来的直接收益是可安全迁移。当配置结构从 v1 演进到 v2 时,规则给出了一段标准的迁移函数:
// Migration from v1 to v2 function migrate() { try { const v1 = localStorage.getItem('userConfig:v1') if (v1) { const old = JSON.parse(v1) saveConfig({ theme: old.darkMode ? 'dark' : 'light', language: old.lang }) localStorage.removeItem('userConfig:v1') } } catch {} }这段迁移代码的价值在于:
- 幂等可重复执行:迁移函数可在应用启动时无条件调用——若 v1 已迁移则
getItem('userConfig:v1')返回null,直接跳过,不会重复写入; - 就地转换字段:v1 的
darkMode: boolean语义升级为 v2 的theme: 'dark' | 'light',通过old.darkMode ? 'dark' : 'light'完成布尔值到枚举值的映射; - 迁移后清理旧 Key:
removeItem('userConfig:v1')避免旧数据长期残留在用户设备上,既省配额又避免隐私残留; - 整体包裹 try-catch:迁移失败不应阻塞应用启动,静默降级即可。
在实际项目中,建议在应用初始化处按顺序执行:migrate()→loadConfig(),保证任何用户(含老版本遗留数据)都能平滑升级到最新 schema,这正是"Schema evolution via versioning(通过版本化实现 schema 演进)"的落地形态。
正确姿势三:只存 UI 需要的最小字段
规则强调,从服务器响应中缓存数据时,只挑选界面渲染真正需要的字段,而不是整包存储:
// User object has 20+ fields, only store what UI needs function cachePrefs(user: FullUser) { try { localStorage.setItem('prefs:v1', JSON.stringify({ theme: user.preferences.theme, notifications: user.preferences.notifications })) } catch {} }FullUser可能有 20+ 字段,但本地缓存只需其中的偏好子集。这样做的三重收益:
- 降低存储体积:
localStorage按字符串存储,全量对象序列化会显著占用配额;最小化后读写更快、更省空间; - 防止敏感数据落地:token、会话凭证、内部标志位、审计信息等一旦写入
localStorage,就暴露在 XSS 可触及的范围内(任何注入脚本都能读取);只挑白名单字段天然隔离了风险面; - 降低 schema 耦合:缓存结构只依赖 UI 需要的字段子集,服务端字段增减不会直接破坏客户端缓存。
配套规则:缓存 Storage 读取,避免同步 I/O
localStorage的getItem/setItem是同步且昂贵的操作,每次调用都会触发磁盘 I/O。同技能中编号7.5 Cache Storage API Calls(见 js-cache-storage.md)的规则与本文主题直接配套,影响级别 LOW-MEDIUM,主张"在内存中缓存读取结果":
const storageCache = new Map<string, string | null>() function getLocalStorage(key: string) { if (!storageCache.has(key)) { storageCache.set(key, localStorage.getItem(key)) } return storageCache.get(key) } function setLocalStorage(key: string, value: string) { localStorage.setItem(key, value) storageCache.set(key, value) // keep cache in sync }配套实践的关键点:
- 用 Map(而非 Hook)实现:规则原文强调 "Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components"——普通工具函数、事件处理器中同样可用,不受 React 组件上下文限制;
- 写路径同步更新缓存:
setLocalStorage在写入存储的同时更新内存 Map,保证读写一致性; - 外部变更需失效缓存:跨标签页修改或服务端写入 cookie 时,应监听
storage事件与visibilitychange使缓存失效:
window.addEventListener('storage', (e) => { if (e.key) storageCache.delete(e.key) }) document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { storageCache.clear() } })将本规则(4.4 版本化 + 最小化)与 7.5(读取缓存)组合,即可得到完整的客户端存储最佳实践:版本化 Key 保 schema 演进,最小字段防泄漏,Map 缓存降 I/O。
同一技能中的协同规则
在client-分类下,本文规则还与 client-swr-dedup.md(4.x Use SWR for Automatic Deduplication)形成互补:SWR 负责网络请求层面的去重与缓存,localStorage 负责本地持久化层面的版本管理——一个管"网络往返",一个管"本地落地",共同构成客户端数据层的完整治理。
收益与落地清单
规则文件结尾给出的收益总结(Benefits)可作为验收标准:
- Schema evolution via versioning:通过
key:vN版本机制支持数据结构的渐进演进与平滑迁移; - Reduced storage size:只存最小字段集,控制配额占用,降低同步 I/O 开销;
- Prevents storing tokens/PII/internal flags:白名单化存储,从源头杜绝敏感数据写入浏览器可读的存储区。
落地到 Comp AI CRM 前端(apps/app目录下的 Next.js 应用)时,可按以下清单自查:
- 所有
localStorage.setItem的 Key 是否带:vN版本后缀? - 读写是否都包裹在 try-catch 中,能否在隐私模式/配额满时静默降级?
- 是否只序列化了 UI 必需的字段子集,而不是整包服务端对象?
- 是否存在旧版本 Key 的迁移函数,并在启动时幂等执行?
- 频繁读取的 Key 是否经过内存 Map 缓存,并监听
storage事件保持同步?
这五条即是对 client-localstorage-schema.md 规则及其配套规则 js-cache-storage.md 的完整工程化落地。
- 后端
- 前端
- CRM
- 人工智能
- AI Agent
【免费下载链接】crm
Comp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.
相关推荐
Polar 前端实践:localStorage 数据版本化与最小化存储指南
Polar 前端实践:localStorage 数据版本化与最小化存储指南 本指南围绕 Polar 仓库前端工程规范中的 client localstorage
后端前端金融科技Langfuse 前端实践:localStorage 数据的版本化与最小化存储指南
Langfuse 前端实践:localStorage 数据的版本化与最小化存储指南 导读 localStorage 是前端持久化用户偏好的首选方案,但无版本、无
人工智能LLMOps可观测性AI 评测LLM 网关后端前端Agent Substrate microVM沙箱实战:Kata Containers + Cloud Hypervisor完整指南
Agent Substrate microVM沙箱实战:Kata Containers + Cloud Hypervisor完整指南 Agent Substra
人工智能AI AgentAgent 沙箱云原生容器运行时零信任
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考