/** * i18n-reloader.ts — i18n 语言包热替换(Phase 2B) * * Soft Reload 时重新加载编译产物中的语言包文件, * 并通过 configureI18n 回调更新框架的 i18n 配置。 * * 核心流程: * * 1. 检查 outDir/locales/ 目录是否存在 * 2. 扫描目录下的所有 .js 文件(编译产物) * 3. 按文件名提取语言代码(如 zh-CN.js → 'zh-CN') * 4. require() 每个语言文件(require.cache 已被 cache-invalidator 清除, * 这里会重新从磁盘加载新编译的 .js) * 5. 通过 configureI18n 回调将新的语言包注册到 schema-dsl * * 与 i18n-loader.ts 的区别: * * | 对比项 | i18n-loader.ts(启动时) | i18n-reloader.ts(热重载时) | * |-----------------|-----------------------------------|-------------------------------------| * | 调用时机 | bootstrap 阶段(首次加载) | soft reload 时(用户修改语言文件后) | * | 加载方式 | ESM dynamic import(file:// URL) | CJS require(编译产物 .js) | * | 缓存处理 | 无需(首次加载) | require.cache 已被前置步骤清除 | * | i18n 注册 | schemaAdapter.configure() 直接调用 | 通过 configureI18n 回调解耦 | * | 子目录模式支持 | 仅平铺模式(模式 A) | 仅平铺模式(模式 A) | * * 安全保证: * * - locales 目录不存在 → 静默跳过(返回空结果) * - 语言文件 require 失败 → 跳过并打印警告(不阻塞重载流程) * - 无有效语言文件 → 静默跳过(不调用 configureI18n) * - configureI18n 回调失败 → 打印警告(不阻塞重载流程) * * @module lib/dev/i18n-reloader * @see 11b-soft-reload.md §6(i18n 热替换) * @see i18n-loader.ts(启动时语言包加载器) * @see 06b-error.md §1.7(多语言配置方式) * @see IMPLEMENTATION-PLAN.md 任务 2.2b */ /** * 错误消息映射类型 * * 与 schema-dsl 的 ErrorMessages 类型兼容。 * key: 错误 key(如 'user.not_found') * value: { code: number, message: string } 或其他 schema-dsl 支持的格式 */ export type ErrorMessages = Record; /** * i18n 配置回调函数类型 * * 由调用方提供,用于将加载的语言包注册到 schema-dsl。 * 通常封装了 schemaAdapter.configure({ i18n: locales }) 调用。 * * 这样设计是为了解耦 i18n-reloader 与 schema-dsl 的直接依赖, * 便于单元测试和未来切换 i18n 实现。 * * @param locales 语言代码 → 错误消息映射 的字典(如 { 'zh-CN': {...}, 'en-US': {...} }) */ export type ConfigureI18nFn = (locales: Record) => void; /** * 最小化的 Logger 接口(仅包含 i18n-reloader 需要的方法) */ export interface I18nReloaderLogger { info(...args: unknown[]): void; warn(...args: unknown[]): void; debug(...args: unknown[]): void; error(...args: unknown[]): void; } /** * i18n 重载选项 */ export interface ReloadLocalesOptions { /** * 编译产物目录(.vext/dev/ 的绝对路径) * * i18n-reloader 会在 outDir/locales/ 下查找语言文件。 */ outDir: string; /** * Logger 实例 */ logger: I18nReloaderLogger; /** * i18n 配置回调函数 * * 加载完所有语言文件后,调用此函数将新语言包注册到 i18n 系统。 * 如果不提供,则只加载文件但不注册(仅用于测试或手动注册场景)。 */ configureI18n?: ConfigureI18nFn; } /** * i18n 重载结果 */ export interface I18nReloadResult { /** 成功加载的语言代码列表(如 ['zh-CN', 'en-US']) */ loadedLocales: string[]; /** 加载失败的语言文件列表(文件名) */ failedFiles: string[]; /** 是否成功注册到 i18n 系统 */ configured: boolean; } /** * isLocaleFile — 判断文件名是否为有效的语言文件 * * 条件: * 1. 以 .js 结尾(编译产物) * 2. 不是 .js.map(source map) * 3. 去掉扩展名后匹配语言代码格式 * * @param filename 文件名(不含目录路径) * @returns 是否为有效的语言文件 */ export declare function isLocaleFile(filename: string): boolean; /** * extractLocaleCode — 从文件名中提取语言代码 * * @param filename 文件名(如 'zh-CN.js') * @returns 语言代码(如 'zh-CN') */ export declare function extractLocaleCode(filename: string): string; /** * reloadLocales — 重载 i18n 语言包 * * 扫描 outDir/locales/ 目录,require() 每个语言文件, * 并通过 configureI18n 回调注册到 i18n 系统。 * * require.cache 已在前面被 cache-invalidator 清除, * 这里 require() 会从磁盘重新加载最新编译产物。 * * @param options 重载选项 * @returns 重载结果 */ export declare function reloadLocales(options: ReloadLocalesOptions): Promise; /** * shouldReloadLocales — 判断变更文件列表中是否包含 locale 文件 * * 用于 soft reload 主流程中快速判断是否需要执行 i18n 重载。 * 避免在无 locale 变更时执行不必要的 reloadLocales。 * * @param filePaths 变更文件的相对路径列表(如 ['routes/user.ts', 'locales/zh-CN.ts']) * @returns 是否包含 locale 文件 */ export declare function shouldReloadLocales(filePaths: string[]): boolean; /** * createI18nReloader — 创建一个预配置的 i18n 重载函数 * * 将 logger 和 configureI18n 绑定后,返回一个只需 outDir 的 * 简化重载函数。适合在 soft reload 主流程中使用。 * * @param logger Logger 实例 * @param configureI18n i18n 配置回调 * @returns 简化的 i18n 重载函数 * * @example * ```ts * // 初始化时 * const reloadI18n = createI18nReloader(app.logger, (locales) => { * schemaAdapter.configure({ i18n: locales }) * }) * * // soft reload 时 * if (shouldReloadLocales(filePaths)) { * await reloadI18n(outDir) * } * ``` */ export declare function createI18nReloader(logger: I18nReloaderLogger, configureI18n?: ConfigureI18nFn): (outDir: string) => Promise;