公司动态

AmplifyJS 源码解析:amplify.store 特性检测与 JSON 序列化设计

📅 2026/8/19 18:05:12
AmplifyJS 源码解析:amplify.store 特性检测与 JSON 序列化设计
AmplifyJS 源码解析amplify.store 特性检测与 JSON 序列化设计【免费下载链接】amplifyAmplifyJS项目地址: https://gitcode.com/gh_mirrors/amp/amplifyAmplifyJS 是一套专注数据管理与应用通信的轻量 JavaScript 组件库其中 amplify.store 是最实用的模块之一它用一条统一的 API 完成客户端持久化存储。本文从源码角度解析 amplify.store 的特性检测机制与 JSON 序列化设计看看它如何在从 IE 5 到现代浏览器的环境中自动选出最佳存储方案又如何把复杂对象安全地塞进只能存字符串的浏览器存储中。amplify.store 是什么一条 API 搞定浏览器存储 AmplifyJS 的设计理念是让开发者专注业务而不是纠结兼容性。amplify.store 正是这一理念的典型代表支持 IE 5、Firefox 2、Safari 4、Chrome、Opera 10.5 等横跨十余年的浏览器无论底层是 localStorage、sessionStorage还是老旧的 userData你都只需要记住同一组 API存、取、删、批量导出全部由一个入口完成看一个最常用的用法摘自项目自带示例// 存一个对象amplify 自动挑选最合适的存储技术 amplify.store( storeExample1, { foo: bar } ); // 按 key 取回自动反序列化 var value amplify.store( storeExample1 ); value.foo; // bar // 不传 key一次性导出所有数据 var all amplify.store();这段代码来自 demo/store/implicit/demo.js完整的 API 说明见官方文档 docs/amplify.store.md。源码架构从统一入口到多存储后端 ️打开 src/store.js你会发现 amplify.store 本身只是一个路由器它维护一张存储类型注册表store.types每次调用根据options.type或默认类型把请求转交给对应的后端store.addType()负责注册新类型并自动生成amplify.store.xxx()这样的快捷方法src/store.js#L13-L24这种插件式架构让扩展新存储后端变得非常简单——项目内置的五个存储类型全部都是通过 addType 注册进来的。特性检测设计自动挑选最优存储方案 五种存储类型的探测顺序amplify.store 能通吃所有浏览器靠的不是一堆if (isIE)式的浏览器嗅探而是特性检测。它按照越先进越优先的顺序依次探测顺序存储类型适用浏览器1localStorageIE 8、Firefox 3.5、Chrome、Safari 4 等2sessionStorage同上会话级存储3globalStorageFirefox 2/3 时代的过渡方案4userDataIE 5-7 的专属方案5memory内存兜底保证 API 永远可用第一个探测成功的类型会自动成为amplify.store()的默认存储后端。探测技巧写入再删除的试运行特性检测最精妙的部分在 src/store.js#L105-L115。单纯检查window.localStorage是否存在远远不够因为 Safari 5 的隐私浏览模式会伪装支持 localStorage但实际写入必然失败。所以源码采用了写入-删除实测法先尝试写入一个测试项再立即删除它两步都成功才判定该存储真正可用整个过程包裹在 try/catch 中同时兼顾了 file:// 协议下 Firefox 的异常行为。任何一步报错都会静默跳过继续探测下一个类型绝不打扰用户。特性检测失败时的优雅降级探测失败的场景同样处理得细腻只有 localStorage 不可用时才回退到 Firefox 专用的 globalStorage并贴心地把默认类型从 sessionStorage纠正为 globalStoragesrc/store.js#L120-L132userData 无法轻易探测源码干脆真刀真枪地添加 behavior 并尝试加载数据失败即放弃src/store.js#L137-L161最后还有内存存储 memory 兜底保证任何环境下 API 都不会抛错src/store.js#L250-L287这种层层递进、步步降级的思路正是特性检测设计的核心价值所在。JSON 序列化设计把对象安全存进浏览器 localStorage 只能存字符串Web Storage 有一个天然局限value 只能是字符串。如果直接localStorage.setItem(key, { foo: bar })存进去的会是[object Object]。所以 amplify.store 必须自己负责序列化与反序列化。{ data, expires } 包装格式看看 src/store.js#L80-L83 的写入逻辑amplify.store 并没有简单地把数据 stringify 后存进去而是额外包了一层parsed JSON.stringify({ data: value, // 你的原始数据 expires: options.expires ? now options.expires : null });这个设计一举两得用 JSON 序列化对象、数组、字符串都能存取天然支持复杂数据结构顺带实现了 expires 过期时间——读取时对比当前时间与 expires过期数据立即删除src/store.js#L70-L75命名空间前缀与防冲突设计为了防止与直接操作存储的第三方代码冲突所有 key 都会加上__amplify__前缀src/store.js#L29、src/store.js#L66。遍历整个存储时也只导出带前缀、由 amplify 管理的数据。此外源码还专门绕过了 Firefox 4.0 的一个 localStorage 遍历 bugsrc/store.js#L41-L46细节之处足见功力。userData 的 XML 名称清洗IE 5-7 的 userData 更加特殊key 必须是合法的 XML 名称。于是源码用一段正则把所有非法字符替换成短横线src/store.js#L192-L194。这也解释了官方文档中提到的userData 的 key 无法完全保真这一已知问题。配额超限先清理再重试 ⚠️localStorage 的容量通常只有 5MB 左右写满时 setItem 会抛异常。amplify.store 的处理策略非常实用src/store.js#L84-L95捕获写入异常先执行一次清扫——遍历并删除所有已过期的数据再尝试写入一次若仍然失败抛出 amplify.store quota exceeded 错误userData 后端还多了一层回滚保护失败时先把属性恢复为原值避免留下半截脏数据src/store.js#L218-L243。总结这份源码值得你精读 ✅特性检测而非浏览器嗅探是 amplify.store 跨浏览器兼容的核心思路JSON 序列化 包装格式让对象存取与过期时间成为标配能力插件式注册架构让自定义存储后端变得轻而易举配额超限的清理重试与userData 的回滚保护展示了成熟库对边界情况的重视如果你正在设计自己的存储封装src/store.js 这份源码非常值得逐行研读想快速上手用法可以看 demo/store/implicit/demo.js 与 demo/store/sessionstorage/demo.js 两个示例完整的单元测试则集中在 test/store/unit.js。【免费下载链接】amplifyAmplifyJS项目地址: https://gitcode.com/gh_mirrors/amp/amplify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考