npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gulibs/react-autoroutes-client

v0.0.18

Published

Client-side utilities for React auto routes

Readme

@gulibs/react-autoroutes-client

一个功能强大的 React 路由自动化客户端库,提供完整的路由保护、状态管理、国际化和性能优化解决方案。

✨ 特性

  • 🛡️ 路由保护 - 支持认证、权限、角色和自定义守卫
  • 🏗️ 中间件系统 - 可插拔的中间件架构
  • 🌍 国际化支持 - 与 @gulibs/vite-plugin-i18n 完美集成
  • 📊 状态管理 - 基于 React Storage 的用户认证状态管理
  • 性能优化 - 内置缓存、防抖和性能监控
  • 🎯 TypeScript - 完整的类型定义支持
  • 📱 现代化 - 支持 React 18+ 和现代浏览器
  • 🔄 热更新 - 支持开发时的热模块替换
  • 📦 模块化 - 按需导入,减小包大小

📦 安装

npm install @gulibs/react-autoroutes-client
# 或
pnpm add @gulibs/react-autoroutes-client
# 或
yarn add @gulibs/react-autoroutes-client

对等依赖

npm install react react-dom react-router lodash

🚀 快速开始

1. 路由保护

import { RouteProtectionWrapper, defineAuth, defineGuard } from '@gulibs/react-autoroutes-client';

// 定义认证守卫
const authGuard = defineAuth({
  redirectTo: '/login',
  errorMessage: '请先登录'
});

// 定义自定义守卫
const adminGuard = defineGuard({
  name: 'admin-only',
  condition: (context) => context.user?.role === 'admin',
  redirectTo: '/forbidden',
  errorMessage: '需要管理员权限'
});

function ProtectedPage() {
  return (
    <RouteProtectionWrapper
      guards={[authGuard, adminGuard]}
      loadingElement={<div>验证中...</div>}
      component={<YourPageComponent />}
    />
  );
}

2. 用户状态管理

import { useUser } from '@gulibs/react-autoroutes-client';

function AuthComponent() {
  const {
    user,
    isAuthenticated,
    isLoading,
    login,
    logout,
    error
  } = useUser({
    loginApi: async (credentials) => {
      const response = await fetch('/api/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(credentials)
      });
      return response.json();
    },
    fetchUser: async (token) => {
      const response = await fetch('/api/user', {
        headers: { Authorization: `Bearer ${token}` }
      });
      return response.json();
    }
  });

  if (isLoading) return <div>加载中...</div>;
  if (error) return <div>错误: {error}</div>;

  return (
    <div>
      {isAuthenticated ? (
        <div>
          <p>欢迎, {user?.name}</p>
          <button onClick={logout}>退出登录</button>
        </div>
      ) : (
        <button onClick={() => login({ username: 'demo', password: '123' })}>
          登录
        </button>
      )}
    </div>
  );
}

3. 国际化支持

import { I18nProvider, useI18n, createI18nClient } from '@gulibs/react-autoroutes-client';

// 创建国际化客户端
const i18nClient = createI18nClient({
  defaultLocale: 'zh',
  supportedLocales: ['zh', 'en'],
  resources: {
    zh: {
      welcome: '欢迎',
      hello: '你好, {name}!'
    },
    en: {
      welcome: 'Welcome',
      hello: 'Hello, {name}!'
    }
  }
});

function App() {
  return (
    <I18nProvider client={i18nClient}>
      <MyComponent />
    </I18nProvider>
  );
}

function MyComponent() {
  const { t, locale, setLocale } = useI18n();

  return (
    <div>
      <p>{t('welcome')}</p>
      <p>{t('hello', { name: '张三' })}</p>
      <button onClick={() => setLocale(locale === 'zh' ? 'en' : 'zh')}>
        切换语言
      </button>
    </div>
  );
}

4. 页面配置和 Hooks

import {
  useHandle,
  usePageConfig,
  useI18nPageConfig,
  useVGroveLayoutSettings,
  useLayoutFeatures,
  defineHandle
} from '@gulibs/react-autoroutes-client';

