ttmg-pack 0.4.0 → 0.4.4

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/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * ==========================================
3
3
  * @Description: ttmg pack
4
- * @Version: 0.4.0
4
+ * @Version: 0.4.4
5
5
  * @Author: zhanghongyang.mocha
6
- * @Date: 2026-03-06 16:13:38
6
+ * @Date: 2026-03-19 15:31:24
7
7
  * ==========================================
8
8
  */
9
9
  'use strict';
@@ -279,8 +279,184 @@ function deleteNoJsFilesSync(dir) {
279
279
  }
280
280
  }
281
281
 
282
+ const messages = {
283
+ 'en-US': {
284
+ 'log.check.start': 'Start checking project.',
285
+ 'log.check.project.start': 'Start checking project dimension.',
286
+ 'log.check.project.success': 'Project checks passed.',
287
+ 'log.check.config.start': 'Start checking config.',
288
+ 'log.check.projectSize.start': 'Start checking project size.',
289
+ 'log.check.subpackages.start': 'Start checking subpackages in game.json.',
290
+ 'log.check.subpackages.success': 'Subpackages config checks passed.',
291
+ 'log.check.mainPackage.start': 'Start checking main package.',
292
+ 'log.check.mainPackageEntry.start': 'Start checking main package entry.',
293
+ 'log.check.mainPackageEntry.success': 'Main package entry check passed.',
294
+ 'log.check.mainPackageSize.start': 'Start checking main package size.',
295
+ 'log.check.mainPackage.success': 'Main package checks passed.',
296
+ 'log.check.independent.start': 'Start checking independent subpackages in game.json.',
297
+ 'log.check.independent.success': 'Independent subpackages config checks passed.',
298
+ 'log.setup.startGeneratePackageConfig': 'Start generating packageConfig.json from game.json.',
299
+ 'log.setup.generatePackageConfigSuccess': 'Generated packageConfig.json from game.json successfully.',
300
+ 'log.collectMaps.start': 'Start collecting JS files from game source packages.',
301
+ 'log.collectMaps.openDataContextDir': 'Open data context directory: {dir}',
302
+ 'log.collectMaps.done': 'Collected JS files from game source packages successfully.',
303
+ 'log.makePkgs.start': 'Pack start, startTime: {startTime}',
304
+ 'log.makePkgs.startPackBySource': 'Start packing from game source, package: {pkgName}',
305
+ 'log.makePkgs.finishPackBySource': 'Finished packing and partitioning from game source, package: {pkgName}',
306
+ 'log.makePkgs.packBySourceCost': 'Pack and partition cost, package: {pkgName}, duration: {duration}ms',
307
+ 'log.makePkgs.startOpenData': 'Start packing from open data context source.',
308
+ 'log.makePkgs.finishOpenData': 'Finished packing from open data context source.',
309
+ 'log.makePkgs.openDataCost': 'Open data context packing cost: {duration}ms',
310
+ 'log.makePkgs.end': 'Pack end, duration: {duration}ms',
311
+ 'log.build.version': 'TTMG_PACK_VERSION: {version}',
312
+ 'log.build.start': 'Pack start, startTime: {startTime}',
313
+ 'log.build.end': 'Pack end: {duration}ms',
314
+ 'log.pack.start': 'Pack start, startTime: {startTime}',
315
+ 'log.pack.end': 'Pack end, package: {pkgName}',
316
+ 'log.safeBuild.initStart': 'Attempting to initialize esbuild service...',
317
+ 'log.safeBuild.initSuccess': 'esbuild service initialized successfully.',
318
+ 'log.safeBuild.initFailed': 'Failed to initialize esbuild service:',
319
+ 'log.cleanup.start': 'Start cleaning useless files, total entries: {total}',
320
+ 'log.cleanup.accessDirFailed': 'Cannot access directory: {dir}, {error}',
321
+ 'log.cleanup.deletedDir': 'Deleted useless directory: {path}',
322
+ 'log.cleanup.deletedFile': 'Deleted useless file: {path}',
323
+ 'log.cleanup.processFailed': 'Cannot process entry: {path}, {error}',
324
+ 'log.cleanup.progress': 'Progress: {processed}/{total} ({percentage}%)',
325
+ 'log.cleanup.done': 'Cleanup finished.',
326
+ 'log.cleanup.summary.total': '- Total entries: {total}',
327
+ 'log.cleanup.summary.deletedDirs': '- Deleted directories: {deletedDirs}',
328
+ 'log.cleanup.summary.deletedFiles': '- Deleted files: {deletedFiles}',
329
+ 'log.cleanup.summary.errors': '- Errors: {errors}',
330
+ 'check.project.gameJson.missing': 'Cannot find game.json in the project source. Please make sure game.json exists.',
331
+ 'check.project.gameJson.subPackagesInvalid': "'subPackages' is found in game.json. Please use 'subpackages' (all lowercase) instead.",
332
+ 'check.project.gameJson.success': 'Check game.json config successfully.',
333
+ 'check.project.size.failed': 'Project size check failed: {sizeMB}MB. It must not exceed {limitMB}MB.',
334
+ 'check.project.size.success': 'Project size check passed: {sizeMB}MB.',
335
+ 'check.project.perf.noSplitNeeded': 'wasmFuncCount < {limit}. No wasm code splitting is needed.',
336
+ 'check.project.perf.needSplit': 'The Wasm function count in wasmcode/ exceeds {limit}. Please enable code splitting to optimize performance.',
337
+ 'check.project.perf.splitEnabled': 'wasmFuncCount >= {limit}, and wasm split is enabled.',
338
+ 'check.main.size.failed': 'Main package size check failed: {sizeMB}MB. It must not exceed {limitMB}MB.',
339
+ 'check.main.size.success': 'Main package size check passed: {sizeMB}MB.',
340
+ 'check.main.entry.missing': 'Main package entry check failed: game.js must exist in the main package.',
341
+ 'check.main.entry.success': 'Main package entry check passed: game.js exists in the main package.',
342
+ 'check.subpackages.config.empty': 'Subpackages config check failed: one or more subpackages have an empty root or name. Please ensure every subpackage has non-empty root and name.',
343
+ 'check.subpackages.config.invalidPath': 'Subpackages config check failed: subpackage<{name}> has invalid {invalidFields}. Only A-Za-z0-9 _ - . / \\ are allowed.',
344
+ 'check.subpackages.config.success': 'Subpackage<{name}> config check passed.',
345
+ 'check.subpackages.config.missingDir': 'Subpackages config check failed: cannot find entry directory for subpackage<{name}>. Please verify its root path in game.json.',
346
+ 'check.independent.config.empty': 'Independent subpackages config check failed: one or more independent subpackages have an empty root or name. Please ensure every independent subpackage has non-empty root and name.',
347
+ 'check.independent.config.missingDir': 'Independent subpackages config check failed: cannot find entry directory for independent subpackage<{name}>. Please verify its root path in game.json.',
348
+ 'check.independent.config.success': 'Independent subpackage<{name}> config check passed.',
349
+ 'check.pkgSize.success': 'Package<{pkgName}> size check passed: {sizeMB}MB.',
350
+ 'check.pkgSize.exceeds': 'Package<{pkgName}> size check failed: {sizeMB}MB exceeds limit {limitMB}MB.',
351
+ 'check.api.integrated': '{name} integrated.',
352
+ 'check.api.notIntegrated': '{name} not integrated.',
353
+ 'check.api.suggestedActionSuffix': 'Please resolve this before submission to avoid review rejection.',
354
+ 'debug.validation.failed': 'Project validation failed (Errors):\n{errorMsg}',
355
+ },
356
+ 'zh-CN': {
357
+ 'log.check.start': '开始校验项目。',
358
+ 'log.check.project.start': '开始校验项目维度。',
359
+ 'log.check.project.success': '项目校验通过。',
360
+ 'log.check.config.start': '开始校验配置。',
361
+ 'log.check.projectSize.start': '开始校验项目大小。',
362
+ 'log.check.subpackages.start': '开始校验 game.json 中的分包配置。',
363
+ 'log.check.subpackages.success': '分包配置校验通过。',
364
+ 'log.check.mainPackage.start': '开始校验主包。',
365
+ 'log.check.mainPackageEntry.start': '开始校验主包入口。',
366
+ 'log.check.mainPackageEntry.success': '主包入口校验通过。',
367
+ 'log.check.mainPackageSize.start': '开始校验主包大小。',
368
+ 'log.check.mainPackage.success': '主包校验通过。',
369
+ 'log.check.independent.start': '开始校验 game.json 中的独立分包配置。',
370
+ 'log.check.independent.success': '独立分包配置校验通过。',
371
+ 'log.setup.startGeneratePackageConfig': '开始基于源代码中的 game.json 生成 packageConfig.json。',
372
+ 'log.setup.generatePackageConfigSuccess': '基于源代码中的 game.json 生成 packageConfig.json 成功。',
373
+ 'log.collectMaps.start': '开始基于游戏源代码收集分包中的 JS 文件。',
374
+ 'log.collectMaps.openDataContextDir': '开放数据域目录:{dir}',
375
+ 'log.collectMaps.done': '基于游戏源代码收集分包中的 JS 文件完成。',
376
+ 'log.makePkgs.start': '打包开始,开始时间:{startTime}',
377
+ 'log.makePkgs.startPackBySource': '开始基于游戏源代码打包,包名:{pkgName}',
378
+ 'log.makePkgs.finishPackBySource': '基于游戏源代码打包分包完成,包名:{pkgName}',
379
+ 'log.makePkgs.packBySourceCost': '基于游戏源代码打包分包耗时,包名:{pkgName},耗时:{duration}ms',
380
+ 'log.makePkgs.startOpenData': '开始基于开放数据域源代码打包。',
381
+ 'log.makePkgs.finishOpenData': '基于开放数据域源代码打包完成。',
382
+ 'log.makePkgs.openDataCost': '基于开放数据域源代码打包耗时,耗时:{duration}ms',
383
+ 'log.makePkgs.end': '打包结束,总耗时:{duration}ms',
384
+ 'log.build.version': 'TTMG_PACK_VERSION: {version}',
385
+ 'log.build.start': '打包开始,开始时间:{startTime}',
386
+ 'log.build.end': '打包结束:{duration}ms',
387
+ 'log.pack.start': '打包开始,开始时间:{startTime}',
388
+ 'log.pack.end': '打包结束,包名:{pkgName}',
389
+ 'log.safeBuild.initStart': '尝试初始化 esbuild 服务...',
390
+ 'log.safeBuild.initSuccess': 'esbuild 服务初始化成功。',
391
+ 'log.safeBuild.initFailed': '初始化 esbuild 服务失败:',
392
+ 'log.cleanup.start': '开始清理无用文件,共 {total} 个条目',
393
+ 'log.cleanup.accessDirFailed': '无法访问目录: {dir}, {error}',
394
+ 'log.cleanup.deletedDir': '已删除无用目录: {path}',
395
+ 'log.cleanup.deletedFile': '已删除无用文件: {path}',
396
+ 'log.cleanup.processFailed': '无法处理: {path}, {error}',
397
+ 'log.cleanup.progress': '进度: {processed}/{total} ({percentage}%)',
398
+ 'log.cleanup.done': '清理完成!',
399
+ 'log.cleanup.summary.total': '- 总条目: {total}',
400
+ 'log.cleanup.summary.deletedDirs': '- 已删除目录: {deletedDirs}',
401
+ 'log.cleanup.summary.deletedFiles': '- 已删除文件: {deletedFiles}',
402
+ 'log.cleanup.summary.errors': '- 错误数: {errors}',
403
+ 'check.project.gameJson.missing': '未在项目源码中找到 game.json,请确认 game.json 文件存在。',
404
+ 'check.project.gameJson.subPackagesInvalid': "在 game.json 中发现了 'subPackages' 字段,请改为全小写的 'subpackages'。",
405
+ 'check.project.gameJson.success': 'game.json 配置检查通过。',
406
+ 'check.project.size.failed': '项目大小检查失败:当前 {sizeMB}MB,不能超过 {limitMB}MB。',
407
+ 'check.project.size.success': '项目大小检查通过:当前 {sizeMB}MB。',
408
+ 'check.project.perf.noSplitNeeded': 'wasmFuncCount < {limit},无需进行 wasm 代码拆分。',
409
+ 'check.project.perf.needSplit': 'wasmcode/ 中的 Wasm 函数数量超过 {limit},请开启代码拆分以优化性能。',
410
+ 'check.project.perf.splitEnabled': 'wasmFuncCount >= {limit},且已开启 wasm 拆分。',
411
+ 'check.main.size.failed': '主包大小检查失败:当前 {sizeMB}MB,不能超过 {limitMB}MB。',
412
+ 'check.main.size.success': '主包大小检查通过:当前 {sizeMB}MB。',
413
+ 'check.main.entry.missing': '主包入口检查失败:主包中必须存在 game.js。',
414
+ 'check.main.entry.success': '主包入口检查通过:主包中存在 game.js。',
415
+ 'check.subpackages.config.empty': '分包配置检查失败:一个或多个分包的 root 或 name 为空,请确保所有分包都配置了非空的 root 和 name。',
416
+ 'check.subpackages.config.invalidPath': '分包配置检查失败:分包<{name}> 的 {invalidFields} 含有非法字符,仅允许 A-Za-z0-9 _ - . / \\。',
417
+ 'check.subpackages.config.success': '分包<{name}> 配置检查通过。',
418
+ 'check.subpackages.config.missingDir': '分包配置检查失败:找不到分包<{name}> 的入口目录,请检查 game.json 中的 root 路径。',
419
+ 'check.independent.config.empty': '独立分包配置检查失败:一个或多个独立分包的 root 或 name 为空,请确保所有独立分包都配置了非空的 root 和 name。',
420
+ 'check.independent.config.missingDir': '独立分包配置检查失败:找不到独立分包<{name}> 的入口目录,请检查 game.json 中的 root 路径。',
421
+ 'check.independent.config.success': '独立分包<{name}> 配置检查通过。',
422
+ 'check.pkgSize.success': '包<{pkgName}> 大小检查通过:{sizeMB}MB。',
423
+ 'check.pkgSize.exceeds': '包<{pkgName}> 大小检查失败:当前 {sizeMB}MB,超过限制 {limitMB}MB。',
424
+ 'check.api.integrated': '{name} 已接入。',
425
+ 'check.api.notIntegrated': '{name} 未接入。',
426
+ 'check.api.suggestedActionSuffix': '请在提审之前完成问题处理,避免审核阶段被拒审。',
427
+ 'debug.validation.failed': '项目校验失败(错误项):\n{errorMsg}',
428
+ },
429
+ };
430
+ function format(template, params) {
431
+ if (!params)
432
+ return template;
433
+ return template.replace(/\{(\w+)\}/g, (_, key) => {
434
+ const value = params[key];
435
+ return value === undefined ? `{${key}}` : String(value);
436
+ });
437
+ }
438
+ function resolvePackLanguage(lang) {
439
+ return lang === 'zh-CN' ? 'zh-CN' : 'en-US';
440
+ }
441
+ let runtimePackLang = 'en-US';
442
+ function setPackRuntimeLanguage(lang) {
443
+ runtimePackLang = resolvePackLanguage(lang);
444
+ }
445
+ function createPackTranslator(lang) {
446
+ const currentLang = resolvePackLanguage(lang);
447
+ return (key, params) => {
448
+ var _a, _b;
449
+ const template = (_b = (_a = messages[currentLang][key]) !== null && _a !== void 0 ? _a : messages['en-US'][key]) !== null && _b !== void 0 ? _b : key;
450
+ return format(template, params);
451
+ };
452
+ }
453
+ function getPackTranslator() {
454
+ return createPackTranslator(runtimePackLang);
455
+ }
456
+
282
457
  const uselessFiles = ['.DS_Store', 'Thumbs.db'];
