forked from 77media/video-flow
149 lines
3.8 KiB
TypeScript
149 lines
3.8 KiB
TypeScript
/**
|
||
* 开发环境助手工具
|
||
* 用于处理 Next.js 开发环境中的常见问题
|
||
*/
|
||
|
||
import { isDevelopment } from '@/lib/env';
|
||
|
||
/**
|
||
* 安全的组件重渲染函数
|
||
* 用于处理热重载时的组件状态重置
|
||
*/
|
||
export const safeRerender = (callback: () => void) => {
|
||
if (isDevelopment) {
|
||
try {
|
||
callback();
|
||
} catch (error) {
|
||
console.warn('热重载时组件重渲染失败:', error);
|
||
// 在开发环境中,可以选择刷新页面
|
||
if (window.confirm('检测到热重载错误,是否刷新页面?')) {
|
||
window.location.reload();
|
||
}
|
||
}
|
||
} else {
|
||
callback();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 处理 ChunkLoadError 的函数
|
||
*/
|
||
export const handleChunkLoadError = (error: Error): boolean => {
|
||
if (error.name === 'ChunkLoadError' || error.message.includes('Loading chunk')) {
|
||
console.warn('检测到 ChunkLoadError,尝试刷新页面');
|
||
window.location.reload();
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
/**
|
||
* 全局错误处理器
|
||
* 自动处理常见的开发环境错误
|
||
*/
|
||
export const setupGlobalErrorHandler = () => {
|
||
if (isDevelopment && typeof window !== 'undefined') {
|
||
window.addEventListener('error', (event) => {
|
||
if (handleChunkLoadError(event.error)) {
|
||
event.preventDefault();
|
||
}
|
||
});
|
||
|
||
window.addEventListener('unhandledrejection', (event) => {
|
||
if (event.reason?.name === 'ChunkLoadError') {
|
||
console.warn('检测到未处理的 ChunkLoadError Promise 拒绝');
|
||
event.preventDefault();
|
||
window.location.reload();
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 安全的状态更新 Hook
|
||
* 防止在组件卸载后更新状态
|
||
*/
|
||
export const useSafeState = <T>(initialState: T): [T, (newState: T | ((prev: T) => T)) => void] => {
|
||
const [state, setState] = React.useState(initialState);
|
||
const mountedRef = React.useRef(true);
|
||
|
||
React.useEffect(() => {
|
||
return () => {
|
||
mountedRef.current = false;
|
||
};
|
||
}, []);
|
||
|
||
const safeSetState = React.useCallback((newState: T | ((prev: T) => T)) => {
|
||
if (mountedRef.current) {
|
||
setState(newState);
|
||
}
|
||
}, []);
|
||
|
||
return [state, safeSetState];
|
||
};
|
||
|
||
/**
|
||
* 清理本地缓存的函数
|
||
*/
|
||
export const clearLocalCache = () => {
|
||
if (typeof window !== 'undefined') {
|
||
// 清理 localStorage
|
||
try {
|
||
const keys = Object.keys(localStorage);
|
||
keys.forEach(key => {
|
||
if (key.startsWith('__next') || key.startsWith('webpack')) {
|
||
localStorage.removeItem(key);
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.warn('清理 localStorage 失败:', error);
|
||
}
|
||
|
||
// 清理 sessionStorage
|
||
try {
|
||
const keys = Object.keys(sessionStorage);
|
||
keys.forEach(key => {
|
||
if (key.startsWith('__next') || key.startsWith('webpack')) {
|
||
sessionStorage.removeItem(key);
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.warn('清理 sessionStorage 失败:', error);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 开发环境初始化函数
|
||
* 在应用启动时调用
|
||
*/
|
||
export const initDevHelper = () => {
|
||
if (isDevelopment) {
|
||
setupGlobalErrorHandler();
|
||
console.log('开发环境助手已启动');
|
||
|
||
// 在控制台提供一些有用的方法
|
||
if (typeof window !== 'undefined') {
|
||
(window as any).__devHelper = {
|
||
clearCache: clearLocalCache,
|
||
reload: () => window.location.reload(),
|
||
clearAndReload: () => {
|
||
clearLocalCache();
|
||
window.location.reload();
|
||
}
|
||
};
|
||
|
||
console.log('可用的开发工具方法:');
|
||
console.log('- __devHelper.clearCache(): 清理本地缓存');
|
||
console.log('- __devHelper.reload(): 刷新页面');
|
||
console.log('- __devHelper.clearAndReload(): 清理缓存并刷新页面');
|
||
}
|
||
}
|
||
};
|
||
|
||
// 自动初始化(仅在浏览器环境中)
|
||
if (typeof window !== 'undefined') {
|
||
initDevHelper();
|
||
}
|
||
|
||
import React from 'react';
|