// 定义页面处理配置
export const handle = defineHandle({
  meta: {
    title: 'page.title',
    description: '页面描述'
  },
  breadcrumbs: {
    href: '/current-page',
    children: '当前页面'
  },
  layoutSettings: {
    variant: 'modern',
    sidebar: true,
    header: true,
    footer: false,
    content: {
      maxWidth: '1400px',
      padding: '2rem',
      centered: true,
      fullWidth: false
    },
    navbar: {
      sticky: true,
      transparent: false,
      height: '72px'
    },
    sidebarConfig: {
      position: 'left',
      width: '320px',
      collapsible: true,
      defaultCollapsed: false
    },
    theme: {
      mode: 'dark',
      primaryColor: '#3b82f6'
    },
    responsive: {
      hideSidebarOnMobile: true,
      mobileBreakpoint: '768px'
    }
  }
});

function MyPage() {
  // 获取页面配置
  const { meta, breadcrumbs, layoutSettings } = usePageConfig(handle);

  // 获取 VGrove 布局配置(带默认值)
  const vgroveLayout = useVGroveLayoutSettings(handle);

  // 获取布局功能状态
  const {
    hasSidebar,
    hasHeader,
    hasFooter,
    isModern,
    isSidebarCollapsible,
    shouldHideSidebarOnMobile
  } = useLayoutFeatures(handle);

  // 获取国际化页面配置
  const i18nConfig = useI18nPageConfig(handle);

  return (
    <div>
      <h1>{meta?.title}</h1>
      {hasSidebar && <div>显示侧边栏</div>}
      {hasHeader && <div>显示头部</div>}
      {/* 页面内容 */}
    </div>
  );
}

🎯 高级用法

中间件系统

import { defineMiddleware } from '@gulibs/react-autoroutes-client';

const loggingMiddleware = defineMiddleware({
  name: 'logging',
  priority: 10,
  handler: async (context, next) => {
    console.log(`访问页面: ${context.path}`);
    const start = Date.now();

    await next();

    const duration = Date.now() - start;
    console.log(`页面处理耗时: ${duration}ms`);
  }
});

// 全局性能监控中间件
const performanceMiddleware = defineMiddleware({
  name: 'performance',
  priority: 1,
  handler: async (context, next) => {
    if (window.performance) {
      const mark = `route-${context.path}-start`;
      performance.mark(mark);
    }

    await next();

    if (window.performance) {
      const endMark = `route-${context.path}-end`;
      performance.mark(endMark);
      performance.measure(`route-${context.path}`, `route-${context.path}-start`, endMark);
    }
  }
});

<RouteProtectionWrapper
  middlewares={[performanceMiddleware, loggingMiddleware]}
  component={<YourComponent />}
/>

国际化资源加载器

import { createI18nLoader, ViteI18nLoader, createI18nClient } from '@gulibs/react-autoroutes-client';

// 1. 基础资源加载器
const loader = createI18nLoader({
  basePath: '/api/locales',
  extensions: ['.json'],
  cache: true,
  debug: true
});

// 2. 自定义获取函数
const customLoader = createI18nLoader({
  fetchResources: async (locale, path) => {
    const response = await fetch(`/api/i18n/${locale}`);
    if (!response.ok) {
      throw new Error(`Failed to load locale: ${response.statusText}`);
    }
    return response.json();
  },
  onLoad: (locale, data) => {
    console.log(`✅ Loaded ${locale}:`, Object.keys(data));
  },
  onError: (locale, error) => {
    console.error(`❌ Failed to load ${locale}:`, error);
  }
});

// 3. 高级加载器实例
const advancedLoader = new ViteI18nLoader({
  basePath: '/locales',
  cache: true,
  cacheTime: 30 * 60 * 1000, // 30分钟
  debug: process.env.NODE_ENV === 'development'
});

// 4. 与国际化客户端集成
const i18nClient = createI18nClient({
  defaultLocale: 'zh',
  supportedLocales: ['zh', 'en'],
  basePath: '/api/locales',
  cache: true,
  detectBrowserLanguage: true,
  persistence: {
    enabled: true,
    key: 'user_locale',
    storage: 'localStorage'
  }
});

// 5. 手动预加载资源
await loader.preloadResources(['zh', 'en']);

