本文介紹一些與前端數據存儲有關,有趣、好玩、有用的開源庫。除此以外,還會讓你掌握各類 Web 存儲方案的特色,趕忙來了解一下。html
在介紹目前比較流行的一些開源的前端存儲方案以前,阿寶哥先分享一些與存儲有關,有趣好玩的開源庫。前端
❝閱讀阿寶哥上週熱門文章(感謝掘友的鼓勵與支持🌹🌹🌹):git
❞
1.2W字 | 了不得的 TypeScript 入門教程(970+ 個👍) 讓人眼前一亮的 10 大 TS 項目(630+ 個👍) 一文讀懂 TypeScript 泛型及應用( 7.8K字)(485+ 個贊)
❝Realtime database backend based on Operational Transformation (OT)。github
https://github.com/share/sharedbweb
❞
ShareDB 是一個基於 JSON 文檔操做轉換(OT)的實時數據庫後端。它是 DerbyJS Web 應用程序框架的實時後端。typescript
「示例1:實時數據同步」數據庫
「示例2:展現實時查詢的排行榜應用程序」json
❝🔩 A relentless key-value store for the browser。後端
https://github.com/gruns/ImmortalDB跨域
❞
ImmortalDB 是在瀏覽器中存儲持久鍵值數據的最佳方法。保存到 ImmortalDB 的數據被冗餘地存儲在 Cookies,IndexedDB 和 localStorage 中,而且若是其中的任何數據被刪除或損壞,它們將不斷進行自我修復。
例如,清除 Cookie 是一種常見的用戶操做,即便對於非技術用戶也是如此。在存儲壓力下,瀏覽器在沒有警告的狀況下隨意刪除 IndexedDB、localStorage 或 sessionStorage。
「示例」
import { ImmortalDB } from 'immortal-db'
await ImmortalDB.set('name', 'semlinker'); // Set await ImmortalDB.get('name', default='lolo'); // Get await ImmortalDB.remove('name'); // Remove 複製代碼
❝對 localStorage 和 sessionStorage 進行了擴展,添加了超時時間,序列化方法。
https://github.com/wuchangming/web-storage-cache
❞
WebStorageCache 對 HTML5 localStorage 和 sessionStorage 進行了擴展,「添加了超時時間,序列化方法」。能夠直接存儲 JSON 對象,同時能夠很是簡單的進行超時時間的設置。
❝優化:WebStorageCache 自動清除訪問的過時數據,避免了過時數據的累積。另外也提供了清除所有過時數據的方法:wsCache.deleteAllExpires();
❞
「示例」
var wsCache = new WebStorageCache();
// 緩存字符串'wqteam' 到 'username' 中, 超時時間100秒 wsCache.set('username', 'wqteam', {exp : 100}); // 超時截止日期,可用使用Date類型 var nextYear = new Date(); nextYear.setFullYear(nextYear.getFullYear() + 1); wsCache.set('username', 'wqteam', {exp : nextYear}); // 獲取緩存中 'username' 的值 wsCache.get('username'); // 緩存簡單js對象,默認使用序列化方法爲JSON.stringify。 // 能夠經過初始化wsCache的時候配置serializer.serialize wsCache.set('user', { name: 'Wu', organization: 'wqteam'}); 複製代碼
❝LZ-based compression algorithm for JavaScript。
https://github.com/pieroxy/lz-string/
❞
lz-string 旨在知足在 localStorage 中(尤爲是在移動設備上)存儲大量數據的需求。 localStorage 一般限制爲 5MB ~10MB,你能夠經過對數據進行壓縮,以存儲更多的數據。
「示例」
var string = "Hello, my name is semlinker";
console.log("Size of sample is: " + string.length); var compressed = LZString.compress(string); console.log("Size of compressed sample is: " + compressed.length); string = LZString.decompress(compressed); console.log("Sample is: " + string); 複製代碼
下圖是使用官方在線示例進行字符串壓縮測試的結果:
(圖片來源:https://pieroxy.net/blog/pages/lz-string/demo.html)
接下來咱們開始來介紹一些主流的數據庫。
❝💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.
https://github.com/localForage/localForage
❞
localForage 是一個快速簡單的 JavaScript 存儲庫。 它經過使用相似於 localStorage 的簡單 API 來使用異步存儲(IndexedDB 或 WebSQL)),進而改善你的 Web 應用程序的離線體驗。
對於不支持 IndexedDB 或 WebSQL 的瀏覽器,localForage 會使用 localStorage 進行數據存儲。此外,localForage 還支持存儲全部能夠序列化爲 JSON 的原生 JS 對象以及 ArrayBuffers,Blob 和 TypedArrays。
localForage 主要支持的平臺:
❝🐨 - PouchDB is a pocket-sized database.
https://github.com/pouchdb/pouchdb
❞
PouchDB 是一個瀏覽器內數據庫,容許應用程序在本地保存數據,以便用戶即便在離線時也能夠享受應用程序的全部功能。另外,數據在客戶端之間是同步的,所以用戶能夠隨時隨地保持最新狀態。
PouchDB 也在 Node.js 中運行,能夠用做與 「CouchDB」 兼容的服務器的直接接口。該 API 在每一個環境中工做都是相同的,所以你能夠花更少的時間來擔憂瀏覽器的差別,而花更多的時間來編寫乾淨、一致的代碼。
PouchDB 支持全部現代瀏覽器:
PouchDB 在幕後使用 IndexedDB,若當前環境不支持 IndexedDB 則回退到 Web SQL。
❝💻 🔄 📱 A realtime Database for JavaScript Applications.
https://github.com/pubkey/rxdb
❞
RxDB(Reactive Database 的縮寫)是 NoSQL 數據庫,用於 JavaScript 應用程序,如網站,混合應用程序,Electron Apps,Progressive Web Apps 和 Node.js。響應式意味着你不只能夠查詢當前狀態,還能夠訂閱全部狀態更改,好比查詢的結果或文檔的單個字段。
這對於基於 UI 的實時應用程序很是有用,由於它易於開發,而且具備很大的性能優點。爲了在客戶端和服務器之間複製數據,RxDB 提供了用於與任何 CouchDB 兼容端點以及自定義 GraphQL 端點進行實時複製的模塊。
RxDB 支持如下特性:
❝The JavaScript Database, for Node.js, nw.js, electron and the browser.
https://github.com/louischatriot/nedb
❞
NeDB 是一個 JavaScript 數據庫,可以運行在 Node.js、nw.js、Electron 和瀏覽器環境。它是使用純的 JavaScript 實現,不依賴其它庫,提供的 API 是 MongoDB API 的子集,重要的是它的速度很是快:
插入:10,680 ops/s
查找:43,290 ops/s
更新:8,000 ops/s。
刪除:11,750 ops/s。
ops (operation per second) 即表示每秒操做的次數。
❝A Minimalistic Wrapper for IndexedDB.
https://github.com/dfahlander/Dexie.js
❞
Dexie.js 是 IndexedDB 的包裝庫,它提供了一套通過精心設計的 API,強大的錯誤處理,較強的可擴展性,此外它可以跟蹤數據變化,支持 KeyRange (搜索不區分大小寫,可設置匹方式和 OR 操做)。
Dexie.js 主要爲了解決原生 IndexedDB API 中存在的三個主要問題:
爲了便於開發者接入 Dexie.js,在 Dexie.js 官網中提供了豐富的示例:
以上只列出部分示例,瞭解更多示例請訪問:Dexie.js - Samples(https://dexie.org/docs/Samples)。最後咱們來簡單介紹一下各類 Web 存儲方案。
HTTP Cookie(也叫 Web Cookie 或瀏覽器 Cookie)是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。一般,它用於告知服務端兩個請求是否來自同一瀏覽器,如保持用戶的登陸狀態。
Cookie 主要用於如下三個方面:
Cookie 的特色:
HttpOnly
,防止 Cookie 被客戶端的 JavaScript 訪問。
「示例1:簡單用法」
document.cookie = "name=semlinker";
document.cookie = "favorite_food=tripe"; alert(document.cookie); // 顯示: name=semlinker;favorite_food=tripe 複製代碼
「示例2:獲得名爲 test2 的 cookie」
document.cookie = "test1=Hello";
document.cookie = "test2=World"; var myCookie = document.cookie .replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/, "$1"); alert(myCookie); 複製代碼
一種持久化的存儲方式,也就是說若是不手動清除,數據就永遠不會過時。它是採用鍵值對的方式存儲數據,按域名將數據分別保存到對應數據庫文件裏。相比 Cookie 來講,它能保存更大的數據。
localStorage 的特色:
「示例」
// 經過setItem()增長一個數據項
localStorage.setItem('myName', 'Semlinker'); // 經過getItem()獲取某個數據項 let me = localStorage.getItem('myName'); // 經過removeItem()移除某個數據項 localStorage.removeItem('myName'); // 移除全部數據項 localStorage.clear(); 複製代碼
與服務端的 session 相似,sessionStorage 是一種會話級別的緩存,關閉瀏覽器時數據會被清除。須要注意的是 sessionStorage 的做用域是窗口級別的,也就是說不一樣窗口之間保存的 sessionStorage 數據是不能共享的。
sessionStorage 的特色:
「示例」
// 經過setItem()增長一個數據項
sessionStorage.setItem('myName', 'Semlinker'); // 經過getItem()獲取某個數據項 let me = sessionStorage.getItem('myName'); // 經過removeItem()移除某個數據項 sessionStorage.removeItem('myName'); // 移除全部數據項 sessionStorage.clear(); 複製代碼
Web SQL 數據庫 API 實際上不是 HTML5 規範的一部分,而是一個單獨的規範,它引入了一組 API 來使用 SQL 來操做客戶端數據庫。須要注意的是,HTML5 已經放棄 Web SQL 數據庫。
Web SQL Database 規範中定義的三個核心方法:
openDatabase:這個方法使用現有數據庫或新建數據庫來建立數據庫對象;
transaction:這個方法容許咱們根據狀況控制事務的提交或回滾;
executeSql:這個方法用於執行真實的 SQL 語句。
Web SQL 的特色(相比 Cookie、localStorage 與 sessionStorage):
「示例」
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) { // 執行查詢操做 tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)'); // 執行插入操做 tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "foobar")'); tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "logmsg")'); }); 複製代碼
IndexedDB 是一種底層 API,用於客戶端存儲大量結構化數據,包括文件、二進制大型對象。該 API 使用索引來實現對該數據的高性能搜索。雖然 Web Storage 對於存儲較少許的數據頗有用,但對於存儲更大量的結構化數據來講,這種方法不太好用。IndexedDB 提供了一個解決方案。
IndexedDB 的特色:
「示例」
var dbName = "my_db";
var request = indexedDB.open(dbName, 2); request.onerror = function(event) { // 錯誤處理 }; request.onupgradeneeded = function(event) { var db = event.target.result; // 創建一個對象倉庫來存儲咱們客戶的相關信息,咱們選擇 ssn 做爲鍵路徑(key path) // 由於 ssn 能夠保證是不重複的 var objectStore = db.createObjectStore("customers", { keyPath: "ssn" }); // 創建一個索引來經過姓名來搜索客戶。名字可能會重複,因此咱們不能使用 unique 索引 objectStore.createIndex("name", "name", { unique: false }); // 使用郵箱創建索引,咱們確保客戶的郵箱不會重複,因此咱們使用 unique 索引 objectStore.createIndex("email", "email", { unique: true }); // 使用事務的 oncomplete 事件確保在插入數據前對象倉庫已經建立完畢 objectStore.transaction.oncomplete = function(event) { // 將數據保存到新建立的對象倉庫 var customerObjectStore = db.transaction("customers", "readwrite").objectStore("customers"); customerData.forEach(function(customer) { customerObjectStore.add(customer); }); }; }; 複製代碼
篇幅有限這裏咱們只介紹了部分開源庫,其實還有一些其它成熟的開源庫,好比 lowdb(Local JSON Database)、Lovefield(Relational Database)和 LokiJS(NoSQL Database)等,若是你知道其它好玩的項目,歡迎給阿寶哥留言喲。
建立了一個 「全棧修仙之路交流羣」 的微信羣,想加羣的小夥伴,加我微信 "semlinker",備註 TS。阿里、京東、騰訊的大佬都在羣裏等你喲。 semlinker/awesome-typescript 1.6K
本文使用 mdnice 排版