283
458
  function removeSystemUseless(gameEntry, uselessDirs) {
459
+ const t = getPackTranslator();
284
460
  const progress = {
285
461
  total: 0,
286
462
  processed: 0,
@@ -293,10 +469,13 @@ function removeSystemUseless(gameEntry, uselessDirs) {
293
469
  try {
294
470
  files = fs.readdirSync(gameEntry);
295
471
  progress.total = files.length;
296
- logger.info(`开始清理无用文件,共 ${progress.total} 个条目`);
472
+ logger.info(t('log.cleanup.start', { total: progress.total }));
297
473
  }
298
474
  catch (err) {
299
- logger.warn(`无法访问目录: ${gameEntry}, ${err.message}`);
475
+ logger.warn(t('log.cleanup.accessDirFailed', {
476
+ dir: gameEntry,
477
+ error: err.message,
478
+ }));
300
479
  progress.errors++;
301
480
  return progress;
302
481
  }
@@ -310,21 +489,24 @@ function removeSystemUseless(gameEntry, uselessDirs) {
310
489
  logger.debug(`正在删除目录: ${filePath}`);
311
490
  fs.rmSync(filePath, { recursive: true, force: true });
312
491
  progress.deletedDirs++;
313
- logger.info(`✅ 已删除无用目录: ${filePath}`);
492
+ logger.info(t('log.cleanup.deletedDir', { path: filePath }));
314
493
  }
315
494
  else if (stat.isFile() && uselessFiles.includes(file)) {
316
495
  // 删除无用文件
317
496
  logger.debug(`正在删除文件: ${filePath}`);
318
497
  fs.rmSync(filePath, { force: true });
319
498
  progress.deletedFiles++;
320
- logger.info(`✅ 已删除无用文件: ${filePath}`);
499
+ logger.info(t('log.cleanup.deletedFile', { path: filePath }));
321
500
  }
322
501
  else {
323
502
  logger.debug(`跳过: ${filePath} (非目标文件/目录)`);
324
503
  }
325
504
  }
326
505
  catch (err) {
327
- logger.warn(`❌ 无法处理: ${filePath}, ${err.message}`);
506
+ logger.warn(t('log.cleanup.processFailed', {
507
+ path: filePath,
508
+ error: err.message,
509
+ }));
328
510
  progress.errors++;
329
511
  }
330
512
  // 更新进度
@@ -332,15 +514,23 @@ function removeSystemUseless(gameEntry, uselessDirs) {
332
514
  // 可选:每处理10个条目输出一次进度
333
515
  if ((index + 1) % 10 === 0 || index + 1 === progress.total) {
334
516
  const percentage = Math.round(((index + 1) / progress.total) * 100);
335
- logger.info(`进度: ${index + 1}/${progress.total} (${percentage}%)`);
517
+ logger.info(t('log.cleanup.progress', {
518
+ processed: index + 1,
519
+ total: progress.total,
520
+ percentage,
521
+ }));
336
522
  }
337
523
  });
338
524
  // 3. 输出总结
339
- logger.info(`清理完成!`);
340
- logger.info(`- 总条目: ${progress.total}`);
341
- logger.info(`- 已删除目录: ${progress.deletedDirs}`);
342
- logger.info(`- 已删除文件: ${progress.deletedFiles}`);
343
- logger.info(`- 错误数: ${progress.errors}`);
525
+ logger.info(t('log.cleanup.done'));
526
+ logger.info(t('log.cleanup.summary.total', { total: progress.total }));
527
+ logger.info(t('log.cleanup.summary.deletedDirs', {
528
+ deletedDirs: progress.deletedDirs,
529
+ }));
530
+ logger.info(t('log.cleanup.summary.deletedFiles', {
531
+ deletedFiles: progress.deletedFiles,
532
+ }));
533
+ logger.info(t('log.cleanup.summary.errors', { errors: progress.errors }));
344
534
  return progress;
345
535
  }