// 6. 检查加载器状态
console.log('Available keys:', loader.getAvailableKeys?.());
console.log('Has key "welcome":', loader.hasKey?.('welcome'));
console.log('Using virtual module:', advancedLoader.isUsingVirtualModule?.());

复杂路由守卫

// 角色守卫
const roleGuard = defineAuth({
  roles: ['admin', 'moderator'],
  redirectTo: '/login',
  errorMessage: '需要以下角色之一: admin, moderator'
});

// 权限守卫
const permissionGuard = defineGuard({
  name: 'permission-user:read,user:write',
  condition: (context) => {
    return context.user?.permissions?.includes('user:read') &&
           context.user?.permissions?.includes('user:write');
  },
  redirectTo: '/forbidden',
  errorMessage: '需要以下权限: user:read, user:write'
});

// 自定义复合守卫
const complexGuard = defineGuard({
  name: 'complex-auth',
  condition: async (context) => {
    // 检查用户是否已认证
    if (!context.user) return false;

    // 检查时间限制
    const now = new Date();
    const workingHours = now.getHours() >= 9 && now.getHours() <= 18;

    // 检查用户类型和时间
    return context.user.type === 'employee' ? workingHours : true;
  },
  redirectTo: '/access-denied',
  errorMessage: '当前时间段无法访问'
});

// 环境守卫
const environmentGuard = defineGuard({
  name: 'environment',
  condition: () => {
    return process.env.NODE_ENV === 'development' ||
           localStorage.getItem('feature_flag_enabled') === 'true';
  },
  redirectTo: '/not-available'
});

性能优化工具

import {
  PerformanceCache,
  BatchProcessor,
  PerformanceTracker,
  MemoryOptimizer
} from '@gulibs/react-autoroutes-client';

// 创建缓存实例
const cache = new PerformanceCache<string, any>(100);

// 批处理器
const processor = new BatchProcessor(5, 100);

// 性能追踪
const tracker = new PerformanceTracker();

// 内存优化器
const memoryOptimizer = MemoryOptimizer.getInstance();

function useOptimizedData() {
  useEffect(() => {
    // 启动性能追踪
    tracker.startTimer('data-loading');

    // 批处理数据加载
    const loadData = async () => {
      const items = ['user', 'settings', 'permissions'];
      const results = await processor.processBatch(
        items,
        async (item) => {
          const cached = cache.get(item);
          if (cached) return cached;

          const data = await fetchData(item);
          cache.set(item, data);
          return data;
        }
      );

      return results;
    };

    loadData().finally(() => {
      const duration = tracker.endTimer('data-loading');
      console.log(`数据加载耗时: ${duration}ms`);
    });

    // 注册清理任务
    memoryOptimizer.addCleanupTask(() => {
      cache.clear();
    });

    return () => {
      memoryOptimizer.runCleanup();
    };
  }, []);
}

工具函数和实用程序

import {
  normalizePath,
  parseQuery,
  buildQuery,
  debounce,
  throttle,
  deepMerge,
  safeParseInt,
  isEmpty,
  measureTime
} from '@gulibs/react-autoroutes-client';

// 路径处理
const normalizedPath = normalizePath('//path//to//page//');
// => '/path/to/page'

// 查询参数处理
const params = parseQuery('?name=john&age=25&active=true');
// => { name: 'john', age: '25', active: 'true' }

const query = buildQuery({ name: 'jane', age: 30 });
// => 'name=jane&age=30'

// 防抖和节流
const debouncedSearch = debounce((query: string) => {
  searchAPI(query);
}, 500);

const throttledScroll = throttle(() => {
  updateScrollPosition();
}, 100);

// 性能测量
const timedFunction = measureTime(expensiveFunction, 'expensive-operation');

// 数据处理
const config = deepMerge(defaultConfig, userConfig);
const count = safeParseInt(userInput, 0);
const hasData = !isEmpty(responseData);

📖 API 参考

路由保护

RouteProtectionWrapper

路由保护包装器组件。

Props:

