@dune2/tools 0.4.15 → 0.5.1
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/package.json +1 -1
- package/src/i18n/compile.ts +20 -0
- package/src/i18n/duneI18n.ts +14 -62
- package/src/i18n/enums.ts +2 -0
- package/src/i18n/index.ts +0 -1
- package/src/i18n/loadPlatformLocaleResource.ts +0 -72
package/package.json
CHANGED
package/src/i18n/compile.ts
CHANGED
|
@@ -74,3 +74,23 @@ export function compileMessage(
|
|
|
74
74
|
return message;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 编译消息函数
|
|
80
|
+
* 使用建议:
|
|
81
|
+
* 1. 在 rsc 中直接使用,会减少 client 端的打包大小
|
|
82
|
+
* 2. 在 spa 中直接使用,会增加 client 端的打包大小
|
|
83
|
+
*/
|
|
84
|
+
export function compileMessages(msgs: Record<string, string>) {
|
|
85
|
+
// 创建一个空对象用于存储编译后的消息
|
|
86
|
+
const compiled: Record<string, any> = {};
|
|
87
|
+
|
|
88
|
+
// 遍历输入的消息对象的键
|
|
89
|
+
Object.keys(msgs).forEach((k) => {
|
|
90
|
+
// 将编译后的消息存入 compiled 对象
|
|
91
|
+
compiled[k] = compileMessage(msgs[k] || k);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// 返回编译后的消息对象
|
|
95
|
+
return compiled;
|
|
96
|
+
}
|
package/src/i18n/duneI18n.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
fromUrl,
|
|
7
7
|
} from "@lingui/detect-locale";
|
|
8
8
|
import type { EventEmitter } from "./EventEmitterType";
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
import { LocalesEnum } from "./enums";
|
|
11
11
|
import type { Config } from "./shared";
|
|
12
12
|
|
|
@@ -163,8 +163,10 @@ export class DuneI18n {
|
|
|
163
163
|
|
|
164
164
|
//#region 注册语言包,并不一定会加载
|
|
165
165
|
private messageLoader: Record<string, MsgLoader> = {};
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
get messageLoadResult() {
|
|
167
|
+
//@ts-expect-error 内部属性
|
|
168
|
+
return this.baseI18n._messages;
|
|
169
|
+
}
|
|
168
170
|
register(locale: LocalesEnum, message: MsgLoader) {
|
|
169
171
|
this.messageLoader[locale] = message;
|
|
170
172
|
this.log("register ", locale, message);
|
|
@@ -174,14 +176,8 @@ export class DuneI18n {
|
|
|
174
176
|
* 外部可以直接调用,加载语言包
|
|
175
177
|
* 这是一个同步方法
|
|
176
178
|
*/
|
|
177
|
-
loadMessage(locale: string, message: BaseMsg
|
|
178
|
-
|
|
179
|
-
const { compiled, raw } = this.compileMessage(messages);
|
|
180
|
-
this.messageLoadResult[locale] = Object.assign(
|
|
181
|
-
this.messageLoadResult[locale] || {},
|
|
182
|
-
raw,
|
|
183
|
-
);
|
|
184
|
-
this.baseI18n.load(locale, compiled);
|
|
179
|
+
loadMessage(locale: string, message: BaseMsg) {
|
|
180
|
+
this.baseI18n.load(locale, message);
|
|
185
181
|
}
|
|
186
182
|
|
|
187
183
|
// 这里不能变成 async 方法,因为在 ssg 时,需要同步加载语言包
|
|
@@ -192,69 +188,25 @@ export class DuneI18n {
|
|
|
192
188
|
if (!loader) {
|
|
193
189
|
return;
|
|
194
190
|
}
|
|
195
|
-
// case: i18n.register(LocalesEnum.zh,
|
|
191
|
+
// case: i18n.register(LocalesEnum.zh, {});
|
|
196
192
|
if (typeof loader === "object") {
|
|
197
193
|
this.loadMessage(locale, loader);
|
|
198
194
|
return;
|
|
199
195
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return loader();
|
|
204
|
-
} catch (e) {
|
|
205
|
-
console.error(`load ${locale} translate failed`);
|
|
206
|
-
console.error(e);
|
|
207
|
-
return [];
|
|
208
|
-
}
|
|
209
|
-
})();
|
|
210
|
-
if (!isAsyncMsg(p)) {
|
|
211
|
-
// case: i18n.register(LocalesEnum.zh, () => [{},{}]);
|
|
212
|
-
return this.tryLoadMessage(locale, p);
|
|
213
|
-
}
|
|
214
|
-
// case: i18n.register(LocalesEnum.zh, () => [Promise.resolve({})]);
|
|
215
|
-
// case: i18n.register(LocalesEnum.zh, () => [import('./i18n.json')]);
|
|
216
|
-
return Promise.allSettled(p).then((res) => {
|
|
217
|
-
const loadSuccess = res.reduce((acc, v) => {
|
|
218
|
-
if (v.status === "rejected") {
|
|
219
|
-
console.error(`load ${locale} translate failed: `, v.reason);
|
|
220
|
-
return acc;
|
|
221
|
-
}
|
|
222
|
-
return [...acc, v.value];
|
|
223
|
-
}, [] as BaseMsg[]);
|
|
224
|
-
return this.tryLoadMessage(locale, loadSuccess);
|
|
196
|
+
// case: i18n.register(LocalesEnum.zh, () => import("./zh.json"));
|
|
197
|
+
return loader().then((res) => {
|
|
198
|
+
this.tryLoadMessage(locale, res);
|
|
225
199
|
});
|
|
226
200
|
}
|
|
227
201
|
|
|
228
|
-
/**
|
|
229
|
-
* 将多个语言包合并成一个
|
|
230
|
-
*/
|
|
231
|
-
private compileMessage(messages: BaseMsg[]) {
|
|
232
|
-
const compiled: BaseMsg = {};
|
|
233
|
-
const raw: BaseMsg = {};
|
|
234
|
-
messages.forEach((msg) => {
|
|
235
|
-
Object.keys(msg).forEach((k) => {
|
|
236
|
-
const v = msg[k];
|
|
237
|
-
raw[k] = v;
|
|
238
|
-
if (typeof v === "string") {
|
|
239
|
-
compiled[k] = compileMessage(v || k);
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
return { compiled, raw };
|
|
244
|
-
}
|
|
245
202
|
//#endregion
|
|
246
203
|
}
|
|
247
204
|
|
|
248
205
|
export type BaseMsg = Record<string, any>;
|
|
249
206
|
|
|
250
|
-
export type MsgLoader =
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
p: Promise<BaseMsg>[] | BaseMsg[],
|
|
254
|
-
): p is Promise<BaseMsg>[] => {
|
|
255
|
-
let first = Array.isArray(p) ? p[0] : p;
|
|
256
|
-
return typeof first?.then === "function";
|
|
257
|
-
};
|
|
207
|
+
export type MsgLoader =
|
|
208
|
+
| Record<string, unknown>
|
|
209
|
+
| (() => Promise<Record<string, unknown>>);
|
|
258
210
|
|
|
259
211
|
export const i18n = new DuneI18n();
|
|
260
212
|
|
package/src/i18n/enums.ts
CHANGED
package/src/i18n/index.ts
CHANGED
|
@@ -6,7 +6,6 @@ export type { I18nContext, I18nProviderProps } from "@lingui/react";
|
|
|
6
6
|
export { I18nProvider } from "./I18nProvider";
|
|
7
7
|
export { i18n } from "./duneI18n";
|
|
8
8
|
export { LocalesEnum } from "./enums";
|
|
9
|
-
export { loadPlatformLocaleResource } from "./loadPlatformLocaleResource";
|
|
10
9
|
export { msg } from "./msg";
|
|
11
10
|
export { t } from "./t";
|
|
12
11
|
export { useLocale } from "./useLocale";
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { i18n } from "./duneI18n";
|
|
2
|
-
|
|
3
|
-
type Data = Record<string, Record<string, string>>;
|
|
4
|
-
|
|
5
|
-
let cache = {
|
|
6
|
-
time: 0,
|
|
7
|
-
data: {} as Data,
|
|
8
|
-
dataPromise: null as Promise<Data | void> | null,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
async function initFetch(opts: Opts): Promise<Data | void> {
|
|
12
|
-
const urlObj = new URL(opts.url);
|
|
13
|
-
urlObj.searchParams.set("projectName", opts.projectName);
|
|
14
|
-
try {
|
|
15
|
-
const res = await fetch(urlObj.toString()).then((res) => res.json());
|
|
16
|
-
if (res.code !== 200) {
|
|
17
|
-
console.error(`load translate failed: `, res);
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
return res.data;
|
|
21
|
-
} catch (e) {
|
|
22
|
-
console.error(`load translate error: `, e);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface Opts {
|
|
28
|
-
/**
|
|
29
|
-
* 语言
|
|
30
|
-
*/
|
|
31
|
-
locale: string;
|
|
32
|
-
/**
|
|
33
|
-
* 项目名称
|
|
34
|
-
*/
|
|
35
|
-
projectName: string;
|
|
36
|
-
/**
|
|
37
|
-
* 翻译平台地址接口地址
|
|
38
|
-
*/
|
|
39
|
-
url: string;
|
|
40
|
-
/**
|
|
41
|
-
* 缓存时间 5s
|
|
42
|
-
* @default 5 * 1000
|
|
43
|
-
*/
|
|
44
|
-
cacheTime?: number;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 从翻译平台加载翻译资源
|
|
49
|
-
*/
|
|
50
|
-
export async function loadPlatformLocaleResource(opts: Opts) {
|
|
51
|
-
const locale = opts.locale;
|
|
52
|
-
const now = Date.now();
|
|
53
|
-
const cacheTime = opts.cacheTime || 5 * 1000;
|
|
54
|
-
|
|
55
|
-
// 有缓存且未过期
|
|
56
|
-
if (cache.data[locale] && now - cache.time < cacheTime) {
|
|
57
|
-
i18n.loadMessage(locale, cache.data[locale]);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!cache.dataPromise) {
|
|
62
|
-
cache.dataPromise = initFetch(opts);
|
|
63
|
-
}
|
|
64
|
-
const data = await cache.dataPromise;
|
|
65
|
-
// 用完后需要清空,否则会一直缓存
|
|
66
|
-
cache.dataPromise = null;
|
|
67
|
-
if (data) {
|
|
68
|
-
cache.data = data;
|
|
69
|
-
cache.time = Date.now();
|
|
70
|
-
i18n.loadMessage(locale, data[locale]);
|
|
71
|
-
}
|
|
72
|
-
}
|