From 12401e97420df05d5f027988a5c2a6e3c7b5bb4f Mon Sep 17 00:00:00 2001 From: jingrow Date: Mon, 29 Dec 2025 03:31:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dvite=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E6=AD=A3=E5=88=99=E5=8C=B9=E9=85=8D=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/vite-plugin-translate.mjs | 232 +++++++++++++++++----------- 1 file changed, 140 insertions(+), 92 deletions(-) diff --git a/dashboard/vite-plugin-translate.mjs b/dashboard/vite-plugin-translate.mjs index 064c3a7..c9dd00a 100644 --- a/dashboard/vite-plugin-translate.mjs +++ b/dashboard/vite-plugin-translate.mjs @@ -7,10 +7,9 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); /** - * Vite 插件:构建时直接读取 CSV,替换代码中的 t('xxx') 为翻译文本 - * 无需生成任何中间文件,直接从 CSV 读取并替换 + * Vite 插件:构建时直接读取 CSV,替换代码中的 $t('xxx') 为翻译文本 * @param {object} options - 插件选项 - * @param {string} options.locale - 目标语言代码,从 vite.config.ts 传递 + * @param {string} options.locale - 目标语言代码 */ function vitePluginTranslate(options = {}) { let translations = {}; @@ -18,111 +17,173 @@ function vitePluginTranslate(options = {}) { return { name: 'vite-plugin-translate', - enforce: 'pre', // 在 Vue 插件之前执行,处理原始模板 + enforce: 'pre', configResolved(config) { - // 直接读取 CSV 翻译文件(与后端共享同一数据源) if (locale && locale !== 'en') { const csvPath = path.resolve(__dirname, `../jcloud/translations/${locale}.csv`); if (fs.existsSync(csvPath)) { translations = parseCSV(csvPath); - console.log(`[translate] Loaded ${Object.keys(translations).length} translations from ${csvPath}`); - } else { - console.warn(`[translate] CSV file not found: ${csvPath}, translations will not be replaced`); } } }, transform(code, id) { - // 只处理 .vue, .js, .ts 文件 - if (!/\.(vue|js|ts|jsx|tsx)$/.test(id)) { - return null; - } - - // 如果是英文,不替换 - if (locale === 'en') { - return null; - } - - // 如果翻译为空,警告但不阻止(可能 CSV 文件不存在,使用原文) - if (Object.keys(translations).length === 0) { - console.warn(`[translate] No translations loaded for locale: ${locale}, skipping replacement`); + const fileMatches = /\.(vue|js|ts|jsx|tsx)(\?.*)?$/.test(id); + if (!fileMatches || locale === 'en' || Object.keys(translations).length === 0) { return null; } let replaced = code; - const isVueFile = id.endsWith('.vue'); + const isVueFile = id.includes('.vue') && !id.includes('?vue&type=style'); if (isVueFile) { - // 分离