interface RouteProtectionWrapperProps {
  guards?: (AuthOptions | GuardOptions | Function)[];
  middlewares?: (MiddlewareOptions | Function)[];
  loadingElement?: React.ReactNode;
  component: React.ReactNode;
  children?: React.ReactNode;
}

defineAuth(options: AuthOptions)

定义认证守卫。

interface AuthOptions {
  name?: string;
  redirectTo?: string;
  errorMessage?: string;
  check?: (context: AuthContext) => boolean | Promise<boolean>;
  roles?: string[];
  permissions?: string[];
}

defineGuard(options: GuardOptions)

定义自定义守卫。

interface GuardOptions {
  name?: string;
  type?: 'auth' | 'role' | 'permission' | 'custom';
  redirectTo?: string;
  errorMessage?: string;
  condition: (context: GuardContext) => boolean | Promise<boolean>;
}

defineMiddleware(options: MiddlewareOptions)

定义中间件。

interface MiddlewareOptions {
  name?: string;
  priority?: number;
  devOnly?: boolean;
  handler: (context: MiddlewareContext, next: () => Promise<void> | void) => Promise<void> | void;
}

状态管理

useUser<TUser, TCredentials>(options: UseUserOptions)

用户状态管理 Hook。

返回值:

interface AuthState<TUser> & AuthActions<TUser, TCredentials> {
  user: TUser | null;
  token: string | null;
  refreshToken: string | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
  login: (credentials: TCredentials) => Promise<void>;
  logout: () => void;
  refreshUser: () => Promise<void>;
  refreshTokenAction: () => Promise<void>;
  updateUser: (userData: Partial<TUser>) => void;
  setToken: (token: string) => void;
  setRefreshToken: (refreshToken: string) => void;
  clearError: () => void;
}

useStorage<T>(key: string, defaultValue: T, options?)

通用存储 Hook。

function useStorage<T>(
  key: string,
  defaultValue: T,
  options?: { storage?: 'local' | 'session' }
): [T, (value: T) => void, () => void]

国际化

I18nProvider

国际化提供者组件。

interface I18nProviderProps {
  children: ReactNode;
  client?: I18nClient | I18nClientConfig;
  defaultLocale?: string;
  locales?: string[];
  loadResources?: (locale: string) => Promise<Record<string, any>>;
  resources?: Record<string, Record<string, any>>;
}

useI18n()

国际化 Hook。

interface I18nContextType {
  locale: string;
  setLocale: (locale: string) => Promise<void>;
  t: (key: string, params?: Record<string, any>) => string;
  isReady: boolean;
  availableLocales: string[];
  availableKeys: string[];
  hasKey: (key: string) => boolean;
  getNamespaceResources: (namespace: string) => Record<string, any> | undefined;
  isUsingVirtualModule: boolean;
}

createI18nClient(config: I18nClientConfig)

创建国际化客户端。

interface I18nClientConfig extends I18nLoaderConfig {
  defaultLocale: string;
  supportedLocales?: string[];
  resources?: Record<string, Record<string, any>>;
  fallbackToDefault?: boolean;
  detectBrowserLanguage?: boolean;
  persistence?: {
    enabled?: boolean;
    key?: string;
    storage?: 'localStorage' | 'sessionStorage';
  };
  interpolation?: {
    prefix?: string;
    suffix?: string;
    escape?: (value: any) => string;
  };
}

createI18nLoader(config: I18nLoaderConfig)

创建资源加载器。

interface I18nLoaderConfig {
  basePath?: string;
  extensions?: string[];
  localePattern?: 'directory' | 'filename';
  defaultLocale?: string;
  cacheTime?: number;
  cache?: boolean;
  debug?: boolean;
  onLoad?: (locale: string, data: Record<string, any>) => void;
  onError?: (locale: string, error: Error) => void;
  fetchResources?: (locale: string, path: string) => Promise<Record<string, any>>;
}

页面配置

usePageConfig<Keys>(handle?, options?)

获取页面配置。

useI18nPageConfig<Keys>(handle?)

获取国际化页面配置。

useHandle<Keys>()

获取当前页面的 handle。

useBreadcrumbs<Keys>(handle?, options?)

获取面包屑配置。

useDocumentTitle<Keys>(handle?, suffix?, options?)

