npm package: @mico_fe/vite-plugin-i18n-vue
Description: Vite plugin for Vue auto i18n - Chinese → $t(key)
Author: manwang
Latest version: 1.0.0

# @mico_fe/vite-plugin-i18n-vue

> Vue 3 + Vite 编译时自动国际化插件

**核心功能**：在编译时自动将中文转换为 `$t(key)` 调用，实现零运行时开销的国际化。

## 📦 安装

```bash
npm install @mico_fe/vite-plugin-i18n-vue @mico_fe/i18n-vue -D
# 或
pnpm add @mico_fe/vite-plugin-i18n-vue @mico_fe/i18n-vue -D
```

## 🎯 工作原理

```
源代码                          编译后
┌─────────────────────┐      ┌─────────────────────────┐
│ <p>你好世界</p>      │  →   │ <p>{{ $t('xxx') }}</p>  │
│ <button>提交</button>│  →   │ <button>{{ $t('yyy') }}</button>│
│ placeholder="请输入" │  →   │ :placeholder="$t('zzz')"│
└─────────────────────┘      └─────────────────────────┘
```

## 🚀 配置

### vite.config.ts

```ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueI18n from '@mico_fe/vite-plugin-i18n-vue'

export default defineConfig({
  plugins: [
    vue(),
    vueI18n({
      // 语言包目录（相对于项目根目录）
      localesDir: 'src/locales',
      
      // 源语言代码
      sourceLocale: 'zh-CN',
      
      // 模板中的翻译函数名（默认 '$t'）
      translateFn: '$t',
      
      // 脚本中的翻译函数名（默认 't'）
      scriptTranslateFn: 't',
      
      // 是否转换 <script> 中的中文（默认 true）
      transformScript: true,
      
      // 排除 console.log 中的中文（默认 true）
      excludeConsole: true,
      
      // 开发模式是否启用（默认 true）
      enableInDev: true,
      
      // 排除的文件模式
      exclude: [/node_modules/, /\.d\.ts$/],
      
      // 调试模式，打印转换日志
      debug: false,
    }),
  ],
})
```

## 📖 配置选项

| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `localesDir` | `string` | `'src/locales'` | 语言包目录 |
| `sourceLocale` | `string` | `'zh-CN'` | 源语言代码 |
| `translateFn` | `string` | `'$t'` | 模板中的翻译函数名 |
| `scriptTranslateFn` | `string` | `'t'` | 脚本中的翻译函数名 |
| `transformScript` | `boolean` | `true` | 是否转换脚本中的中文 |
| `excludeConsole` | `boolean` | `true` | 排除 console.* 中的中文 |
| `enableInDev` | `boolean` | `true` | 开发模式是否启用 |
| `exclude` | `(string \| RegExp)[]` | `[/node_modules/]` | 排除的文件模式 |
| `debug` | `boolean` | `false` | 调试模式 |

## 🔧 转换规则

### 1. 模板文本

```vue
<!-- 转换前 -->
<p>你好世界</p>
<span>欢迎使用</span>

<!-- 转换后 -->
<p>{{ $t('message.hello') }}</p>
<span>{{ $t('message.welcome') }}</span>
```

### 2. 属性值

```vue
<!-- 转换前 -->
<input placeholder="请输入用户名" />
<button title="点击提交">提交</button>

<!-- 转换后 -->
<input :placeholder="$t('form.enterUsername')" />
<button :title="$t('button.clickSubmit')">{{ $t('button.submit') }}</button>
```

### 3. 脚本中的字符串

```vue
<script setup>
// 转换前
const message = '操作成功'
alert('保存完成')

// 转换后
const message = t('message.success')
alert(t('message.saved'))
</script>
```

### 4. 不转换的情况

```vue
<script setup>
// console.log 中的中文（excludeConsole: true）
console.log('调试信息')  // 不转换

// 已经在翻译函数中的
t('已有的key')  // 不转换
$t('已有的key')  // 不转换
tt('中文文案')  // 不转换
</script>
```

## 📁 语言包格式

插件会自动读取 `localesDir` 目录下的 JSON 文件：

```
src/locales/
├── zh-CN.json    # 源语言（必须包含中文文案）
├── en-US.json    # 目标语言
└── index.ts      # 语言模块
```

**zh-CN.json**（源语言必须有中文）
```json
{
  "message.hello": "你好世界",
  "message.welcome": "欢迎使用",
  "form.enterUsername": "请输入用户名",
  "button.submit": "提交"
}
```

**en-US.json**
```json
{
  "message.hello": "Hello World",
  "message.welcome": "Welcome",
  "form.enterUsername": "Enter username",
  "button.submit": "Submit"
}
```

## ⚠️ 注意事项

### 1. 语言包必须包含所有中文

插件通过**反向映射**（中文 → key）来查找对应的 key。如果语言包中没有某个中文文案，将无法转换。

```json
// ❌ 错误：只有英文
{ "button.submit": "Submit" }

// ✅ 正确：中文语言包必须有中文
{ "button.submit": "提交" }
```

### 2. 确保 key 的唯一性

同一个中文文案应该对应唯一的 key：

```json
// ⚠️ 注意：相同中文会映射到第一个 key
{
  "button.confirm": "确定",
  "dialog.ok": "确定"  // 会被忽略，"确定" 已映射到 button.confirm
}
```

### 3. 动态字符串

动态拼接的字符串可能无法正确转换：

```ts
// ⚠️ 可能无法转换
const msg = '你好' + name

// ✅ 建议使用参数
const msg = t('message.hello', { name })
```

## 🐛 调试

开启 debug 模式查看转换详情：

```ts
vueI18n({
  debug: true,  // 控制台打印转换日志
})
```

输出示例：
```
[vite-plugin-i18n-vue] Processing: src/App.vue
[vite-plugin-i18n-vue] Transformed: 你好世界 → $t('message.hello')
[vite-plugin-i18n-vue] Transformed: 提交 → $t('button.submit')
```

## 📄 License

MIT