@xiaonoodles/meetfun-i18n 1.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FIX_WEBPACK_RESOLUTION.md +245 -0
- package/LICENSE +22 -0
- package/MIGRATION_GUIDE.md +253 -0
- package/README.md +482 -0
- package/TROUBLESHOOTING.md +280 -0
- package/VERIFY_FIX.md +272 -0
- package/VUE2_USAGE.md +170 -0
- package/dist/index.d.ts +348 -0
- package/dist/index.esm.js +1167 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +1173 -0
- package/dist/index.js.map +1 -0
- package/dist/vue2/index.cjs +1256 -0
- package/dist/vue2/index.cjs.map +1 -0
- package/dist/vue2/index.d.ts +346 -0
- package/dist/vue2/index.esm.js +1231 -0
- package/dist/vue2/index.esm.js.map +1 -0
- package/package.json +78 -0
- package/vue2/index.d.ts +3 -0
- package/vue2/index.js +3 -0
- package/vue2/index.mjs +4 -0
- package/vue2/package.json +14 -0
- package/vue2.d.ts +3 -0
- package/vue2.mjs +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
# meetfun-i18n
|
|
2
|
+
|
|
3
|
+
基于 vue-i18n 的 uni-app 国际化解决方案,支持 **Vue2/Vue3**,支持多语言缓存、远程语言包、动态加载等功能。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🚀 **开箱即用** - 简单的 API 设计,快速集成到 uni-app 项目
|
|
8
|
+
- 🎭 **Vue2/Vue3 双支持** - 同时支持 Vue2 + vue-i18n@8 和 Vue3 + vue-i18n@9
|
|
9
|
+
- 📦 **多语言缓存** - 自动缓存语言包到本地,支持离线使用
|
|
10
|
+
- 🔄 **动态语言包** - 支持从远程服务器动态加载语言包
|
|
11
|
+
- 🎯 **缺失键上报** - 自动收集并上报缺失的翻译键
|
|
12
|
+
- 🔧 **变量替换** - 支持复杂的变量替换,包括嵌套对象访问
|
|
13
|
+
- 🎨 **代理模式** - 内置国际化代理功能,轻松处理枚举翻译
|
|
14
|
+
- 📱 **跟随系统** - 支持跟随系统语言自动切换
|
|
15
|
+
- 💪 **TypeScript** - 完整的类型定义支持
|
|
16
|
+
|
|
17
|
+
## 安装
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 使用 pnpm
|
|
21
|
+
pnpm add meetfun-i18n
|
|
22
|
+
|
|
23
|
+
# Vue2 项目还需要安装
|
|
24
|
+
pnpm add vue@^2.7.0 vue-i18n@^8.0.0
|
|
25
|
+
|
|
26
|
+
# Vue3 项目需要安装
|
|
27
|
+
pnpm add vue@^3.0.0 vue-i18n@^9.0.0
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 引入方式
|
|
31
|
+
|
|
32
|
+
根据你的项目类型选择对应的引入方式:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
// Vue3 项目(默认)
|
|
36
|
+
import { createMeetFunI18n } from 'meetfun-i18n'
|
|
37
|
+
|
|
38
|
+
// Vue2 项目
|
|
39
|
+
import { createMeetFunI18n } from 'meetfun-i18n/vue2'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 快速开始
|
|
43
|
+
|
|
44
|
+
### 1. 准备语言包文件
|
|
45
|
+
|
|
46
|
+
创建语言包文件,例如 `src/locales/zh-Hans.json`:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"TALENTS": {
|
|
51
|
+
"欢迎": "欢迎",
|
|
52
|
+
"你好,{name}": "你好,{name}"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. 创建 API 函数
|
|
58
|
+
|
|
59
|
+
创建获取语言包的 API 函数,例如 `src/api/translate.ts`:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { translateRequest } from '@/utils/request'
|
|
63
|
+
import type { LangDictResponse, QueryLangDictColdDataParams } from '@meetfun/i18n'
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 获取热数据(常用翻译)
|
|
67
|
+
*/
|
|
68
|
+
export const queryLangDictHotData = (params: { systemCode: string }) => {
|
|
69
|
+
return translateRequest.post<LangDictResponse>(
|
|
70
|
+
'/api/translate/langDict/queryLangDictHotData',
|
|
71
|
+
params,
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 获取冷数据(缺失翻译上报)
|
|
77
|
+
*/
|
|
78
|
+
export const queryLangDictColdData = (params: QueryLangDictColdDataParams) => {
|
|
79
|
+
return translateRequest.post<LangDictResponse>(
|
|
80
|
+
'/api/translate/langDict/queryLangDictColdData',
|
|
81
|
+
params,
|
|
82
|
+
{ custom: { loading: false } },
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 3. 初始化 i18n
|
|
88
|
+
|
|
89
|
+
在 `src/locales/index.ts` 中初始化:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { createMeetFunI18n } from '@meetfun/i18n'
|
|
93
|
+
import { queryLangDictHotData, queryLangDictColdData } from '@/api/translate'
|
|
94
|
+
import zhHans from './zh-Hans.json'
|
|
95
|
+
import zhHant from './zh-Hant.json'
|
|
96
|
+
import en from './en.json'
|
|
97
|
+
|
|
98
|
+
// 基础语言包
|
|
99
|
+
const baseMessages = {
|
|
100
|
+
'zh-Hans': zhHans,
|
|
101
|
+
'zh-Hant': zhHant,
|
|
102
|
+
en: en,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// API 配置
|
|
106
|
+
const apiConfig = {
|
|
107
|
+
queryLangDictHotData,
|
|
108
|
+
queryLangDictColdData,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 创建 i18n 实例
|
|
112
|
+
const i18nInstance = createMeetFunI18n(baseMessages, apiConfig, {
|
|
113
|
+
defaultLocale: 'zh-Hans',
|
|
114
|
+
defaultLangDictDomainCode: 'TALENTS',
|
|
115
|
+
systemCode: 'TALENTS_STUDENT',
|
|
116
|
+
localeCacheKey: 'APP_LOCALE_SETTING',
|
|
117
|
+
langDictCacheKey: 'APP_LANG_DICT_CACHE',
|
|
118
|
+
cacheMaxAge: 365 * 24 * 60 * 60 * 1000, // 365天
|
|
119
|
+
reportDelay: 5000, // 5秒
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
export default i18nInstance
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 4. 在 Vue 应用中使用
|
|
126
|
+
|
|
127
|
+
在 `main.ts` 中安装:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { createSSRApp } from 'vue'
|
|
131
|
+
import i18nInstance from './locales'
|
|
132
|
+
|
|
133
|
+
export function createApp() {
|
|
134
|
+
const app = createSSRApp(App)
|
|
135
|
+
|
|
136
|
+
// 安装 vue-i18n
|
|
137
|
+
app.use(i18nInstance.getI18n())
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
app,
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 5. 在组件中使用
|
|
146
|
+
|
|
147
|
+
```vue
|
|
148
|
+
<template>
|
|
149
|
+
<view>
|
|
150
|
+
<!-- 使用 $t 函数翻译 -->
|
|
151
|
+
<text>{{ $t('欢迎') }}</text>
|
|
152
|
+
|
|
153
|
+
<!-- 带变量的翻译 -->
|
|
154
|
+
<text>{{ $t('你好,{name}', { name: '张三' }) }}</text>
|
|
155
|
+
</view>
|
|
156
|
+
</template>
|
|
157
|
+
|
|
158
|
+
<script setup lang="ts">
|
|
159
|
+
import i18nInstance from '@/locales'
|
|
160
|
+
|
|
161
|
+
// 直接使用 i18n 实例
|
|
162
|
+
const welcomeText = i18nInstance.$t('欢迎')
|
|
163
|
+
|
|
164
|
+
// 带参数
|
|
165
|
+
const greetingText = i18nInstance.$t('你好,{name}', { name: '李四' })
|
|
166
|
+
</script>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## API 文档
|
|
170
|
+
|
|
171
|
+
### createMeetFunI18n(baseMessages, apiConfig, userConfig?)
|
|
172
|
+
|
|
173
|
+
创建 i18n 实例的工厂函数。
|
|
174
|
+
|
|
175
|
+
**参数:**
|
|
176
|
+
|
|
177
|
+
- `baseMessages`: `Record<string, any>` - 基础语言包
|
|
178
|
+
- `apiConfig`: `ApiConfig` - API 配置
|
|
179
|
+
- `queryLangDictHotData`: 获取热数据的函数
|
|
180
|
+
- `queryLangDictColdData`: 获取冷数据的函数
|
|
181
|
+
- `userConfig?`: `Partial<I18nConfig>` - 用户配置(可选)
|
|
182
|
+
- `defaultLocale?`: 默认语言,默认 `'zh-Hans'`
|
|
183
|
+
- `defaultLangDictDomainCode?`: 默认领域代码,默认 `'TALENTS'`
|
|
184
|
+
- `systemCode?`: 系统代码
|
|
185
|
+
- `localeCacheKey?`: 语言设置缓存键,默认 `'APP_LOCALE_SETTING'`
|
|
186
|
+
- `langDictCacheKey?`: 语言包缓存键,默认 `'APP_LANG_DICT_CACHE'`
|
|
187
|
+
- `cacheMaxAge?`: 缓存最大有效期(毫秒),默认 365 天
|
|
188
|
+
- `reportDelay?`: 上报延迟时间(毫秒),默认 5000ms
|
|
189
|
+
|
|
190
|
+
**返回:** `MeetFunI18n` 实例
|
|
191
|
+
|
|
192
|
+
### MeetFunI18n 实例方法
|
|
193
|
+
|
|
194
|
+
#### $t(key, params?)
|
|
195
|
+
|
|
196
|
+
翻译函数,支持变量替换。
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
const text = i18nInstance.$t('你好,{name}', { name: '张三' })
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### fetchLangDictHotData()
|
|
203
|
+
|
|
204
|
+
获取远程语言包(热数据)。
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
await i18nInstance.fetchLangDictHotData()
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### switchLocale(locale)
|
|
211
|
+
|
|
212
|
+
切换语言。
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
import { LANGUAGE_OPTIONS_CONFIGURATION } from '@meetfun/i18n'
|
|
216
|
+
|
|
217
|
+
// 切换到英文
|
|
218
|
+
i18nInstance.switchLocale(LANGUAGE_OPTIONS_CONFIGURATION.EN)
|
|
219
|
+
|
|
220
|
+
// 跟随系统
|
|
221
|
+
i18nInstance.switchLocale(LANGUAGE_OPTIONS_CONFIGURATION.FOLLOW_SYSTEM)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### getCurrentLocale()
|
|
225
|
+
|
|
226
|
+
获取当前语言。
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const locale = i18nInstance.getCurrentLocale() // 'zh-Hans'
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### getHeaderLang()
|
|
233
|
+
|
|
234
|
+
获取用于请求头的语言标识。
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const headerLang = i18nInstance.getHeaderLang() // 'zh_cn'
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### updateI18nMessages(langDictData, saveToCache?)
|
|
241
|
+
|
|
242
|
+
更新语言包。
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
await i18nInstance.updateI18nMessages(newLangData, true)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### flushMissingKeys()
|
|
249
|
+
|
|
250
|
+
立即上报所有缓存的缺失翻译键。
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
await i18nInstance.flushMissingKeys()
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
#### getTranslationKeysStats()
|
|
257
|
+
|
|
258
|
+
获取翻译键统计信息。
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const stats = i18nInstance.getTranslationKeysStats()
|
|
262
|
+
console.log(stats.missingKeys) // { TALENTS: 10 }
|
|
263
|
+
console.log(stats.usedKeys) // { TALENTS: 100 }
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### clearLangDictCache()
|
|
267
|
+
|
|
268
|
+
清除语言包缓存。
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
i18nInstance.clearLangDictCache()
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## 高级功能
|
|
275
|
+
|
|
276
|
+
### 国际化代理 - 枚举翻译
|
|
277
|
+
|
|
278
|
+
使用代理模式轻松处理枚举翻译:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import i18nInstance from '@/locales'
|
|
282
|
+
|
|
283
|
+
// 定义角色枚举翻译映射
|
|
284
|
+
const roleNamesMap = {
|
|
285
|
+
PRODUCING_AREA: 'role.PRODUCING_AREA',
|
|
286
|
+
PRESENTATION_AREA: 'role.PRESENTATION_AREA',
|
|
287
|
+
STORE_MANAGER: 'role.STORE_MANAGER',
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// 创建代理对象
|
|
291
|
+
const roleNames = i18nInstance.createI18nProxy(roleNamesMap)
|
|
292
|
+
|
|
293
|
+
// 直接访问即可获得翻译后的文本
|
|
294
|
+
console.log(roleNames.PRODUCING_AREA) // '产区'
|
|
295
|
+
console.log(roleNames.STORE_MANAGER) // '店长'
|
|
296
|
+
|
|
297
|
+
// 也可以使用 createEnumI18nProxy(语义化别名)
|
|
298
|
+
const statusNames = i18nInstance.createEnumI18nProxy({
|
|
299
|
+
ACTIVE: 'status.active',
|
|
300
|
+
INACTIVE: 'status.inactive',
|
|
301
|
+
})
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### 变量替换
|
|
305
|
+
|
|
306
|
+
支持嵌套对象访问的变量替换:
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
const template = '用户 {user.name} 的年龄是 {user.age}'
|
|
310
|
+
const params = {
|
|
311
|
+
user: {
|
|
312
|
+
name: '张三',
|
|
313
|
+
age: 25,
|
|
314
|
+
},
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const result = i18nInstance.interpolateVariables(template, params)
|
|
318
|
+
console.log(result) // '用户 张三 的年龄是 25'
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### 条件编译支持
|
|
322
|
+
|
|
323
|
+
在不同的编译环境使用不同的系统代码:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
let systemCode = 'TALENTS_STUDENT'
|
|
327
|
+
// #ifdef SYSTEM_S
|
|
328
|
+
systemCode = 'TALENTS_STUDENT'
|
|
329
|
+
// #endif
|
|
330
|
+
|
|
331
|
+
// #ifdef SYSTEM_M
|
|
332
|
+
systemCode = 'TALENTS_MANAGEMENT_APP'
|
|
333
|
+
// #endif
|
|
334
|
+
|
|
335
|
+
const i18nInstance = createMeetFunI18n(baseMessages, apiConfig, {
|
|
336
|
+
systemCode,
|
|
337
|
+
})
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## 语言包数据格式
|
|
341
|
+
|
|
342
|
+
服务器返回的语言包格式:
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"zh_cn": {
|
|
347
|
+
"TALENTS": {
|
|
348
|
+
"欢迎": "欢迎",
|
|
349
|
+
"你好": "你好"
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
"zh_hk": {
|
|
353
|
+
"TALENTS": {
|
|
354
|
+
"欢迎": "歡迎",
|
|
355
|
+
"你好": "你好"
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
"en": {
|
|
359
|
+
"TALENTS": {
|
|
360
|
+
"欢迎": "Welcome",
|
|
361
|
+
"你好": "Hello"
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
库会自动将 `zh_cn` 转换为 `zh-Hans`,`zh_hk` 转换为 `zh-Hant`。
|
|
368
|
+
|
|
369
|
+
## 最佳实践
|
|
370
|
+
|
|
371
|
+
### 1. 在 App.vue 中加载远程语言包
|
|
372
|
+
|
|
373
|
+
```vue
|
|
374
|
+
<script setup lang="ts">
|
|
375
|
+
import { onLaunch } from '@dcloudio/uni-app'
|
|
376
|
+
import i18nInstance from '@/locales'
|
|
377
|
+
|
|
378
|
+
onLaunch(() => {
|
|
379
|
+
// 加载远程语言包
|
|
380
|
+
i18nInstance.fetchLangDictHotData()
|
|
381
|
+
})
|
|
382
|
+
</script>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### 2. 在页面卸载时上报缺失键
|
|
386
|
+
|
|
387
|
+
```vue
|
|
388
|
+
<script setup lang="ts">
|
|
389
|
+
import { onUnmounted } from 'vue'
|
|
390
|
+
import i18nInstance from '@/locales'
|
|
391
|
+
|
|
392
|
+
onUnmounted(() => {
|
|
393
|
+
// 立即上报缺失的翻译键
|
|
394
|
+
i18nInstance.flushMissingKeys()
|
|
395
|
+
})
|
|
396
|
+
</script>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### 3. 语言切换组件
|
|
400
|
+
|
|
401
|
+
```vue
|
|
402
|
+
<template>
|
|
403
|
+
<view>
|
|
404
|
+
<picker :value="langIndex" :range="langOptions" @change="handleLangChange">
|
|
405
|
+
<view>{{ langOptions[langIndex] }}</view>
|
|
406
|
+
</picker>
|
|
407
|
+
</view>
|
|
408
|
+
</template>
|
|
409
|
+
|
|
410
|
+
<script setup lang="ts">
|
|
411
|
+
import { ref } from 'vue'
|
|
412
|
+
import { LANGUAGE_OPTIONS_CONFIGURATION } from '@meetfun/i18n'
|
|
413
|
+
import i18nInstance from '@/locales'
|
|
414
|
+
|
|
415
|
+
const langOptions = ['跟随系统', '简体中文', '繁體中文', 'English']
|
|
416
|
+
const langIndex = ref(0)
|
|
417
|
+
|
|
418
|
+
const handleLangChange = (e: any) => {
|
|
419
|
+
const index = e.detail.value
|
|
420
|
+
langIndex.value = index
|
|
421
|
+
|
|
422
|
+
const langMap = [
|
|
423
|
+
LANGUAGE_OPTIONS_CONFIGURATION.FOLLOW_SYSTEM,
|
|
424
|
+
LANGUAGE_OPTIONS_CONFIGURATION.ZH_HANS,
|
|
425
|
+
LANGUAGE_OPTIONS_CONFIGURATION.ZH_HANT,
|
|
426
|
+
LANGUAGE_OPTIONS_CONFIGURATION.EN,
|
|
427
|
+
]
|
|
428
|
+
|
|
429
|
+
i18nInstance.switchLocale(langMap[index])
|
|
430
|
+
|
|
431
|
+
uni.showToast({
|
|
432
|
+
title: '切换成功',
|
|
433
|
+
icon: 'success',
|
|
434
|
+
})
|
|
435
|
+
}
|
|
436
|
+
</script>
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## Vue2 支持
|
|
440
|
+
|
|
441
|
+
本库完整支持 Vue2 项目,详细使用方式请查看:[Vue2 使用指南](./VUE2_USAGE.md)
|
|
442
|
+
|
|
443
|
+
**关键区别:**
|
|
444
|
+
- Vue2 项目从 `meetfun-i18n/vue2` 引入
|
|
445
|
+
- Vue3 项目从 `meetfun-i18n` 引入(默认)
|
|
446
|
+
- API 使用方式完全一致
|
|
447
|
+
|
|
448
|
+
## 版本要求
|
|
449
|
+
|
|
450
|
+
- **Vue2**: Vue 2.7+ 和 vue-i18n 8.x
|
|
451
|
+
- **Vue3**: Vue 3.x 和 vue-i18n 9.x
|
|
452
|
+
|
|
453
|
+
## 注意事项
|
|
454
|
+
|
|
455
|
+
1. **uni 对象依赖**:本库依赖 uni-app 的 `uni` 全局对象,仅适用于 uni-app 项目。
|
|
456
|
+
2. **API 配置**:必须提供 `queryLangDictHotData` 和 `queryLangDictColdData` 两个 API 函数。
|
|
457
|
+
3. **缓存策略**:语言包缓存默认有效期为 365 天,可根据需求调整。
|
|
458
|
+
4. **缺失键上报**:使用防抖机制,默认延迟 5 秒上报,避免频繁请求。
|
|
459
|
+
5. **Vue 版本选择**:确保使用正确的引入路径(Vue2 使用 `/vue2` 子路径)。
|
|
460
|
+
|
|
461
|
+
## 类型定义
|
|
462
|
+
|
|
463
|
+
本库提供完整的 TypeScript 类型定义,支持类型提示和检查。
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
import type {
|
|
467
|
+
I18nConfig,
|
|
468
|
+
ApiConfig,
|
|
469
|
+
LangDictResponse,
|
|
470
|
+
TranslationKeysStats,
|
|
471
|
+
// ... 更多类型
|
|
472
|
+
} from '@meetfun/i18n'
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
## License
|
|
476
|
+
|
|
477
|
+
MIT
|
|
478
|
+
|
|
479
|
+
## 作者
|
|
480
|
+
|
|
481
|
+
meetfun
|
|
482
|
+
|