设置文档标题。

useVGroveLayoutSettings<Keys>(handle?, defaults?)

获取 VGrove 布局配置,带默认值处理。

function useVGroveLayoutSettings<Keys extends string = string>(
    handle?: PageHandle<Keys>,
    defaults?: Partial<LayoutSettings>
): LayoutSettings

useLayoutFeatures<Keys>(handle?)

检查布局功能是否启用。

interface LayoutFeatures {
    hasSidebar: boolean;
    hasHeader: boolean;
    hasFooter: boolean;
    isCompact: boolean;
    isModern: boolean;
    isMinimal: boolean;
    isSidebarCollapsible: boolean;
    isNavbarSticky: boolean;
    isFooterSticky: boolean;
    shouldHideSidebarOnMobile: boolean;
}

useLayoutConfig<Keys>(section, handle?)

获取布局配置的特定部分。

function useLayoutConfig<Keys extends string = string>(
    section: keyof LayoutSettings,
    handle?: PageHandle<Keys>
): any

LayoutSettings 接口

VGrove 布局配置接口,支持完整的布局定制。

interface LayoutSettings {
    /** 布局变体 */
    variant?: 'default' | 'compact' | 'modern' | 'minimal' | string;
    /** 是否显示侧边栏 */
    sidebar?: boolean;
    /** 是否显示导航栏/头部 */
    header?: boolean;
    /** 是否显示页脚 */
    footer?: boolean;
    /** 内容区域配置 */
    content?: {
        /** 内容最大宽度 */
        maxWidth?: string;
        /** 内容内边距 */
        padding?: string;
        /** 是否居中对齐 */
        centered?: boolean;
        /** 是否全宽显示 */
        fullWidth?: boolean;
    };
    /** 导航栏配置 */
    navbar?: {
        /** 是否固定在顶部 */
        sticky?: boolean;
        /** 背景透明度 */
        transparent?: boolean;
        /** 高度 */
        height?: string;
    };
    /** 侧边栏配置 */
    sidebarConfig?: {
        /** 侧边栏位置 */
        position?: 'left' | 'right';
        /** 侧边栏宽度 */
        width?: string;
        /** 是否可折叠 */
        collapsible?: boolean;
        /** 默认是否折叠 */
        defaultCollapsed?: boolean;
    };
    /** 页脚配置 */
    footerConfig?: {
        /** 是否固定在底部 */
        sticky?: boolean;
        /** 高度 */
        height?: string;
    };
    /** 主题相关配置 */
    theme?: {
        /** 主题模式 */
        mode?: 'light' | 'dark' | 'auto';
        /** 主色调 */
        primaryColor?: string;
    };
    /** 响应式配置 */
    responsive?: {
        /** 移动端是否隐藏侧边栏 */
        hideSidebarOnMobile?: boolean;
        /** 移动端断点 */
        mobileBreakpoint?: string;
    };
}

性能优化

PerformanceCache<K, V>

高性能 LRU 缓存。

class PerformanceCache<K, V> {
  constructor(maxSize: number = 100);
  get(key: K): V | undefined;
  set(key: K, value: V): void;
  has(key: K): boolean;
  delete(key: K): boolean;
  clear(): void;
  size(): number;
}

BatchProcessor

批处理器。

class BatchProcessor {
  constructor(batchSize: number = 10, delay: number = 50);
  async processBatch<T, R>(
    items: T[],
    processor: (item: T) => Promise<R>
  ): Promise<R[]>;
}

PerformanceTracker

性能追踪器。

class PerformanceTracker {
  startTimer(name: string): void;
  endTimer(name: string): number;
  increment(name: string): void;
  getCounter(name: string): number;
  reset(): void;
  getStats(): Record<string, any>;
}

🏆 最佳实践

1. VGrove 布局配置最佳实践

// layout/LayoutProvider.tsx
import { useVGroveLayoutSettings, useLayoutFeatures } from '@gulibs/react-autoroutes-client';
import { VGroveLayout } from '@gulibs/vgrove-ui';

