npm package: @mico_fe/vite-plugin-i18n-react
Description: Vite plugin for React auto i18n - Chinese → t(key) with Babel
Author: manwang
Latest version: 1.0.0

# @mico_fe/vite-plugin-i18n-react

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

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

## 📦 安装

```bash
npm install @mico_fe/vite-plugin-i18n-react @mico_fe/i18n-react -D
# 或
pnpm add @mico_fe/vite-plugin-i18n-react @mico_fe/i18n-react -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 react from '@vitejs/plugin-react'
import reactI18n from '@mico_fe/vite-plugin-i18n-react'

export default defineConfig({
  plugins: [
    react(),
    reactI18n({
      // 语言包目录（相对于项目根目录）
      localesDir: 'src/locales',
      
      // 源语言代码
      sourceLocale: 'zh-CN',
      
      // 翻译函数名（默认 't'）
      translateFn: 't',
      
      // 排除 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'` | 翻译函数名 |
| `excludeConsole` | `boolean` | `true` | 排除 console.* 中的中文 |
| `enableInDev` | `boolean` | `true` | 开发模式是否启用 |
| `exclude` | `(string \| RegExp)[]` | `[/node_modules/]` | 排除的文件模式 |
| `debug` | `boolean` | `false` | 调试模式 |
| `onMissing` | `'warn' \| 'error' \| 'ignore'` | `'warn'` | 缺少翻译的处理方式 |

## 🔧 转换规则

### 1. JSX 文本

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

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

### 2. JSX 属性

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

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

### 3. 字符串变量

```tsx
// 转换前
const message = '操作成功'
const title = '确认删除？'

// 转换后
const message = t('message.success')
const title = t('dialog.confirmDelete')
```

### 4. 不转换的情况

```tsx
// console.log 中的中文（excludeConsole: true）
console.log('调试信息')  // 不转换

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

## 📁 语言包格式

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

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

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

## 🔌 与 @mico_fe/i18n-react 配合使用

```tsx
// main.tsx
import { createRoot } from 'react-dom/client'
import { I18nProvider } from '@mico_fe/i18n-react'
import localeModule from './locales'
import App from './App'

createRoot(document.getElementById('root')!).render(
  <I18nProvider localeModule={localeModule}>
    <App />
  </I18nProvider>
)

// App.tsx
import { useTranslation } from '@mico_fe/i18n-react'

function App() {
  const { t, setLang } = useTranslation()
  
  return (
    <div>
      {/* 这些中文会在编译时自动转换为 t() 调用 */}
      <h1>欢迎使用</h1>
      <p>这是一个自动国际化的示例</p>
      <button onClick={() => setLang('en-US')}>
        切换到英文
      </button>
    </div>
  )
}
```

## ⚠️ 注意事项

### 1. 必须在 I18nProvider 内使用

由于 `t` 函数来自 `useTranslation` Hook，组件必须在 `I18nProvider` 内：

```tsx
// ✅ 正确
<I18nProvider localeModule={localeModule}>
  <App />  {/* App 内可以使用自动转换 */}
</I18nProvider>

// ❌ 错误：在 Provider 外部
<App />  {/* t 函数未定义 */}
```

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

插件通过**反向映射**来查找 key，如果语言包中没有某个中文，将无法转换并显示警告。

### 3. 动态字符串

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

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

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

## 🐛 调试

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

```ts
reactI18n({
  debug: true,
})
```

输出示例：
```
[vite-plugin-i18n-react] Processing: src/App.tsx
[babel-plugin-auto-i18n] Transformed: 你好世界 → t('message.hello')
[babel-plugin-auto-i18n] Missing: 未找到的文案
```

## 📄 License

MIT