346
536
 
@@ -460,8 +650,9 @@ function ensureOnce(fn) {
460
650
  // 它会执行一次 esbuild.build,目的是为了“唤醒”并安全地启动 esbuild 的后台服务。
461
651
  // 我们选择一个几乎无害的操作,比如转换一个空字符串。
462
652
  const initializeEsbuild = async () => {
653
+ const t = getPackTranslator();
463
654
  try {
464
- logger.info('Attempting to initialize esbuild service...');
655
+ logger.info(t('log.safeBuild.initStart'));
465
656
  // 执行一个非常轻量的 build 操作来触发服务启动。
466
657
  await esbuild.build({
467
658
  stdin: { contents: '' },
@@ -469,10 +660,10 @@ const initializeEsbuild = async () => {
469
660
  bundle: false,
470
661
  logLevel: "silent"
471
662
  });
472
- logger.info('esbuild service initialized successfully.');
663
+ logger.info(t('log.safeBuild.initSuccess'));
473
664
  }
474
665
  catch (e) {
475
- logger.error('Failed to initialize esbuild service:');
666
+ logger.error(t('log.safeBuild.initFailed'));
476
667
  // 如果初始化失败,允许重试
477
668
  throw e;
478
669
  }
@@ -889,27 +1080,28 @@ async function buildOdrPkgs({ tempDir }) {
889
1080
  const defaultCheckConfig$3 = {
890
1081
  name: 'project',
891
1082
  dimension: CHECK_DIMENSION.Project,
1083
+ required: true,
892
1084
  };
893
- function checkProject(config) {
894
- logger.info('start check project');
895
- const gameJsonCheckResult = checkGameJson(config);
896
- const checkSizeResult = checkProjectSize(config);
897
- const checkPerfResult = checkPerformance(config);
1085
+ function checkProject(config, t) {
1086
+ logger.info(t('log.check.project.start'));
1087
+ const gameJsonCheckResult = checkGameJson(config, t);
1088
+ const checkSizeResult = checkProjectSize(config, t);
1089
+ const checkPerfResult = checkPerformance(config, t);
898
1090
  /**
899
1091
  * 过滤掉空的
900
1092
  */
901
1093
  const result = [gameJsonCheckResult, checkSizeResult, checkPerfResult].filter(Boolean);
902
1094
  if (result.every(item => item.passed)) {
903
- logger.info('check project successfully');
1095
+ logger.info(t('log.check.project.success'));
904
1096
  }
905
1097
  return result;
906
1098
  }
907
- function checkGameJson(config) {
1099
+ function checkGameJson(config, t) {
908
1100
  var _a, _b;
909
- logger.info('start check config');
1101
+ logger.info(t('log.check.config.start'));
910
1102
  const gameJsonPath = path.join(config.entry, GAME_ORIGIN_CONFIG_FILE_NAME);
911
1103
  if (!fs.existsSync(gameJsonPath)) {
912
- const errMsg = 'Can not find game.json in game source code, please check it';
1104
+ const errMsg = t('check.project.gameJson.missing');
913
1105
  logger.error(errMsg);
914
1106
  if ((_a = config === null || config === void 0 ? void 0 : config.dev) === null || _a === void 0 ? void 0 : _a.enable) {
915
1107
  return Object.assign({ passed: false, msg: errMsg, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME, name: 'project' }, defaultCheckConfig$3);
@@ -921,7 +1113,7 @@ function checkGameJson(config) {
921
1113
  else {
922
1114
  const gameJson = JSON.parse(fs.readFileSync(gameJsonPath, 'utf-8'));
923
1115
  if (gameJson.subPackages) {
924
- const errMsg = `'subPackages' is found in ${GAME_ORIGIN_CONFIG_FILE_NAME}. Please use 'subpackages' (all lowercase) instead.`;
1116
+ const errMsg = t('check.project.gameJson.subPackagesInvalid');
925
1117
  logger.error(errMsg);
926
1118
  if ((_b = config === null || config === void 0 ? void 0 : config.dev) === null || _b === void 0 ? void 0 : _b.enable) {
927
1119
  return Object.assign({ passed: false, msg: errMsg, type: 'config', name: 'project', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$3);
@@ -930,7 +1122,7 @@ function checkGameJson(config) {
930
1122
  throw new Error(errMsg);
931
1123
  }
932
1124
  }
933
- const msg = 'Check game.json config successfully';
1125
+ const msg = t('check.project.gameJson.success');
934
1126
  logger.info(msg);
935
1127
  return Object.assign({ passed: true, msg, type: 'config', level: 'info', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$3);
936
1128
  }
@@ -940,8 +1132,8 @@ function checkGameJson(config) {
940
1132
  * @param param0
941
1133
  * @returns
942
1134
  */
943
- function checkProjectSize(config) {
944
- logger.info('start check project size');
1135
+ function checkProjectSize(config, t) {
1136
+ logger.info(t('log.check.projectSize.start'));
945
1137
  const { entry: entryDir, dev } = config;
946
1138
  const { pkgSizeLimit } = getCheckConfig(config);
947
1139
  const enableDev = dev === null || dev === void 0 ? void 0 : dev.enable;
@@ -949,7 +1141,7 @@ function checkProjectSize(config) {
949
1141
  const gameSizeMB = (gameSize / (1024 * 1024)).toFixed(2);
950
1142
  const limitMB = (pkgSizeLimit / (1024 * 1024)).toFixed(2);
951
1143
  if (gameSize > pkgSizeLimit) {
952
- const errMsg = `Check project size failed, size: ${gameSizeMB}MB, must not exceed ${limitMB}MB`;
1144
+ const errMsg = t('check.project.size.failed', { sizeMB: gameSizeMB, limitMB });
953
1145
  logger.error(errMsg);
954
1146
  if (enableDev) {
955
1147
  return Object.assign({ passed: false, name: 'project', msg: errMsg, type: 'size', level: 'warning', size: gameSize }, defaultCheckConfig$3);
@@ -962,12 +1154,12 @@ function checkProjectSize(config) {
962
1154
  /**
963
1155
  * 游戏大小检查通过
964
1156
  */
965
- const logMsg = `Check project size successfully, size: ${gameSizeMB}MB`;
1157
+ const logMsg = t('check.project.size.success', { sizeMB: gameSizeMB });
966
1158
  logger.info(logMsg);
967
1159
  return Object.assign({ passed: true, msg: logMsg, name: 'project', type: 'size', level: 'info', size: gameSize }, defaultCheckConfig$3);
968
1160
  }
969
1161
  }
970
- function checkPerformance(config) {
1162
+ function checkPerformance(config, t) {
971
1163
  const { entry } = config;
972
1164
  if (!isUnityEngine(entry)) {
973
1165
  return null;
@@ -978,10 +1170,14 @@ function checkPerformance(config) {
978
1170
  return null;
979
1171
  }
980
1172
  if ((gameJson === null || gameJson === void 0 ? void 0 : gameJson.wasmFuncCount) < WASM_FUNC_COUNT_LIMIT) {
981
- return Object.assign(Object.assign({}, defaultCheckConfig$3), { passed: true, msg: `wasmFuncCount < ${WASM_FUNC_COUNT_LIMIT}, no need to split wasm code`, type: 'performance', level: 'info', name: 'project' });
1173
+ return Object.assign(Object.assign({}, defaultCheckConfig$3), { passed: true, msg: t('check.project.perf.noSplitNeeded', {
1174
+ limit: WASM_FUNC_COUNT_LIMIT,
1175
+ }), type: 'performance', level: 'info', name: 'project' });
982
1176
  }
983
1177
  const splitConfigPath = path.join(entry, GAME_WASM_SPLIT_CONFIG_FILE_NAME);
984
- const errResult = Object.assign(Object.assign({}, defaultCheckConfig$3), { passed: false, msg: `The Wasm function count in wasmcode/ exceeds ${WASM_FUNC_COUNT_LIMIT}. Please enable code splitting to optimize performance.`, type: 'performance', level: 'warning', name: 'project' });
1178
+ const errResult = Object.assign(Object.assign({}, defaultCheckConfig$3), { passed: false, msg: t('check.project.perf.needSplit', {
1179
+ limit: WASM_FUNC_COUNT_LIMIT,
1180
+ }), type: 'performance', level: 'warning', name: 'project' });
985
1181
  if (!fs.existsSync(splitConfigPath)) {
986
1182
  return errResult;
987
1183
  }
@@ -990,28 +1186,34 @@ function checkPerformance(config) {
990
1186
  return errResult;
991
1187
  }
992
1188
  else {
993
- return Object.assign(Object.assign({}, defaultCheckConfig$3), { passed: true, msg: 'wasmFuncCount >= 80000, wasm split is enabled', type: 'performance', level: 'info', name: 'project' });
1189
+ return Object.assign(Object.assign({}, defaultCheckConfig$3), { passed: true, msg: t('check.project.perf.splitEnabled', {
1190
+ limit: WASM_FUNC_COUNT_LIMIT,
1191
+ }), type: 'performance', level: 'info', name: 'project' });
994
1192
  }
995
1193
  }
996
1194
 
997
1195
  const defaultCheckConfig$2 = {
998
1196
  name: 'main',
999
1197
  dimension: CHECK_DIMENSION.MainPackage,
1198
+ required: true,
1000
1199
  };
1001
1200
  /**
1002
1201
  * 检查主包大小是否超出限制
1003
1202
  * @param param0
1004
1203
  * @returns
1005
1204
  */
1006
- function checkMainPackageSize(config) {
1007
- logger.info('start check main package size');
1205
+ function checkMainPackageSize(config, t) {
1206
+ logger.info(t('log.check.mainPackageSize.start'));
1008
1207
  const { entry: entryDir, dev } = config;
1009
1208
  const { mainPkgSizeLimit } = getCheckConfig(config);
1010
1209
  const mainPkgSize = getMainPkgSize({ entryDir });
1011
1210
  const mainPkgSizeMB = (mainPkgSize / (1024 * 1024)).toFixed(2);
1012
1211
  const limitMB = (mainPkgSizeLimit / (1024 * 1024)).toFixed(2);
1013
1212
  if (mainPkgSize > mainPkgSizeLimit) {
1014
- const errMsg = `Check main package size failed, main package size ${mainPkgSizeMB}MB, must not exceed ${limitMB}MB`;
1213
+ const errMsg = t('check.main.size.failed', {
1214
+ sizeMB: mainPkgSizeMB,
1215
+ limitMB,
1216
+ });
1015
1217
  logger.error(errMsg);
1016
1218
  if (dev === null || dev === void 0 ? void 0 : dev.enable) {
1017
1219
  return Object.assign({ passed: false, msg: errMsg, size: mainPkgSize, type: 'size', level: 'warning' }, defaultCheckConfig$2);
@@ -1021,37 +1223,40 @@ function checkMainPackageSize(config) {
1021
1223
  }
1022
1224
  }
1023
1225
  else {
1024
- return Object.assign({ passed: true, msg: `Check main package size successfully, size: ${mainPkgSizeMB}MB`, size: mainPkgSize, type: 'size', level: 'info' }, defaultCheckConfig$2);
1226
+ return Object.assign({ passed: true, msg: t('check.main.size.success', {
1227
+ sizeMB: mainPkgSizeMB,
1228
+ }), size: mainPkgSize, type: 'size', level: 'info' }, defaultCheckConfig$2);
1025
1229
  }
1026
1230
  }
1027
- function checkMainPackageEntry(config) {
1231
+ function checkMainPackageEntry(config, t) {
1028
1232
  var _a;
1029
- logger.info('start check main package entry');
1233
+ logger.info(t('log.check.mainPackageEntry.start'));
1030
1234
  const { entry: entryDir } = config;
1031
1235
  const gameJsPath = path__namespace.join(entryDir, 'game.js');
1032
1236
  if (!fs__namespace.existsSync(gameJsPath)) {
1033
- const errMsg = 'Check main package entry failed, game.js must exist in main package!';
1237
+ const errMsg = t('check.main.entry.missing');
1034
1238
  logger.error(errMsg);
1035
1239
  if ((_a = config.dev) === null || _a === void 0 ? void 0 : _a.enable) {
1036
1240
  return Object.assign({ passed: false, msg: errMsg, type: 'config', level: 'error', file: 'game.js' }, defaultCheckConfig$2);
1037
1241
  }
1242
+ throw new Error(errMsg);
1038
1243
  }
1039
- logger.info('check game.js successfully');
1040
- return Object.assign({ passed: true, msg: 'Check main package entry successfully, game.js must exist in main package!', type: 'config', level: 'info', file: 'game.js' }, defaultCheckConfig$2);
1244
+ logger.info(t('log.check.mainPackageEntry.success'));
1245
+ return Object.assign({ passed: true, msg: t('check.main.entry.success'), type: 'config', level: 'info', file: 'game.js' }, defaultCheckConfig$2);
1041
1246
  }
1042
- function checkMainPackage(config) {
1247
+ function checkMainPackage(config, t) {
1043
1248
  var _a;
1044
1249
  const checkResults = [];
1045
- logger.info('start check main package');
1250
+ logger.info(t('log.check.mainPackage.start'));
1046
1251
  /**
1047
1252
  * 检查 game.js 是否存在
1048
1253
  */
1049
- checkResults.push(checkMainPackageEntry(config));
1254
+ checkResults.push(checkMainPackageEntry(config, t));
1050
1255
  if ((_a = getCheckConfig(config)) === null || _a === void 0 ? void 0 : _a.mainPkgSizeLimit) {
1051
- checkResults.push(checkMainPackageSize(config));
1256
+ checkResults.push(checkMainPackageSize(config, t));
1052
1257
  }
1053
1258
  if (checkResults.every(item => item.passed)) {
1054
- logger.info('Check main package successfully');
1259
+ logger.info(t('log.check.mainPackage.success'));
1055
1260
  }
1056
1261
  return checkResults;
1057
1262
  }
@@ -1065,15 +1270,16 @@ function isValidPath(path) {
1065
1270
  const defaultCheckConfig$1 = {
1066
1271
  name: 'subpackage',
1067
1272
  dimension: 'subpackage',
1273
+ required: true,
1068
1274
  };
1069
- function checkSubpackages(config) {
1275
+ function checkSubpackages(config, t) {
1070
1276
  const { entry: entryDir } = config;
1071
1277
  const checkResults = [];
1072
1278
  /**
1073
1279
  * 校验 subpackage 大小
1074
1280
  * 开始校验 subpackages 配置是否有效
1075
1281
  */
1076
- logger.info('start check subpackages in game.json');
1282
+ logger.info(t('log.check.subpackages.start'));
1077
1283
  const subpackages = getSubpackagesConfig(entryDir);
1078
1284
  subpackages.forEach(sub => {
1079
1285
  var _a, _b, _c;
@@ -1081,7 +1287,7 @@ function checkSubpackages(config) {
1081
1287
  * 校验 subpackage 配置是否为空
1082
1288
  */
1083
1289
  if (!sub.name || !sub.root) {
1084
- const errMsg = 'Check subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more subpackages is empty. Please ensure that all subpackages have non-empty root and name values.';
1290
+ const errMsg = t('check.subpackages.config.empty');
1085
1291
  logger.error(errMsg);
1086
1292
  if ((_a = config === null || config === void 0 ? void 0 : config.dev) === null || _a === void 0 ? void 0 : _a.enable) {
1087
1293
  checkResults.push(Object.assign({ passed: false, msg: errMsg, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$1));
@@ -1091,7 +1297,16 @@ function checkSubpackages(config) {
1091
1297
  }
1092
1298
  }
1093
1299
  else if (!isValidPath(sub.root) || !isValidPath(sub.name)) {
1094
- const errMsg = `Check subpackages config failed, the subpackages configuration in game.json is invalid: the root field in subpackage<${sub.name}> is invalid. Your subpackage root contain invalid characters, only A-Za-z0-9 _ - . / \\ are allowed.`;
1300
+ const invalidFields = [
1301
+ !isValidPath(sub.root) ? 'root' : '',
1302
+ !isValidPath(sub.name) ? 'name' : '',
1303
+ ]
1304
+ .filter(Boolean)
1305
+ .join('/');
1306
+ const errMsg = t('check.subpackages.config.invalidPath', {
1307
+ name: sub.name,
1308
+ invalidFields,
1309
+ });
1095
1310
  logger.error(errMsg);
1096
1311
  if ((_b = config === null || config === void 0 ? void 0 : config.dev) === null || _b === void 0 ? void 0 : _b.enable) {
1097
1312
  checkResults.push(Object.assign({ passed: false, msg: errMsg, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$1));
@@ -1101,7 +1316,9 @@ function checkSubpackages(config) {
1101
1316
  }
1102
1317
  }
1103
1318
  else {
1104
- checkResults.push(Object.assign({ passed: true, msg: `Check subpackage<${sub.name}> config successfully`, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$1));
1319
+ checkResults.push(Object.assign({ passed: true, msg: t('check.subpackages.config.success', {
1320
+ name: sub.name,
1321
+ }), type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$1));
1105
1322
  }
1106
1323
  /**
1107
1324
  * 校验 subpackage 配置是否有效
@@ -1109,7 +1326,9 @@ function checkSubpackages(config) {
1109
1326
  const subpackageEntryDir = path.join(entryDir, sub.root);
1110
1327
  // 检查是文件或者文件夹是否存在
1111
1328
  if (!fs.existsSync(subpackageEntryDir)) {
1112
- const errMsg = `Check subpackage<${sub.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${sub.name} entry dir, please check it`;
1329
+ const errMsg = t('check.subpackages.config.missingDir', {
1330
+ name: sub.name,
1331
+ });
1113
1332
  logger.error(errMsg);
1114
1333
  if ((_c = config === null || config === void 0 ? void 0 : config.dev) === null || _c === void 0 ? void 0 : _c.enable) {
1115
1334
  checkResults.push(Object.assign({ passed: false, msg: errMsg, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$1));
@@ -1119,19 +1338,22 @@ function checkSubpackages(config) {
1119
1338
  }
1120
1339
  }
1121
1340
  else {
1122
- checkResults.push(Object.assign({ passed: true, msg: `Check subpackage<${sub.name}> config successfully`, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$1));
1341
+ checkResults.push(Object.assign({ passed: true, msg: t('check.subpackages.config.success', {
1342
+ name: sub.name,
1343
+ }), type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME }, defaultCheckConfig$1));
1123
1344
  }
1124
1345
  });
1125
1346
  if (checkResults.length && checkResults.every(item => item.passed)) {
1126
- logger.info('Check subpackages config successfully');
1347
+ logger.info(t('log.check.subpackages.success'));
1127
1348
  }
1128
1349
  return checkResults;
1129
1350
  }
1130
1351
 
1131
1352
  const defaultCheckConfig = {
1132
1353
  dimension: CHECK_DIMENSION.IndependentPackage,
1354
+ required: true,
1133
1355
  };
1134
- function checkIndependentPackages(config) {
1356
+ function checkIndependentPackages(config, t) {
1135
1357
  var _a;
1136
1358
  const { entry: entryDir } = config;
1137
1359
  const isEnableDev = (_a = config === null || config === void 0 ? void 0 : config.dev) === null || _a === void 0 ? void 0 : _a.enable;
@@ -1139,14 +1361,14 @@ function checkIndependentPackages(config) {
1139
1361
  /**
1140
1362
  * 开始校验 subpackages 配置是否有效
1141
1363
  */
1142
- logger.info('start check independent subpackages in game.json');
1364
+ logger.info(t('log.check.independent.start'));
1143
1365
  const independentSubpackages = getIndependentPackagesConfig(entryDir);
1144
1366
  independentSubpackages.forEach(sub => {
1145
1367
  /**
1146
1368
  * 校验 independent subpackage 配置是否为空
1147
1369
  */
1148
1370
  if (!sub.name || !sub.root) {
1149
- const errMsg = 'Check independent subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more independent subpackages is empty. Please ensure that all independent subpackages have non-empty root and name values.';
1371
+ const errMsg = t('check.independent.config.empty');
1150
1372
  logger.error(errMsg);
1151
1373
  if (isEnableDev) {
1152
1374
  checkResults.push(Object.assign(Object.assign({}, defaultCheckConfig), { passed: false, msg: errMsg, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME, name: sub.name }));
@@ -1156,7 +1378,9 @@ function checkIndependentPackages(config) {
1156
1378
  }
1157
1379
  }
1158
1380
  else {
1159
- checkResults.push(Object.assign(Object.assign({}, defaultCheckConfig), { passed: true, msg: `Check independent package<${sub.name}> config successfully`, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME, name: sub.name }));
1381
+ checkResults.push(Object.assign(Object.assign({}, defaultCheckConfig), { passed: true, msg: t('check.independent.config.success', {
1382
+ name: sub.name,
1383
+ }), type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME, name: sub.name }));
1160
1384
  }
1161
1385
  /**
1162
1386
  * 校验 independent subpackage 配置是否有效
@@ -1164,7 +1388,9 @@ function checkIndependentPackages(config) {
1164
1388
  const subpackageEntryDir = path.join(entryDir, sub.root);
1165
1389
  // 检查是文件或者文件夹是否存在
1166
1390
  if (!fs.existsSync(subpackageEntryDir)) {
1167
- const errMsg = `Check independent package<${sub.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${sub.name} entry dir, please check it`;
1391
+ const errMsg = t('check.independent.config.missingDir', {
1392
+ name: sub.name,
1393
+ });
1168
1394
  logger.error(errMsg);
1169
1395
  if (isEnableDev) {
1170
1396
  checkResults.push(Object.assign(Object.assign({}, defaultCheckConfig), { passed: false, msg: errMsg, type: 'config', level: 'error', file: GAME_ORIGIN_CONFIG_FILE_NAME, name: sub.name }));
@@ -1176,11 +1402,14 @@ function checkIndependentPackages(config) {
1176
1402
  else {
1177
1403
  checkResults.push({
1178
1404
  passed: true,
1179
- msg: `Check independent package<${sub.name}> config successfully`,
1405
+ msg: t('check.independent.config.success', {
1406
+ name: sub.name,
1407
+ }),
1180
1408
  type: 'config',
1181
1409
  level: 'error',
1182
1410
  file: GAME_ORIGIN_CONFIG_FILE_NAME,
1183
1411
  dimension: CHECK_DIMENSION.IndependentPackage,
1412
+ required: true,
1184
1413
  name: sub.name,
1185
1414
  });
1186
1415
  }
@@ -1195,6 +1424,7 @@ function checkIndependentPackages(config) {
1195
1424
  limit: independentSubPkgSizeLimit,
1196
1425
  dimension: CHECK_DIMENSION.IndependentPackage,
1197
1426
  level: isEnableDev ? 'warning' : 'error',
1427
+ t,
1198
1428
  });
1199
1429
  checkResults.push(checkSizeResult);
1200
1430
  logger.info(checkSizeResult.msg);
@@ -1207,11 +1437,11 @@ function checkIndependentPackages(config) {
1207
1437
  }
1208
1438
  });
1209
1439
  if (checkResults.length && checkResults.every(item => item.passed)) {
1210
- logger.info('Check independent subpackages config successfully');
1440
+ logger.info(t('log.check.independent.success'));
1211
1441
  }
1212
1442
  return checkResults;
1213
1443
  }
1214
- function checkPkgSize({ entryDir, limit, pkgName, dimension, level, }) {
1444
+ function checkPkgSize({ entryDir, limit, pkgName, dimension, level, t, }) {
1215
1445
  const size = getDirSizeSync({
1216
1446
  rootDir: entryDir,
1217
1447
  entryDir,
@@ -1222,12 +1452,20 @@ function checkPkgSize({ entryDir, limit, pkgName, dimension, level, }) {
1222
1452
  return {
1223
1453
  passed,
1224
1454
  msg: passed
1225
- ? `Check package ${pkgName} size ${sizeMB.toFixed(2)}MB check successfully`
1226
- : `Check package ${pkgName} size ${sizeMB.toFixed(2)}MB exceeds limit ${limitMB.toFixed(2)}MB`,
1455
+ ? t('check.pkgSize.success', {
1456
+ pkgName,
1457
+ sizeMB: sizeMB.toFixed(2),
1458
+ })
1459
+ : t('check.pkgSize.exceeds', {
1460
+ pkgName,
1461
+ sizeMB: sizeMB.toFixed(2),
1462
+ limitMB: limitMB.toFixed(2),
1463
+ }),
1227
1464
  type: 'size',
1228
1465
  level,
1229
1466
  size,
1230
1467
  dimension,
1468
+ required: true,
1231
1469
  name: pkgName,
1232
1470
  };
1233
1471
  }
@@ -1261,7 +1499,7 @@ const API_LIST = [
1261
1499
  desc: "Get entrance mission reward"
1262
1500
  }
1263
1501
  ];
1264
- function checkAPI(config) {
1502
+ function checkAPI(config, t) {
1265
1503
  var _a;
1266
1504
  if (!((_a = config === null || config === void 0 ? void 0 : config.build) === null || _a === void 0 ? void 0 : _a.enableAPICheck)) {
1267
1505
  return [];
@@ -1329,10 +1567,13 @@ function checkAPI(config) {
1329
1567
  }
1330
1568
  const results = API_LIST.map(({ name }) => {
1331
1569
  const files = Array.from(hitFilesMap.get(name) || []);
1570
+ const passed = files.length > 0;
1332
1571
  return {
1333
1572
  name,
1334
- msg: `${files.length > 0 ? `${name} integrated!` : `${name} not integrated!`}`,
1335
- passed: files.length > 0,
1573
+ msg: passed
1574
+ ? t('check.api.integrated', { name })
1575
+ : `${t('check.api.notIntegrated', { name })} ${t('check.api.suggestedActionSuffix')}`,
1576
+ passed,
1336
1577
  files,
1337
1578
  type: 'api',
1338
1579
  level: 'warning',
@@ -1349,28 +1590,30 @@ function escapeRegex(s) {
1349
1590
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1350
1591
  }
1351
1592
 
1352
- async function checkPkgs(config) {
1353
- logger.info('开始校验项目');
1593
+ async function checkPkgs(config, context = {}) {
1594
+ setPackRuntimeLanguage(context === null || context === void 0 ? void 0 : context.lang);
1595
+ const t = createPackTranslator(context === null || context === void 0 ? void 0 : context.lang);
1596
+ logger.info(getPackTranslator()('log.check.start'));
1354
1597
  /**
1355
1598
  * 1. 校验项目
1356
1599
  */
1357
- const projectCheckResult = checkProject(config);
1600
+ const projectCheckResult = checkProject(config, t);
1358
1601
  /**
1359
1602
  * 2. 如果有,校验分包
1360
1603
  */
1361
- const subpackagesCheckResult = checkSubpackages(config);
1604
+ const subpackagesCheckResult = checkSubpackages(config, t);
1362
1605
  /**
1363
1606
  * 3. 校验主包
1364
1607
  */
1365
- const mainPackageCheckResult = checkMainPackage(config);
1608
+ const mainPackageCheckResult = checkMainPackage(config, t);
1366
1609
  /**
1367
1610
  * 校验独立分包
1368
1611
  */
1369
- const independentPackagesCheckResult = checkIndependentPackages(config);
1612
+ const independentPackagesCheckResult = checkIndependentPackages(config, t);
1370
1613
  /**
1371
1614
  * 校验 API 调用
1372
1615
  */
1373
- const apiCheckResult = checkAPI(config);
1616
+ const apiCheckResult = checkAPI(config, t);
1374
1617
  return [
1375
1618
  ...projectCheckResult,
1376
1619
  ...mainPackageCheckResult,
@@ -1381,8 +1624,9 @@ async function checkPkgs(config) {
1381
1624
  }
1382
1625
 
1383
1626
  async function setup(config) {
1627
+ const t = getPackTranslator();
1384
1628
  const { entry: entryDir, output: outputDir } = config;
1385
- logger.info('开始基于源代码中的 game.json 生成 packageConfig.json');
1629
+ logger.info(t('log.setup.startGeneratePackageConfig'));
1386
1630
  const gameJsonPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);
1387
1631
  const gameJson = JSON.parse(fs.readFileSync(gameJsonPath, 'utf-8'));
1388
1632
  const packages = {};
@@ -1433,7 +1677,7 @@ async function setup(config) {
1433
1677
  }
1434
1678
  fs.mkdirSync(outputDir);
1435
1679
  fs.writeFileSync(path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME), JSON.stringify(result, null, 2));
1436
- logger.info('基于源代码中的 game.json 生成 packageConfig.json 成功');
1680
+ logger.info(t('log.setup.generatePackageConfigSuccess'));
1437
1681
  return result;
1438
1682
  }
1439
1683
  function transformSubPackages(configs) {
@@ -1510,8 +1754,9 @@ function collectPkgJsFiles({ entry, root, exts = ['.js', '.ts', '.jsx', '.tsx'],
1510
1754
  }
1511
1755
  // 构建每个包的 map
1512
1756
  function collectMaps(config, packages) {
1757
+ const t = getPackTranslator();
1513
1758
  const { entry: entryDir } = config;
1514
- logger.info('开始基于游戏源代码收集分包中的 JS 文件');
1759
+ logger.info(t('log.collectMaps.start'));
1515
1760
  const result = {};
1516
1761
  // 1. 先收集所有分包根目录名(如 subpackages/level1、subpackages/level2)
1517
1762
  const subRoots = Object.values(packages)
@@ -1529,7 +1774,9 @@ function collectMaps(config, packages) {
1529
1774
  });
1530
1775
  if (openDataContextEntry) {
1531
1776
  uniqueSubRoots.push(openDataContextEntry);
1532
- logger.info(`开放数据域目录:${openDataContextEntry}`);
1777
+ logger.info(t('log.collectMaps.openDataContextDir', {
1778
+ dir: openDataContextEntry,
1779
+ }));
1533
1780
  }
1534
1781
  // 主包:只收集 entryDir 下非分包目录, 并排除 开放数据域的文件夹目录(如果有)
1535
1782
  jsFiles = collectPkgJsFiles({
@@ -1560,7 +1807,7 @@ function collectMaps(config, packages) {
1560
1807
  [packNameRoot ? `${packNameRoot}/game.pack.js` : 'game.pack.js']: list,
1561
1808
  };
1562
1809
  }
1563
- logger.info('基于游戏源代码收集分包中的 JS 文件完成');
1810
+ logger.info(t('log.collectMaps.done'));
1564
1811
  return result;
1565
1812
  }
1566
1813
 
@@ -1590,7 +1837,7 @@ async function getPluginInfo(params) {
1590
1837
  }
1591
1838
  return { url: meta.PackageCDNURL, md5: meta.PackageMD5 };
1592
1839
  }
1593
- async function addDepsToPackages(gameEntry, outputDir, allDeps) {
1840
+ async function addDepsToPackages(gameEntry, outputDir, allDeps, config) {
1594
1841
  var _a;
1595
1842
  const gamePackConfigPath = path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME);
1596
1843
  const gameJsonPath = path.join(gameEntry, GAME_ORIGIN_CONFIG_FILE_NAME);
@@ -1618,10 +1865,21 @@ async function addDepsToPackages(gameEntry, outputDir, allDeps) {
1618
1865
  continue;
1619
1866
  const version = pluginConfig[pluginName].version;
1620
1867
  const pluginPkgName = `${pluginName}_${version}`;
1621
- const { url, md5 } = await getPluginInfo({
1622
- plugin_name: pluginName.toLowerCase(),
1623
- plugin_version: version
1624
- });
1868
+ let url = '';
1869
+ let md5 = '';
1870
+ if (config === null || config === void 0 ? void 0 : config.dev) {
1871
+ try {
1872
+ const res = await getPluginInfo({
1873
+ plugin_name: pluginName.toLowerCase(),
1874
+ plugin_version: version
1875
+ });
1876
+ url = res.url;
1877
+ md5 = res.md5;
1878
+ }
1879
+ catch (error) {
1880
+ throw new Error(`[ttmg-pack] Failed to get plugin info: ${error.message} plugin_name: ${pluginName}, plugin_version: ${version}`);
1881
+ }
1882
+ }
1625
1883
  gamePackConfig.packages[pkgName].dependencies.push(pluginPkgName);
1626
1884
  if (!gamePackConfig.packages[pluginPkgName]) {
1627
1885
  gamePackConfig.packages[pluginPkgName] = {
@@ -1774,7 +2032,7 @@ async function collectDeps(config, packages) {
1774
2032
  packageDeps: {},
1775
2033
  pluginDeps: {},
1776
2034
  });
1777
- await addDepsToPackages(gameEntry, gameOutput, result.pluginDeps);
2035
+ await addDepsToPackages(gameEntry, gameOutput, result.pluginDeps, config);
1778
2036
  return result;
1779
2037
  }
1780
2038
  function getRootPrefixes(gameEntry) {
@@ -1815,8 +2073,9 @@ function fileExistsWithExtensions(filePath) {
1815
2073
 
1816
2074
  async function pack({ gameEntry, pkgName, allDeps, allMaps, pkgConfig, destRoot, config, }) {
1817
2075
  var _a, _b, _c, _d;
2076
+ const t = getPackTranslator();
1818
2077
  let startTime = Date.now();
1819
- logger.info(`pack start,startTime:${startTime}`);
2078
+ logger.info(t('log.pack.start', { startTime }));
1820
2079
  const packMap = allMaps[pkgName];
1821
2080
  const moduleConfig = {
1822
2081
  main: pkgConfig.main,
@@ -1919,7 +2178,7 @@ async function pack({ gameEntry, pkgName, allDeps, allMaps, pkgConfig, destRoot,
1919
2178
  const fileContent = bundledCode + `\n//# sourceURL=${packFileName}`;
1920
2179
  fs.writeFileSync(outFile, fileContent, 'utf-8');
1921
2180
  }
1922
- logger.info(`pack end,packName:${pkgName}`);
2181
+ logger.info(t('log.pack.end', { pkgName }));
1923
2182
  }
1924
2183
  }
1925
2184
 
@@ -1959,9 +2218,10 @@ async function partition({ pkgRoot, destRoot, packedFiles, gameEntry, gameOutput
1959
2218
  }
1960
2219
 
1961
2220
  async function makePkgs(config) {
2221
+ const t = getPackTranslator();
1962
2222
  const { entry: gameEntry, output: gameOutput } = config;
1963
2223
  let startTime = Date.now();
1964
- logger.info(`pack start,startTime:${startTime}`);
2224
+ logger.info(t('log.makePkgs.start', { startTime }));
1965
2225
  const { packages } = await setup(config);
1966
2226
  const allDeps = await collectDeps(config, packages);
1967
2227
  const allMaps = collectMaps(config, packages);
@@ -1971,7 +2231,7 @@ async function makePkgs(config) {
1971
2231
  */
1972
2232
  await asyncPool$1(10, Object.keys(allMaps), async (pkgName) => {
1973
2233
  var _a;
1974
- logger.info(`开始基于游戏源代码打包,包名:${pkgName}`);
2234
+ logger.info(t('log.makePkgs.startPackBySource', { pkgName }));
1975
2235
  let startTime = Date.now();
1976
2236
  const pkgConfig = packages[pkgName];
1977
2237
  const pkgRoot = path.join(gameEntry, pkgConfig.root);
@@ -2001,17 +2261,24 @@ async function makePkgs(config) {
2001
2261
  });
2002
2262
  const pkgRootDir = path.join(gameOutput, pkgName);
2003
2263
  removeEmptyDir(pkgRootDir);
2004
- logger.info(`基于游戏源代码打包分包完成,包名:${pkgName}`);
2005
- logger.info(`基于游戏源代码打包分包耗时,包名:${pkgName},耗时:${Date.now() - startTime}ms`);
2264
+ logger.info(t('log.makePkgs.finishPackBySource', { pkgName }));
2265
+ logger.info(t('log.makePkgs.packBySourceCost', {
2266
+ pkgName,
2267
+ duration: Date.now() - startTime,
2268
+ }));
2006
2269
  });
2007
2270
  /**
2008
2271
  * build open data context
2009
2272
  */
2010
- logger.info(`开始基于开放数据域源代码打包`);
2273
+ logger.info(t('log.makePkgs.startOpenData'));
2011
2274
  startTime = Date.now();
2012
- logger.info(`基于开放数据域源代码打包完成`);
2013
- logger.info(`基于开放数据域源代码打包耗时,耗时:${Date.now() - startTime}ms`);
2014
- logger.info(`pack end,duration:${Date.now() - startTime}ms`);
2275
+ logger.info(t('log.makePkgs.finishOpenData'));
2276
+ logger.info(t('log.makePkgs.openDataCost', {
2277
+ duration: Date.now() - startTime,
2278
+ }));
2279
+ logger.info(t('log.makePkgs.end', {
2280
+ duration: Date.now() - startTime,
2281
+ }));
2015
2282
  return pkgOutput;
2016
2283
  }
2017
2284
 
@@ -2089,7 +2356,9 @@ async function clearPkgs(config, uselessDirs = ['node_modules', '__MACOSX']) {
2089
2356
  removeSystemUseless(config.entry, uselessDirs);
2090
2357
  }
2091
2358
 
2092
- async function debugPkgs(config) {
2359
+ async function debugPkgs(config, context = {}) {
2360
+ setPackRuntimeLanguage(context === null || context === void 0 ? void 0 : context.lang);
2361
+ const t = createPackTranslator(context === null || context === void 0 ? void 0 : context.lang);
2093
2362
  const { output: outputDir, dev: { enableLog }, } = config;
2094
2363
  logger.init(outputDir, enableLog);
2095
2364
  try {
@@ -2100,7 +2369,7 @@ async function debugPkgs(config) {
2100
2369
  /**
2101
2370
  * 校验
2102
2371
  */
2103
- const checkResults = await checkPkgs(config);
2372
+ const checkResults = await checkPkgs(config, context);
2104
2373
  /**
2105
2374
  * 如果有任何 error 类型的校验项失败,则不再继续后续流程,直接返回错误
2106
2375
  */
@@ -2111,7 +2380,7 @@ async function debugPkgs(config) {
2111
2380
  .join('\n');
2112
2381
  return {
2113
2382
  isSuccess: false,
2114
- errorMsg: `Project validation failed (Errors):\n${errorMsg}`,
2383
+ errorMsg: t('debug.validation.failed', { errorMsg }),
2115
2384
  checkResults,
2116
2385
  };
2117
2386
  }
@@ -2142,12 +2411,16 @@ async function debugPkgs(config) {
2142
2411
  }
2143
2412
  }
2144
2413
 
2145
- async function buildPkgs(config) {
2414
+ async function buildPkgs(config, context = {}) {
2415
+ setPackRuntimeLanguage(context === null || context === void 0 ? void 0 : context.lang);
2416
+ const t = getPackTranslator();
2146
2417
  const { output: outputDir, build } = config;
2147
2418
  let startTime = Date.now();
2148
2419
  logger.init(outputDir, true);
2149
- logger.info(`TTMG_PACK_VERSION: ${"0.4.0"}`);
2150
- logger.info(`pack start, startTime:${startTime}`);
2420
+ logger.info(t('log.build.version', {
2421
+ version: "0.4.4",
2422
+ }));
2423
+ logger.info(t('log.build.start', { startTime }));
2151
2424
  /**
2152
2425
  * 清理
2153
2426
  */
@@ -2155,7 +2428,7 @@ async function buildPkgs(config) {
2155
2428
  /**
2156
2429
  * 校验
2157
2430
  */
2158
- await checkPkgs(config);
2431
+ await checkPkgs(config, context);
2159
2432
  /**
2160
2433
  * 打包
2161
2434
  */
@@ -2169,7 +2442,7 @@ async function buildPkgs(config) {
2169
2442
  * 分拆 odr 包
2170
2443
  */
2171
2444
  }
2172
- logger.info(`pack end:${Date.now() - startTime}ms`);
2445
+ logger.info(t('log.build.end', { duration: Date.now() - startTime }));
2173
2446
  }
2174
2447
 
2175
2448
  async function getPkgs({ entryDir, }) {