export function LayoutProvider({ children, handle }) {
  // 获取完整的布局配置
  const layoutConfig = useVGroveLayoutSettings(handle, {
    // 全局默认配置
    variant: 'modern',
    content: {
      maxWidth: '1400px',
      padding: '1.5rem'
    },
    theme: {
      mode: 'light'
    }
  });

  // 获取布局功能状态
  const features = useLayoutFeatures(handle);

  return (
    <VGroveLayout
      config={layoutConfig}
      features={features}
    >
      {children}
    </VGroveLayout>
  );
}

// pages/dashboard/handle.ts
import { defineHandle } from '@gulibs/react-autoroutes-client';

export const handle = defineHandle({
  meta: {
    title: 'dashboard.title',
    description: 'dashboard.description'
  },
  layoutSettings: {
    variant: 'modern',
    sidebar: true,
    header: true,
    footer: false,
    content: {
      maxWidth: '100%',
      fullWidth: true,
      padding: '0'
    },
    sidebarConfig: {
      width: '280px',
      collapsible: true,
      defaultCollapsed: false
    },
    navbar: {
      sticky: true,
      height: '64px'
    },
    responsive: {
      hideSidebarOnMobile: true
    }
  }
});

// pages/dashboard/page.tsx
import { useVGroveLayoutSettings } from '@gulibs/react-autoroutes-client';
import { handle } from './handle';

export default function DashboardPage() {
  const layoutConfig = useVGroveLayoutSettings(handle);

  return (
    <div className="dashboard">
      <h1>仪表板</h1>
      {/* 根据布局配置显示内容 */}
    </div>
  );
}

// pages/settings/handle.ts
export const handle = defineHandle({
  meta: {
    title: 'settings.title'
  },
  layoutSettings: {
    variant: 'compact',
    sidebar: false,
    header: true,
    footer: true,
    content: {
      maxWidth: '800px',
      centered: true,
      padding: '2rem'
    }
  }
});

2. 路由守卫组织

// guards/index.ts
export const authGuard = defineAuth({
  redirectTo: '/login',
  errorMessage: '请先登录'
});

export const adminGuard = defineAuth({
  roles: ['admin'],
  redirectTo: '/forbidden',
  errorMessage: '需要管理员权限'
});

export const premiumGuard = defineGuard({
  name: 'premium',
  condition: (context) => context.user?.isPremium,
  redirectTo: '/upgrade',
  errorMessage: '需要升级到高级版'
});

// guards/factory.ts
export function createRoleGuard(roles: string[], redirectTo = '/forbidden') {
  return defineAuth({
    roles,
    redirectTo,
    errorMessage: `需要以下角色之一: ${roles.join(', ')}`
  });
}

export function createPermissionGuard(permissions: string[], redirectTo = '/forbidden') {
  return defineGuard({
    name: `permission-${permissions.join('-')}`,
    condition: (context) => {
      return permissions.every(permission =>
        context.user?.permissions?.includes(permission)
      );
    },
    redirectTo,
    errorMessage: `需要以下权限: ${permissions.join(', ')}`
  });
}

3. 国际化最佳实践

// i18n/setup.ts
import { createI18nClient } from '@gulibs/react-autoroutes-client';

export const i18nClient = createI18nClient({
  defaultLocale: 'zh',
  supportedLocales: ['zh', 'en'],
  fallbackToDefault: true,
  detectBrowserLanguage: true,
  persistence: {
    enabled: true,
    key: 'app_locale',
    storage: 'localStorage'
  },
  interpolation: {
    prefix: '{',
    suffix: '}',
    escape: (value) => String(value).replace(/[<>]/g, '')
  },
  debug: process.env.NODE_ENV === 'development',
  // 开发环境短缓存,生产环境长缓存
  cacheTime: process.env.NODE_ENV === 'production'
    ? 24 * 60 * 60 * 1000
    : 5 * 60 * 1000,
  onError: (locale, error) => {
    // 发送错误到监控系统
    console.error(`Failed to load locale ${locale}:`, error);
    // 可以集成 Sentry 等错误监控
  },
  onLoad: (locale, data) => {
    console.log(`✅ Loaded ${locale} with ${Object.keys(data).length} keys`);
  }
});

