2
0

fix:旧浏览器存储方法兼容修改

This commit is contained in:
zhongzm
2024-12-31 17:01:36 +08:00
parent 3c8c9d2f12
commit a70546756a
2 changed files with 189 additions and 42 deletions

View File

@@ -3,61 +3,101 @@ import localforage from 'localforage';
/** The storage type */
export type StorageType = 'local' | 'session';
// 内存存储的备用实现
class MemoryStorage {
private static instance: MemoryStorage;
private storage = new Map<string, string>();
static getInstance() {
if (!MemoryStorage.instance) {
MemoryStorage.instance = new MemoryStorage();
}
return MemoryStorage.instance;
}
setItem(key: string, value: string) {
this.storage.set(key, value);
}
getItem(key: string) {
return this.storage.get(key) || null;
}
removeItem(key: string) {
this.storage.delete(key);
}
clear() {
this.storage.clear();
}
}
// 全局备用存储实例
const memoryStorage = MemoryStorage.getInstance();
export function createStorage<T extends object>(type: StorageType) {
const stg = type === 'session' ? window.sessionStorage : window.localStorage;
// 尝试获取存储实例,如果失败则使用内存存储
let stg: Storage | MemoryStorage;
try {
stg = type === 'session' ? window.sessionStorage : window.localStorage;
// 测试存储是否可用
stg.setItem('__storage_test__', '');
stg.removeItem('__storage_test__');
} catch (e) {
console.warn(`${type} storage is not available, using memory storage`);
stg = memoryStorage;
}
const storage = {
/**
* Set session
*
* @param key Session key
* @param value Session value
*/
set<K extends keyof T>(key: K, value: T[K]) {
const json = JSON.stringify(value);
stg.setItem(key as string, json);
try {
const json = JSON.stringify(value);
stg.setItem(key as string, json);
} catch (e) {
console.warn(`Storage set error, falling back to memory storage`);
memoryStorage.setItem(key as string, JSON.stringify(value));
}
},
/**
* Get session
*
* @param key Session key
*/
get<K extends keyof T>(key: K): T[K] | null {
const json = stg.getItem(key as string);
if (json) {
let storageData: T[K] | null = null;
try {
const json = stg.getItem(key as string);
if (!json) return null;
return JSON.parse(json);
} catch (e) {
console.warn(`Storage get error, trying memory storage`);
try {
storageData = JSON.parse(json);
} catch {}
if (storageData) {
return storageData as T[K];
const memoryValue = memoryStorage.getItem(key as string);
return memoryValue ? JSON.parse(memoryValue) : null;
} catch {
return null;
}
}
stg.removeItem(key as string);
return null;
},
remove(key: keyof T) {
stg.removeItem(key as string);
try {
stg.removeItem(key as string);
memoryStorage.removeItem(key as string);
} catch (e) {
console.warn(`Storage remove error`);
}
},
clear() {
stg.clear();
try {
stg.clear();
memoryStorage.clear();
} catch (e) {
console.warn(`Storage clear error`);
}
}
};
return storage;
}
type LocalForage<T extends object> = Omit<typeof localforage, 'getItem' | 'setItem' | 'removeItem'> & {
getItem<K extends keyof T>(key: K, callback?: (err: any, value: T[K] | null) => void): Promise<T[K] | null>;
setItem<K extends keyof T>(key: K, value: T[K], callback?: (err: any, value: T[K]) => void): Promise<T[K]>;
removeItem(key: keyof T, callback?: (err: any) => void): Promise<void>;
};
type LocalforageDriver = 'local' | 'indexedDB' | 'webSQL';
@@ -68,9 +108,97 @@ export function createLocalforage<T extends object>(driver: LocalforageDriver) {
webSQL: localforage.WEBSQL
};
localforage.config({
driver: driverMap[driver]
});
// 创建一个内存存储的备用实现
const memoryStore = new Map<string, any>();
return localforage as LocalForage<T>;
// 创建备用存储对象
const fallbackStorage = {
getItem<K extends keyof T>(key: K): Promise<T[K] | null> {
return Promise.resolve(memoryStore.get(key as string) || null);
},
setItem<K extends keyof T>(key: K, value: T[K]): Promise<T[K]> {
memoryStore.set(key as string, value);
return Promise.resolve(value);
},
removeItem(key: keyof T): Promise<void> {
memoryStore.delete(key as string);
return Promise.resolve();
},
clear(): Promise<void> {
memoryStore.clear();
return Promise.resolve();
},
length(): Promise<number> {
return Promise.resolve(memoryStore.size);
},
key(keyIndex: number): Promise<string> {
return Promise.resolve(Array.from(memoryStore.keys())[keyIndex]);
},
keys(): Promise<string[]> {
return Promise.resolve(Array.from(memoryStore.keys()));
}
};
try {
// 配置 localforage
localforage.config({
driver: [
driverMap[driver],
localforage.LOCALSTORAGE,
localforage.INDEXEDDB,
localforage.WEBSQL
].filter(Boolean),
name: 'appStorage',
version: 1.0,
storeName: 'keyvaluepairs'
});
// 创建包装的存储对象
const storage = {
getItem<K extends keyof T>(key: K): Promise<T[K] | null> {
return localforage.getItem<T[K]>(key as string)
.catch(() => fallbackStorage.getItem(key));
},
setItem<K extends keyof T>(key: K, value: T[K]): Promise<T[K]> {
return localforage.setItem<T[K]>(key as string, value)
.catch(() => fallbackStorage.setItem(key, value));
},
removeItem(key: keyof T): Promise<void> {
return localforage.removeItem(key as string)
.catch(() => fallbackStorage.removeItem(key));
},
clear(): Promise<void> {
return localforage.clear()
.catch(() => fallbackStorage.clear());
},
length(): Promise<number> {
return localforage.length()
.catch(() => fallbackStorage.length());
},
key(keyIndex: number): Promise<string> {
return localforage.key(keyIndex)
.catch(() => fallbackStorage.key(keyIndex));
},
keys(): Promise<string[]> {
return localforage.keys()
.catch(() => fallbackStorage.keys());
}
};
return storage as LocalForage<T>;
} catch (e) {
console.warn('Localforage initialization failed, using memory storage', e);
return fallbackStorage as LocalForage<T>;
}
}
// 更新类型定义
interface LocalForage<T extends object> {
getItem<K extends keyof T>(key: K): Promise<T[K] | null>;
setItem<K extends keyof T>(key: K, value: T[K]): Promise<T[K]>;
removeItem(key: keyof T): Promise<void>;
clear(): Promise<void>;
length(): Promise<number>;
key(keyIndex: number): Promise<string>;
keys(): Promise<string[]>;
}

View File

@@ -29,7 +29,8 @@ export default defineConfig(configEnv => {
open: false,
proxy: createViteProxy(viteEnv, configEnv.command === 'serve'),
fs: {
cachedChecks: false
cachedChecks: false,
strict: false // 添加这个配置
}
},
preview: {
@@ -40,6 +41,24 @@ export default defineConfig(configEnv => {
sourcemap: viteEnv.VITE_SOURCE_MAP === 'Y',
commonjsOptions: {
ignoreTryCatch: false
},
// 添加以下配置
rollupOptions: {
output: {
manualChunks: undefined, // 禁用代码分割
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
}
},
// 添加以下配置
chunkSizeWarningLimit: 2000,
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
}
}
};