// hooks/useI18nHelpers.ts
export function useI18nHelpers() {
  const { hasKey, validateKey } = useI18nKeyValidator();
  const plural = usePlural();
  const translateLocalized = useTranslateLocalized();

  return {
    hasKey,
    validateKey,
    plural,
    translateLocalized,
    // 安全翻译函数,键不存在时返回键名
    safeT: (key: string, params?: Record<string, any>) => {
      const { t } = useI18n();
      return hasKey(key) ? t(key, params) : key;
    }
  };
}

3. 性能优化策略

// utils/performance.ts
import {
  PerformanceCache,
  BatchProcessor,
  MemoryOptimizer
} from '@gulibs/react-autoroutes-client';

// 全局缓存实例
export const globalCache = new PerformanceCache<string, any>(200);
export const batchProcessor = new BatchProcessor(10, 100);
export const memoryOptimizer = MemoryOptimizer.getInstance();

// 启动内存优化
memoryOptimizer.startPeriodicCleanup(5 * 60 * 1000); // 5分钟清理一次

// hooks/useOptimizedApi.ts
export function useOptimizedApi() {
  const cache = useMemo(() => new PerformanceCache<string, any>(50), []);

  const fetchWithCache = useCallback(async (url: string) => {
    const cached = cache.get(url);
    if (cached) return cached;

    const response = await fetch(url);
    const data = await response.json();
    cache.set(url, data);
    return data;
  }, [cache]);

  const batchFetch = useCallback(async (urls: string[]) => {
    return batchProcessor.processBatch(urls, fetchWithCache);
  }, [fetchWithCache]);

  useEffect(() => {
    // 注册清理任务
    memoryOptimizer.addCleanupTask(() => {
      cache.clear();
    });
  }, [cache]);

  return { fetchWithCache, batchFetch };
}

4. 错误处理

// utils/errorBoundary.tsx
import { defineGuard } from '@gulibs/react-autoroutes-client';

export const errorHandlingGuard = defineGuard({
  name: 'error-handling',
  condition: async (context) => {
    try {
      // 检查用户权限
      if (!context.user) return false;

      // 检查网络状态
      if (!navigator.onLine) {
        throw new Error('网络连接已断开');
      }

      return true;
    } catch (error) {
      // 发送错误到监控系统
      console.error('Guard error:', error);
      return false;
    }
  },
  redirectTo: '/error'
});

// components/ErrorBoundary.tsx
class ErrorBoundary extends React.Component<
  { children: React.ReactNode },
  { hasError: boolean; error?: Error }
> {
  constructor(props: any) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error) {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error('ErrorBoundary caught an error:', error, errorInfo);
    // 发送错误到监控系统
  }

  render() {
    if (this.state.hasError) {
      return (
        <div className="error-fallback">
          <h2>出现了一些问题</h2>
          <details style={{ whiteSpace: 'pre-wrap' }}>
            {this.state.error?.message}
          </details>
        </div>
      );
    }

    return this.props.children;
  }
}

🚨 故障排除

常见问题

1. 虚拟模块加载失败

症状: 错误信息 Failed to resolve import "~i18n-locales-loader"

解决方案:

# 检查插件配置
# vite.config.ts 中确保有:
import i18nPlugin from '@gulibs/vite-plugin-i18n';

export default defineConfig({
  plugins: [
    i18nPlugin({
      basePath: 'src/locales',
      keysOutput: 'src/i18n-keys.ts'
    })
  ]
});

# 重启开发服务器
npm run dev

2. 认证状态不同步

症状: 页面刷新后用户状态丢失

解决方案:

// 确保正确配置 useUser
const { user, isAuthenticated } = useUser({
  storagePrefix: 'myapp', // 使用唯一前缀
  useSessionStorage: false, // 使用 localStorage 持久化
  autoRefreshInterval: 15 * 60 * 1000, // 15分钟自动刷新
});

// 检查 localStorage
console.log('Stored token:', localStorage.getItem('myapp_token'));
console.log('Stored user:', localStorage.getItem('myapp_user'));

3. 路由保护不生效

症状: 守卫没有阻止未授权访问

解决方案:

// 检查 RouteProtectionWrapper 的使用
<RouteProtectionWrapper
  guards={[authGuard]} // 确保守卫已正确定义
  loadingElement={<div>验证中...</div>} // 提供加载状态
  component={<ProtectedComponent />}
>
  {/* 不要在这里放置组件 */}
</RouteProtectionWrapper>

// 确保守卫返回布尔值
const authGuard = defineAuth({
  check: (context) => {
    console.log('Auth check:', context.user); // 调试日志
    return !!context.user; // 明确返回布尔值
  }
});

4. 资源加载失败

症状: 国际化资源无法加载

解决方案:

// 启用调试模式
const loader = createI18nLoader({
  debug: true, // 查看详细加载日志
  onError: (locale, error) => {
    console.error(`Loading ${locale} failed:`, error);
    // 检查网络请求是否成功
  }
});

// 检查资源路径
// 确保服务器上存在对应文件
fetch('/locales/zh.json')
  .then(res => res.json())
  .then(data => console.log('Resource loaded:', data))
  .catch(err => console.error('Resource load failed:', err));

// 检查 CORS 设置(如果是跨域请求)

5. 性能问题

症状: 页面加载缓慢

解决方案:

// 启用缓存
const cache = new PerformanceCache<string, any>(100);

// 预加载关键资源
useEffect(() => {
  // 预加载用户常用语言
  loader.preloadResources(['zh', 'en']);

  // 预加载关键数据
  batchProcessor.processBatch(
    ['user', 'settings', 'permissions'],
    async (item) => await fetchData(item)
  );
}, []);

// 使用 React.memo 优化组件
const OptimizedComponent = React.memo(function MyComponent(props) {
  // 组件实现
});

// 使用 useMemo 缓存计算结果
const expensiveValue = useMemo(() => {
  return heavyComputation(data);
}, [data]);

6. TypeScript 类型错误

症状: TypeScript 编译错误

解决方案:

// 确保导入正确的类型
import type {
  AuthOptions,
  GuardOptions,
  I18nClientConfig
} from '@gulibs/react-autoroutes-client';

// 为用户数据定义接口
interface User {
  id: string;
  name: string;
  role: string;
  permissions: string[];
}

// 使用泛型
const { user } = useUser<User, LoginCredentials>({
  // 配置...
});

// 确保 tsconfig.json 包含正确设置
{
  "compilerOptions": {
    "moduleResolution": "node",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

调试工具

// 开发工具组件
function DevTools() {
  const { locale, availableKeys, isUsingVirtualModule } = useI18n();
  const { user, isAuthenticated } = useUser();

  if (process.env.NODE_ENV !== 'development') return null;

  return (
    <div style={{ position: 'fixed', top: 0, right: 0, background: '#f0f0f0', padding: '10px' }}>
      <h4>调试信息</h4>
      <p>当前语言: {locale}</p>
      <p>翻译键数量: {availableKeys.length}</p>
      <p>使用虚拟模块: {isUsingVirtualModule ? '是' : '否'}</p>
      <p>用户认证: {isAuthenticated ? '已登录' : '未登录'}</p>
      <p>用户信息: {JSON.stringify(user, null, 2)}</p>
    </div>
  );
}

📈 性能基准

| 功能 | 冷启动 | 热启动 | 内存占用 | |------|--------|--------|----------| | 基础路由保护 | ~10ms | ~2ms | ~50KB | | 国际化加载 | ~20ms | ~5ms | ~100KB | | 完整功能 | ~50ms | ~10ms | ~200KB |

🤝 与其他库集成

与状态管理库集成

// 与 Redux Toolkit 集成
import { createSlice } from '@reduxjs/toolkit';
import { useUser } from '@gulibs/react-autoroutes-client';

const authSlice = createSlice({
  name: 'auth',
  initialState: { user: null, token: null },
  reducers: {
    setAuth: (state, action) => {
      state.user = action.payload.user;
      state.token = action.payload.token;
    }
  }
});

function useAuthSync() {
  const dispatch = useDispatch();
  const { user, token } = useUser();

  useEffect(() => {
    if (user && token) {
      dispatch(authSlice.actions.setAuth({ user, token }));
    }
  }, [user, token, dispatch]);
}