@maoyugames/phaser-framework 1.0.2 → 1.0.3
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/cli/index.d.ts +1 -0
- package/dist/cli/index.js +293 -93
- package/dist/index.js +44 -35
- package/package.json +6 -2
package/dist/cli/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* pf build <platform|all> 构建某平台/全部平台(临时入口 + 编程式 vite + 外壳注入 + 校验)
|
|
8
8
|
* pf size-check [platform] 产物体积检查(扫 <root>/dist/<p>)
|
|
9
9
|
* pf verify-isolation [platform] SDK 隔离校验(扫 <root>/dist/<p>)
|
|
10
|
+
* pf verify [platform] [--no-build] 实跑冒烟验证(Playwright 无头:确认渲染 + 无运行期错误)
|
|
10
11
|
* pf cap <sync|open> [android|ios] Capacitor 同步/打开原生工程
|
|
11
12
|
* pf help 查看帮助
|
|
12
13
|
*
|
package/dist/cli/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import '../chunk-PKBMQBKP.js';
|
|
3
|
-
import
|
|
4
|
-
import { resolve, join, relative, basename, dirname } from 'path';
|
|
3
|
+
import pc6 from 'picocolors';
|
|
4
|
+
import { resolve, join, extname, relative, basename, dirname } from 'path';
|
|
5
5
|
import { randomBytes } from 'crypto';
|
|
6
6
|
import fse4 from 'fs-extra';
|
|
7
7
|
import { createRequire } from 'module';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
|
-
import { existsSync, readFileSync } from 'fs';
|
|
9
|
+
import { existsSync, mkdirSync, writeFileSync, readFile, readFileSync } from 'fs';
|
|
10
|
+
import http from 'http';
|
|
10
11
|
import { spawnSync } from 'child_process';
|
|
11
12
|
|
|
12
13
|
// src/cli/platforms-meta.ts
|
|
@@ -538,7 +539,7 @@ function writeShellFiles(distDir, projectRoot, files) {
|
|
|
538
539
|
const dst = join(distDir, f.relPath);
|
|
539
540
|
fse4.ensureDirSync(resolve(dst, ".."));
|
|
540
541
|
fse4.writeFileSync(dst, f.content, "utf-8");
|
|
541
|
-
console.log(
|
|
542
|
+
console.log(pc6.green(` \u2713 ${f.relPath} \u2192 ${relative(projectRoot, dst)}`));
|
|
542
543
|
}
|
|
543
544
|
}
|
|
544
545
|
function injectShell(opts) {
|
|
@@ -548,19 +549,19 @@ function injectShell(opts) {
|
|
|
548
549
|
case "tiktok":
|
|
549
550
|
return true;
|
|
550
551
|
case "facebook": {
|
|
551
|
-
console.log(
|
|
552
|
+
console.log(pc6.cyan(` \u25B6 [facebook] \u6CE8\u5165\u5916\u58F3\u6587\u4EF6`));
|
|
552
553
|
writeShellFiles(distDir, projectRoot, [renderFacebookAppConfig(config.facebook)]);
|
|
553
554
|
return true;
|
|
554
555
|
}
|
|
555
556
|
case "capacitor": {
|
|
556
|
-
console.log(
|
|
557
|
+
console.log(pc6.cyan(` \u25B6 [capacitor] \u751F\u6210 capacitor.config.ts(\u9879\u76EE\u6839)`));
|
|
557
558
|
const capCfgPath = resolve(projectRoot, "capacitor.config.ts");
|
|
558
559
|
fse4.writeFileSync(capCfgPath, renderCapacitorConfig(config.capacitor), "utf-8");
|
|
559
|
-
console.log(
|
|
560
|
+
console.log(pc6.green(` \u2713 capacitor.config.ts \u2192 ${relative(projectRoot, capCfgPath)}`));
|
|
560
561
|
return true;
|
|
561
562
|
}
|
|
562
563
|
case "wechat": {
|
|
563
|
-
console.log(
|
|
564
|
+
console.log(pc6.cyan(` \u25B6 [wechat] \u6CE8\u5165\u5916\u58F3\u6587\u4EF6`));
|
|
564
565
|
writeShellFiles(distDir, projectRoot, renderWeChatShells(config.wechat));
|
|
565
566
|
copyPublicAssetsToWechat(projectRoot, distDir);
|
|
566
567
|
copyWechatVendor(projectRoot, distDir);
|
|
@@ -573,37 +574,37 @@ function injectShell(opts) {
|
|
|
573
574
|
function copyPublicAssetsToWechat(projectRoot, distDir) {
|
|
574
575
|
const srcPublic = resolve(projectRoot, "src/game/public");
|
|
575
576
|
if (!fse4.existsSync(srcPublic)) return;
|
|
576
|
-
console.log(
|
|
577
|
+
console.log(pc6.cyan(" \u25B6 [wechat] \u62F7\u8D1D\u4E1A\u52A1\u9759\u6001\u8D44\u6E90(src/game/public)"));
|
|
577
578
|
fse4.copySync(srcPublic, distDir);
|
|
578
|
-
console.log(
|
|
579
|
+
console.log(pc6.green(" \u2713 src/game/public/* \u2192 dist/wechat/"));
|
|
579
580
|
}
|
|
580
581
|
function copyWechatVendor(projectRoot, distDir) {
|
|
581
|
-
console.log(
|
|
582
|
+
console.log(pc6.cyan(" \u25B6 [wechat] \u68C0\u6D4B\u5FAE\u4FE1\u9002\u914D\u5668(vendor)"));
|
|
582
583
|
const dirs = wechatVendorDirs(projectRoot);
|
|
583
584
|
const adapter = dirs.map((d) => join(d, "weapp-adapter.js")).find((p) => fse4.existsSync(p));
|
|
584
585
|
if (adapter) {
|
|
585
586
|
fse4.copyFileSync(adapter, join(distDir, "weapp-adapter.js"));
|
|
586
|
-
console.log(
|
|
587
|
+
console.log(pc6.green(" \u2713 weapp-adapter.js \u2192 dist/wechat/weapp-adapter.js"));
|
|
587
588
|
const vendorDir = resolve(adapter, "..");
|
|
588
589
|
const symbol = join(vendorDir, "symbol.js");
|
|
589
590
|
if (fse4.existsSync(symbol)) {
|
|
590
591
|
fse4.copyFileSync(symbol, join(distDir, "symbol.js"));
|
|
591
|
-
console.log(
|
|
592
|
+
console.log(pc6.green(" \u2713 symbol.js \u2192 dist/wechat/symbol.js"));
|
|
592
593
|
}
|
|
593
594
|
return true;
|
|
594
595
|
}
|
|
595
|
-
console.log(
|
|
596
|
+
console.log(pc6.yellow(pc6.bold(" \u26A0 \u7F3A\u5C11\u5FAE\u4FE1\u9002\u914D\u5668 weapp-adapter.js")));
|
|
596
597
|
console.log(
|
|
597
|
-
|
|
598
|
+
pc6.yellow(
|
|
598
599
|
" \u5FAE\u4FE1\u5C0F\u6E38\u620F\u65E0 DOM,\u9700\u6B64\u5B98\u65B9\u9002\u914D\u5668\u6CE8\u5165 canvas/document shim,\u5426\u5219 game.js \u542F\u52A8\u5373\u62A5\u9519\u3002"
|
|
599
600
|
)
|
|
600
601
|
);
|
|
601
|
-
console.log(
|
|
602
|
+
console.log(pc6.yellow(` \u8BF7\u628A\u5B98\u65B9 weapp-adapter.js(\u53CA\u53EF\u9009 symbol.js)\u653E\u5230\u4EE5\u4E0B\u4EFB\u4E00\u76EE\u5F55\u540E\u91CD\u65B0\u6784\u5EFA:`));
|
|
602
603
|
for (const d of wechatVendorDirs(projectRoot)) {
|
|
603
|
-
console.log(
|
|
604
|
+
console.log(pc6.yellow(` - ${relative(projectRoot, d)}/weapp-adapter.js`));
|
|
604
605
|
}
|
|
605
606
|
console.log(
|
|
606
|
-
|
|
607
|
+
pc6.yellow(" \u83B7\u53D6\u65B9\u5F0F:\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u65B0\u5EFA\u300C\u5C0F\u6E38\u620F\u300D\u9879\u76EE\u6A21\u677F\u91CC\u9644\u5E26 weapp-adapter.js\u3002")
|
|
607
608
|
);
|
|
608
609
|
return false;
|
|
609
610
|
}
|
|
@@ -627,43 +628,43 @@ function findMainBundle(files) {
|
|
|
627
628
|
}
|
|
628
629
|
function checkPlatform(platform, distDir) {
|
|
629
630
|
if (!fse4.existsSync(distDir)) {
|
|
630
|
-
console.log(
|
|
631
|
+
console.log(pc6.gray(` [${platform}] \u672A\u6784\u5EFA,\u8DF3\u8FC7`));
|
|
631
632
|
return true;
|
|
632
633
|
}
|
|
633
634
|
const files = listFiles(distDir);
|
|
634
635
|
const total = files.reduce((s, f) => s + f.size, 0);
|
|
635
636
|
const main2 = findMainBundle(files);
|
|
636
637
|
const limits = SIZE_LIMITS[platform];
|
|
637
|
-
console.log(
|
|
638
|
-
console.log(` \u603B\u4F53\u79EF:${
|
|
638
|
+
console.log(pc6.cyan(` [${platform}]`));
|
|
639
|
+
console.log(` \u603B\u4F53\u79EF:${pc6.bold(formatBytes(total))}(${files.length} \u4E2A\u6587\u4EF6)`);
|
|
639
640
|
if (main2) {
|
|
640
|
-
console.log(` \u4E3B bundle:${basename(main2.path)} = ${
|
|
641
|
+
console.log(` \u4E3B bundle:${basename(main2.path)} = ${pc6.bold(formatBytes(main2.size))}`);
|
|
641
642
|
}
|
|
642
643
|
let ok = true;
|
|
643
644
|
if (limits?.totalHardLimit) {
|
|
644
645
|
if (total > limits.totalHardLimit) {
|
|
645
646
|
console.log(
|
|
646
|
-
|
|
647
|
+
pc6.red(
|
|
647
648
|
` \u2717 \u8D85\u51FA TikTok \u6574\u5305\u786C\u4E0A\u9650 ${formatBytes(limits.totalHardLimit)}(\u8D85 ${formatBytes(total - limits.totalHardLimit)})`
|
|
648
649
|
)
|
|
649
650
|
);
|
|
650
651
|
ok = false;
|
|
651
652
|
} else {
|
|
652
653
|
console.log(
|
|
653
|
-
|
|
654
|
+
pc6.green(` \u2713 \u5728 TikTok 50MB \u6574\u5305\u4E0A\u9650\u5185(\u4F59 ${formatBytes(limits.totalHardLimit - total)})`)
|
|
654
655
|
);
|
|
655
656
|
}
|
|
656
657
|
}
|
|
657
658
|
if (limits?.mainBundleSoftLimit && main2) {
|
|
658
659
|
if (main2.size > limits.mainBundleSoftLimit) {
|
|
659
660
|
console.log(
|
|
660
|
-
|
|
661
|
+
pc6.yellow(
|
|
661
662
|
` \u26A0 \u5FAE\u4FE1\u4E3B\u5305\u8D85\u8FC7\u5EFA\u8BAE ${formatBytes(limits.mainBundleSoftLimit)}(\u5F53\u524D ${formatBytes(main2.size)});\u5EFA\u8BAE\u62C6\u5206\u5305\u6216\u88C1\u526A\u8D44\u6E90,\u4F46\u4E0D\u963B\u65AD\u6784\u5EFA`
|
|
662
663
|
)
|
|
663
664
|
);
|
|
664
665
|
} else {
|
|
665
666
|
console.log(
|
|
666
|
-
|
|
667
|
+
pc6.green(` \u2713 \u5FAE\u4FE1\u4E3B\u5305\u5728 4MB \u5EFA\u8BAE\u503C\u5185(\u4F59 ${formatBytes(limits.mainBundleSoftLimit - main2.size)})`)
|
|
667
668
|
);
|
|
668
669
|
}
|
|
669
670
|
}
|
|
@@ -672,29 +673,29 @@ function checkPlatform(platform, distDir) {
|
|
|
672
673
|
function runSizeCheck(target) {
|
|
673
674
|
const ctx = resolveProject();
|
|
674
675
|
const targets = target ? isPlatform(target) ? [target] : invalidTarget(target) : ALL_PLATFORMS;
|
|
675
|
-
console.log(
|
|
676
|
+
console.log(pc6.cyan(pc6.bold("\u25B6 \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5")));
|
|
676
677
|
let allOk = true;
|
|
677
678
|
for (const p of targets) {
|
|
678
679
|
const distDir = join(ctx.root, "dist", p);
|
|
679
680
|
if (!checkPlatform(p, distDir)) allOk = false;
|
|
680
681
|
}
|
|
681
682
|
if (!allOk) {
|
|
682
|
-
console.log(
|
|
683
|
+
console.log(pc6.red(pc6.bold("\n\u2717 \u4F53\u79EF\u68C0\u67E5\u672A\u901A\u8FC7(\u5B58\u5728\u8D85\u786C\u4E0A\u9650\u7684\u5E73\u53F0)")));
|
|
683
684
|
return false;
|
|
684
685
|
}
|
|
685
|
-
console.log(
|
|
686
|
+
console.log(pc6.green(pc6.bold("\n\u2713 \u4F53\u79EF\u68C0\u67E5\u5B8C\u6210")));
|
|
686
687
|
return true;
|
|
687
688
|
}
|
|
688
689
|
function sizeCheckPlatform(platform, distDir) {
|
|
689
|
-
console.log(
|
|
690
|
+
console.log(pc6.cyan(pc6.bold("\u25B6 \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5")));
|
|
690
691
|
const ok = checkPlatform(platform, distDir);
|
|
691
|
-
if (ok) console.log(
|
|
692
|
-
else console.log(
|
|
692
|
+
if (ok) console.log(pc6.green(pc6.bold("\u2713 \u4F53\u79EF\u68C0\u67E5\u5B8C\u6210")));
|
|
693
|
+
else console.log(pc6.red(pc6.bold("\u2717 \u4F53\u79EF\u68C0\u67E5\u672A\u901A\u8FC7")));
|
|
693
694
|
return ok;
|
|
694
695
|
}
|
|
695
696
|
function invalidTarget(target) {
|
|
696
|
-
console.log(
|
|
697
|
-
console.log(
|
|
697
|
+
console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
|
|
698
|
+
console.log(pc6.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")}`));
|
|
698
699
|
process.exit(1);
|
|
699
700
|
}
|
|
700
701
|
function collectJsFiles(dir) {
|
|
@@ -716,12 +717,12 @@ function snippetAround(text, index, span = 60) {
|
|
|
716
717
|
function verifyPlatform(platform, distDir, projectRoot) {
|
|
717
718
|
const rules = ISOLATION_RULES[platform];
|
|
718
719
|
if (!fse4.existsSync(distDir)) {
|
|
719
|
-
console.log(
|
|
720
|
+
console.log(pc6.gray(` [${platform}] \u672A\u6784\u5EFA(${relative(projectRoot, distDir)} \u4E0D\u5B58\u5728),\u8DF3\u8FC7`));
|
|
720
721
|
return 0;
|
|
721
722
|
}
|
|
722
723
|
const files = collectJsFiles(distDir);
|
|
723
724
|
if (files.length === 0) {
|
|
724
|
-
console.log(
|
|
725
|
+
console.log(pc6.yellow(` [${platform}] \u672A\u53D1\u73B0 JS \u4EA7\u7269,\u8DF3\u8FC7`));
|
|
725
726
|
return 0;
|
|
726
727
|
}
|
|
727
728
|
let hits = 0;
|
|
@@ -735,13 +736,13 @@ function verifyPlatform(platform, distDir, projectRoot) {
|
|
|
735
736
|
hits++;
|
|
736
737
|
perSig++;
|
|
737
738
|
const rel = relative(projectRoot, file);
|
|
738
|
-
console.log(
|
|
739
|
-
console.log(
|
|
740
|
-
console.log(
|
|
739
|
+
console.log(pc6.red(` \u2717 [${platform}] \u547D\u4E2D\u7981\u7528 SDK \u7B7E\u540D ${pc6.bold(sig)}`));
|
|
740
|
+
console.log(pc6.gray(` \u6587\u4EF6:${rel}`));
|
|
741
|
+
console.log(pc6.gray(` \u7247\u6BB5:\u2026${snippetAround(text, idx)}\u2026`));
|
|
741
742
|
from = idx + sig.length;
|
|
742
743
|
idx = text.indexOf(sig, from);
|
|
743
744
|
if (perSig >= 3 && idx !== -1) {
|
|
744
|
-
console.log(
|
|
745
|
+
console.log(pc6.gray(` (\u8BE5\u7B7E\u540D\u5728\u672C\u6587\u4EF6\u8FD8\u6709\u66F4\u591A\u547D\u4E2D,\u5DF2\u6298\u53E0)`));
|
|
745
746
|
break;
|
|
746
747
|
}
|
|
747
748
|
}
|
|
@@ -749,7 +750,7 @@ function verifyPlatform(platform, distDir, projectRoot) {
|
|
|
749
750
|
}
|
|
750
751
|
if (hits === 0) {
|
|
751
752
|
console.log(
|
|
752
|
-
|
|
753
|
+
pc6.green(` \u2713 [${platform}] \u9694\u79BB\u901A\u8FC7(\u626B\u63CF ${files.length} \u4E2A JS \u6587\u4EF6,\u65E0\u5176\u5B83\u5E73\u53F0 SDK \u7B7E\u540D)`)
|
|
753
754
|
);
|
|
754
755
|
}
|
|
755
756
|
return hits;
|
|
@@ -757,32 +758,32 @@ function verifyPlatform(platform, distDir, projectRoot) {
|
|
|
757
758
|
function runVerifyIsolation(target) {
|
|
758
759
|
const ctx = resolveProject();
|
|
759
760
|
const targets = target ? isPlatform(target) ? [target] : invalidTarget2(target) : ALL_PLATFORMS;
|
|
760
|
-
console.log(
|
|
761
|
+
console.log(pc6.cyan(pc6.bold("\u25B6 SDK \u9694\u79BB\u6821\u9A8C")));
|
|
761
762
|
let totalHits = 0;
|
|
762
763
|
for (const p of targets) {
|
|
763
764
|
totalHits += verifyPlatform(p, join(ctx.root, "dist", p), ctx.root);
|
|
764
765
|
}
|
|
765
766
|
if (totalHits > 0) {
|
|
766
|
-
console.log(
|
|
767
|
+
console.log(pc6.red(pc6.bold(`
|
|
767
768
|
\u2717 \u9694\u79BB\u6821\u9A8C\u5931\u8D25:\u5171\u53D1\u73B0 ${totalHits} \u5904\u8DE8\u5E73\u53F0 SDK \u7B7E\u540D\u6CC4\u6F0F`)));
|
|
768
769
|
return false;
|
|
769
770
|
}
|
|
770
|
-
console.log(
|
|
771
|
+
console.log(pc6.green(pc6.bold("\n\u2713 \u9694\u79BB\u6821\u9A8C\u5168\u90E8\u901A\u8FC7")));
|
|
771
772
|
return true;
|
|
772
773
|
}
|
|
773
774
|
function verifyIsolationPlatform(platform, distDir, projectRoot) {
|
|
774
|
-
console.log(
|
|
775
|
+
console.log(pc6.cyan(pc6.bold("\u25B6 SDK \u9694\u79BB\u6821\u9A8C")));
|
|
775
776
|
const hits = verifyPlatform(platform, distDir, projectRoot);
|
|
776
777
|
if (hits > 0) {
|
|
777
|
-
console.log(
|
|
778
|
+
console.log(pc6.red(pc6.bold(`\u2717 \u9694\u79BB\u6821\u9A8C\u5931\u8D25:${hits} \u5904\u8DE8\u5E73\u53F0 SDK \u7B7E\u540D\u6CC4\u6F0F`)));
|
|
778
779
|
return false;
|
|
779
780
|
}
|
|
780
|
-
console.log(
|
|
781
|
+
console.log(pc6.green(pc6.bold("\u2713 \u9694\u79BB\u6821\u9A8C\u901A\u8FC7")));
|
|
781
782
|
return true;
|
|
782
783
|
}
|
|
783
784
|
function invalidTarget2(target) {
|
|
784
|
-
console.log(
|
|
785
|
-
console.log(
|
|
785
|
+
console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
|
|
786
|
+
console.log(pc6.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")}`));
|
|
786
787
|
process.exit(1);
|
|
787
788
|
}
|
|
788
789
|
|
|
@@ -928,7 +929,7 @@ function findFirstHtml(dir) {
|
|
|
928
929
|
return void 0;
|
|
929
930
|
}
|
|
930
931
|
async function buildPlatform(platform, ctx, config, vite) {
|
|
931
|
-
console.log(
|
|
932
|
+
console.log(pc6.bgCyan(pc6.black(` \u6784\u5EFA\u5E73\u53F0:${platform} `)));
|
|
932
933
|
const cache = cacheDir(ctx.root);
|
|
933
934
|
fse4.ensureDirSync(cache);
|
|
934
935
|
const hash = randomBytes(4).toString("hex");
|
|
@@ -948,7 +949,7 @@ async function buildPlatform(platform, ctx, config, vite) {
|
|
|
948
949
|
tempFiles.push(htmlPath);
|
|
949
950
|
inputFile = htmlPath;
|
|
950
951
|
}
|
|
951
|
-
console.log(
|
|
952
|
+
console.log(pc6.cyan(` \u25B6 [${platform}] vite build`));
|
|
952
953
|
const inlineConfig = createPlatformConfig(platform, {
|
|
953
954
|
projectRoot: ctx.root,
|
|
954
955
|
viteRoot: platform === "wechat" ? ctx.root : cache,
|
|
@@ -961,22 +962,22 @@ async function buildPlatform(platform, ctx, config, vite) {
|
|
|
961
962
|
if (platform !== "wechat") {
|
|
962
963
|
normalizeHtmlOutput(distDir);
|
|
963
964
|
}
|
|
964
|
-
console.log(
|
|
965
|
+
console.log(pc6.green(` \u2713 [${platform}] vite build \u5B8C\u6210 \u2192 ${relative(ctx.root, distDir)}`));
|
|
965
966
|
const injectOk = injectShell({ platform, projectRoot: ctx.root, distDir, config });
|
|
966
967
|
const sizeOk = sizeCheckPlatform(platform, distDir);
|
|
967
968
|
const isoOk = verifyIsolationPlatform(platform, distDir, ctx.root);
|
|
968
969
|
const allOk = injectOk && sizeOk && isoOk;
|
|
969
970
|
if (allOk) {
|
|
970
|
-
console.log(
|
|
971
|
+
console.log(pc6.green(pc6.bold(`\u2713 [${platform}] \u6784\u5EFA + \u6821\u9A8C\u5B8C\u6210 \u2192 ${relative(ctx.root, distDir)}
|
|
971
972
|
`)));
|
|
972
973
|
} else {
|
|
973
|
-
console.log(
|
|
974
|
+
console.log(pc6.red(pc6.bold(`\u2717 [${platform}] \u6821\u9A8C/\u6CE8\u5165\u672A\u5168\u90E8\u901A\u8FC7
|
|
974
975
|
`)));
|
|
975
976
|
}
|
|
976
977
|
return allOk;
|
|
977
978
|
} catch (e) {
|
|
978
|
-
console.log(
|
|
979
|
-
if (e.stack) console.log(
|
|
979
|
+
console.log(pc6.red(` \u2717 [${platform}] vite build \u5931\u8D25:${e.message}`));
|
|
980
|
+
if (e.stack) console.log(pc6.gray(e.stack ?? ""));
|
|
980
981
|
return false;
|
|
981
982
|
} finally {
|
|
982
983
|
for (const f of tempFiles) {
|
|
@@ -989,37 +990,37 @@ async function buildPlatform(platform, ctx, config, vite) {
|
|
|
989
990
|
}
|
|
990
991
|
async function runBuild(target) {
|
|
991
992
|
if (!target) {
|
|
992
|
-
console.log(
|
|
993
|
+
console.log(pc6.red("\u7528\u6CD5:pf build <web|tiktok|wechat|facebook|capacitor|all>"));
|
|
993
994
|
return false;
|
|
994
995
|
}
|
|
995
996
|
const platforms = target === "all" ? ALL_PLATFORMS : isPlatform(target) ? [target] : null;
|
|
996
997
|
if (!platforms) {
|
|
997
|
-
console.log(
|
|
998
|
-
console.log(
|
|
998
|
+
console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
|
|
999
|
+
console.log(pc6.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")} / all`));
|
|
999
1000
|
return false;
|
|
1000
1001
|
}
|
|
1001
1002
|
const ctx = resolveProject();
|
|
1002
1003
|
const config = await loadPlatformConfig(ctx);
|
|
1003
1004
|
const vite = await loadViteFromRoot(ctx.root);
|
|
1004
|
-
console.log(
|
|
1005
|
+
console.log(pc6.cyan(pc6.bold(`\u25B6 \u5F00\u59CB\u6784\u5EFA:${platforms.join(", ")}(\u9879\u76EE:${ctx.root})
|
|
1005
1006
|
`)));
|
|
1006
1007
|
const results = [];
|
|
1007
1008
|
for (const p of platforms) {
|
|
1008
1009
|
results.push({ platform: p, ok: await buildPlatform(p, ctx, config, vite) });
|
|
1009
1010
|
}
|
|
1010
|
-
console.log(
|
|
1011
|
+
console.log(pc6.cyan(pc6.bold("\u25B6 \u6784\u5EFA\u6C47\u603B")));
|
|
1011
1012
|
let allOk = true;
|
|
1012
1013
|
for (const r of results) {
|
|
1013
|
-
if (r.ok) console.log(
|
|
1014
|
+
if (r.ok) console.log(pc6.green(` \u2713 ${r.platform}`));
|
|
1014
1015
|
else {
|
|
1015
|
-
console.log(
|
|
1016
|
+
console.log(pc6.red(` \u2717 ${r.platform}`));
|
|
1016
1017
|
allOk = false;
|
|
1017
1018
|
}
|
|
1018
1019
|
}
|
|
1019
1020
|
if (!allOk) {
|
|
1020
|
-
console.log(
|
|
1021
|
+
console.log(pc6.red(pc6.bold("\n\u2717 \u5B58\u5728\u6784\u5EFA/\u6821\u9A8C\u5931\u8D25\u7684\u5E73\u53F0")));
|
|
1021
1022
|
} else {
|
|
1022
|
-
console.log(
|
|
1023
|
+
console.log(pc6.green(pc6.bold("\n\u2713 \u5168\u90E8\u5B8C\u6210")));
|
|
1023
1024
|
}
|
|
1024
1025
|
return allOk;
|
|
1025
1026
|
}
|
|
@@ -1043,8 +1044,8 @@ function renderHtmlShell2(platform, config, scriptSrc) {
|
|
|
1043
1044
|
async function runDev(target) {
|
|
1044
1045
|
const platform = target ? isPlatform(target) ? target : invalidTarget3(target) : "web";
|
|
1045
1046
|
if (platform === "wechat") {
|
|
1046
|
-
console.log(
|
|
1047
|
-
console.log(
|
|
1047
|
+
console.log(pc6.red("\u2717 wechat \u65E0 HTML dev server \u5F62\u6001\u3002"));
|
|
1048
|
+
console.log(pc6.yellow(" \u8BF7\u7528 `pf build wechat` \u4EA7\u51FA dist/wechat,\u518D\u7528\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6253\u5F00\u9884\u89C8\u3002"));
|
|
1048
1049
|
return false;
|
|
1049
1050
|
}
|
|
1050
1051
|
const ctx = resolveProject();
|
|
@@ -1096,9 +1097,9 @@ async function runDev(target) {
|
|
|
1096
1097
|
await server.listen();
|
|
1097
1098
|
const info = server.resolvedUrls;
|
|
1098
1099
|
const url = info?.local?.[0] ?? "http://localhost:5173/";
|
|
1099
|
-
console.log(
|
|
1100
|
-
console.log(` \u6253\u5F00:${
|
|
1101
|
-
console.log(
|
|
1100
|
+
console.log(pc6.green(pc6.bold(`\u25B6 [${platform}] dev server \u5C31\u7EEA`)));
|
|
1101
|
+
console.log(` \u6253\u5F00:${pc6.cyan(url)}`);
|
|
1102
|
+
console.log(pc6.gray(" (Ctrl+C \u9000\u51FA,\u4E34\u65F6\u5165\u53E3\u4F1A\u81EA\u52A8\u6E05\u7406)"));
|
|
1102
1103
|
const onExit = async () => {
|
|
1103
1104
|
cleanup();
|
|
1104
1105
|
await server.close();
|
|
@@ -1109,17 +1110,208 @@ async function runDev(target) {
|
|
|
1109
1110
|
return true;
|
|
1110
1111
|
} catch (e) {
|
|
1111
1112
|
cleanup();
|
|
1112
|
-
console.log(
|
|
1113
|
+
console.log(pc6.red(`\u2717 dev server \u542F\u52A8\u5931\u8D25:${e.message}`));
|
|
1113
1114
|
return false;
|
|
1114
1115
|
}
|
|
1115
1116
|
}
|
|
1116
1117
|
function invalidTarget3(target) {
|
|
1117
|
-
console.log(
|
|
1118
|
+
console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
|
|
1119
|
+
process.exit(1);
|
|
1120
|
+
}
|
|
1121
|
+
var CONTENT_TYPES = {
|
|
1122
|
+
".html": "text/html; charset=utf-8",
|
|
1123
|
+
".js": "text/javascript; charset=utf-8",
|
|
1124
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
1125
|
+
".json": "application/json; charset=utf-8",
|
|
1126
|
+
".css": "text/css; charset=utf-8",
|
|
1127
|
+
".png": "image/png",
|
|
1128
|
+
".jpg": "image/jpeg",
|
|
1129
|
+
".jpeg": "image/jpeg",
|
|
1130
|
+
".webp": "image/webp",
|
|
1131
|
+
".svg": "image/svg+xml",
|
|
1132
|
+
".wasm": "application/wasm"
|
|
1133
|
+
};
|
|
1134
|
+
function serveDist(distDir) {
|
|
1135
|
+
const server = http.createServer((req, res) => {
|
|
1136
|
+
let p = decodeURIComponent((req.url ?? "/").split("?")[0]);
|
|
1137
|
+
if (p === "/") p = "/index.html";
|
|
1138
|
+
if (p === "/favicon.ico") {
|
|
1139
|
+
res.statusCode = 204;
|
|
1140
|
+
res.end();
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1143
|
+
const fp = join(distDir, p);
|
|
1144
|
+
if (!resolve(fp).startsWith(resolve(distDir))) {
|
|
1145
|
+
res.statusCode = 403;
|
|
1146
|
+
res.end("forbidden");
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
readFile(fp, (err, data) => {
|
|
1150
|
+
if (err) {
|
|
1151
|
+
res.statusCode = 404;
|
|
1152
|
+
res.end("not found");
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
res.setHeader("Content-Type", CONTENT_TYPES[extname(fp).toLowerCase()] ?? "application/octet-stream");
|
|
1156
|
+
res.end(data);
|
|
1157
|
+
});
|
|
1158
|
+
});
|
|
1159
|
+
return new Promise((r) => {
|
|
1160
|
+
server.listen(0, "127.0.0.1", () => {
|
|
1161
|
+
const addr = server.address();
|
|
1162
|
+
const port = typeof addr === "object" && addr ? addr.port : 0;
|
|
1163
|
+
r({ server, port });
|
|
1164
|
+
});
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
function resolvePlaywright(root) {
|
|
1168
|
+
const req = createRequire(join(root, "package.json"));
|
|
1169
|
+
for (const name of ["playwright", "playwright-core", "@playwright/test"]) {
|
|
1170
|
+
try {
|
|
1171
|
+
const mod = req(name);
|
|
1172
|
+
if (mod && mod.chromium) return { chromium: mod.chromium };
|
|
1173
|
+
} catch {
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
return null;
|
|
1177
|
+
}
|
|
1178
|
+
async function readViewport(ctx) {
|
|
1179
|
+
try {
|
|
1180
|
+
const mod = await loadConfigModule(ctx.root, ctx.gameConfigPath);
|
|
1181
|
+
const cfg = mod.gameConfig ?? mod.default ?? {};
|
|
1182
|
+
const width = Number(cfg.designWidth) || 720;
|
|
1183
|
+
const height = Number(cfg.designHeight) || 1280;
|
|
1184
|
+
return { width, height };
|
|
1185
|
+
} catch {
|
|
1186
|
+
return { width: 720, height: 1280 };
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
async function runVerify(target, opts = {}) {
|
|
1190
|
+
const platform = target ? isPlatform(target) ? target : invalid(target) : "web";
|
|
1191
|
+
if (platform === "wechat") {
|
|
1192
|
+
console.log(pc6.yellow("\u26A0 wechat \u65E0 DOM\u3001\u9700\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177,\u65E0\u6CD5\u7528\u6D4F\u89C8\u5668 verify\u3002"));
|
|
1193
|
+
console.log(pc6.gray(" \u8BF7 `pf build wechat` \u540E\u7528\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6253\u5F00 dist/wechat \u9884\u89C8\u9A8C\u8BC1\u3002"));
|
|
1194
|
+
return false;
|
|
1195
|
+
}
|
|
1196
|
+
const ctx = resolveProject();
|
|
1197
|
+
const pw = resolvePlaywright(ctx.root);
|
|
1198
|
+
if (!pw) {
|
|
1199
|
+
console.log(pc6.red("\u2717 pf verify \u9700\u8981 Playwright(\u53EF\u9009\u4F9D\u8D56,\u672A\u5B89\u88C5)\u3002"));
|
|
1200
|
+
console.log(pc6.yellow(" \u5B89\u88C5:") + pc6.cyan(" npm i -D playwright"));
|
|
1201
|
+
console.log(pc6.gray(" \u6D4F\u89C8\u5668\u4F18\u5148\u7528\u7CFB\u7EDF Chrome(channel:chrome),\u901A\u5E38\u65E0\u9700 `npx playwright install`\u3002"));
|
|
1202
|
+
return false;
|
|
1203
|
+
}
|
|
1204
|
+
if (!opts.noBuild) {
|
|
1205
|
+
console.log(pc6.cyan(pc6.bold(`\u25B6 [verify] \u5148\u6784\u5EFA ${platform}`)));
|
|
1206
|
+
const built = await runBuild(platform);
|
|
1207
|
+
if (!built) {
|
|
1208
|
+
console.log(pc6.red("\u2717 [verify] \u6784\u5EFA\u5931\u8D25,\u7EC8\u6B62\u9A8C\u8BC1"));
|
|
1209
|
+
return false;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
const distDir = resolve(ctx.root, "dist", platform);
|
|
1213
|
+
if (!existsSync(join(distDir, "index.html"))) {
|
|
1214
|
+
console.log(pc6.red(`\u2717 [verify] \u627E\u4E0D\u5230 ${join(distDir, "index.html")}(\u5148 build \u6216\u53BB\u6389 --no-build)`));
|
|
1215
|
+
return false;
|
|
1216
|
+
}
|
|
1217
|
+
const viewport = await readViewport(ctx);
|
|
1218
|
+
const { server, port } = await serveDist(distDir);
|
|
1219
|
+
const url = `http://127.0.0.1:${port}/`;
|
|
1220
|
+
console.log(pc6.cyan(pc6.bold(`\u25B6 [verify] \u65E0\u5934\u6D4F\u89C8\u5668\u6253\u5F00 ${platform} \u4EA7\u7269`)));
|
|
1221
|
+
const launchArgs = ["--no-sandbox", "--disable-webgl", "--disable-webgl2"];
|
|
1222
|
+
let browser;
|
|
1223
|
+
try {
|
|
1224
|
+
browser = await pw.chromium.launch({ channel: "chrome", headless: true, args: launchArgs });
|
|
1225
|
+
} catch {
|
|
1226
|
+
try {
|
|
1227
|
+
browser = await pw.chromium.launch({ headless: true, args: launchArgs });
|
|
1228
|
+
} catch (e) {
|
|
1229
|
+
server.close();
|
|
1230
|
+
console.log(pc6.red(`\u2717 [verify] \u6D4F\u89C8\u5668\u542F\u52A8\u5931\u8D25:${e.message}`));
|
|
1231
|
+
console.log(pc6.yellow(" \u88C5\u7CFB\u7EDF Chrome,\u6216\u8FD0\u884C `npx playwright install chromium`\u3002"));
|
|
1232
|
+
return false;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
const errors = [];
|
|
1236
|
+
let rendered = false;
|
|
1237
|
+
let distinctColors = 0;
|
|
1238
|
+
let canvasInfo = null;
|
|
1239
|
+
try {
|
|
1240
|
+
const page = await browser.newPage({ viewport });
|
|
1241
|
+
page.on("pageerror", (e) => errors.push("PAGEERROR: " + e.message));
|
|
1242
|
+
page.on("console", (m) => {
|
|
1243
|
+
if (m.type() === "error" && !/favicon/i.test(m.text())) errors.push("CONSOLE: " + m.text());
|
|
1244
|
+
});
|
|
1245
|
+
await page.goto(url, { waitUntil: "load", timeout: 3e4 });
|
|
1246
|
+
for (let i = 0; i < 20; i++) {
|
|
1247
|
+
await page.waitForTimeout(1e3);
|
|
1248
|
+
const stat = await page.evaluate(() => {
|
|
1249
|
+
const c = document.querySelector("canvas");
|
|
1250
|
+
if (!c) return { ok: false, distinct: 0, w: 0, h: 0 };
|
|
1251
|
+
const cx = c.getContext("2d");
|
|
1252
|
+
if (!cx) return { ok: false, distinct: 0, w: c.width, h: c.height };
|
|
1253
|
+
const w = c.width;
|
|
1254
|
+
const h = c.height;
|
|
1255
|
+
const data = cx.getImageData(0, 0, w, h).data;
|
|
1256
|
+
const colors = /* @__PURE__ */ new Set();
|
|
1257
|
+
const total = w * h;
|
|
1258
|
+
const step = Math.max(1, Math.floor(total / 3e3));
|
|
1259
|
+
for (let k = 0; k < total && colors.size < 40; k += step) {
|
|
1260
|
+
const o = k * 4;
|
|
1261
|
+
colors.add(`${data[o]},${data[o + 1]},${data[o + 2]}`);
|
|
1262
|
+
}
|
|
1263
|
+
return { ok: true, distinct: colors.size, w, h };
|
|
1264
|
+
}).catch(() => ({ ok: false, distinct: 0, w: 0, h: 0 }));
|
|
1265
|
+
canvasInfo = stat.w ? { w: stat.w, h: stat.h } : canvasInfo;
|
|
1266
|
+
distinctColors = stat.distinct;
|
|
1267
|
+
if (stat.ok && stat.distinct > 3) {
|
|
1268
|
+
rendered = true;
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
const durl = await page.evaluate(() => {
|
|
1273
|
+
const c = document.querySelector("canvas");
|
|
1274
|
+
return c ? c.toDataURL("image/png") : "";
|
|
1275
|
+
}).catch(() => "");
|
|
1276
|
+
if (durl) {
|
|
1277
|
+
const outDir = join(ctx.root, ".pf-verify");
|
|
1278
|
+
mkdirSync(outDir, { recursive: true });
|
|
1279
|
+
const shot = join(outDir, `${platform}.png`);
|
|
1280
|
+
writeFileSync(shot, Buffer.from(durl.split(",")[1], "base64"));
|
|
1281
|
+
console.log(pc6.gray(` \u622A\u56FE:${shot}`));
|
|
1282
|
+
}
|
|
1283
|
+
} catch (e) {
|
|
1284
|
+
errors.push("VERIFY: " + e.message);
|
|
1285
|
+
} finally {
|
|
1286
|
+
await browser.close();
|
|
1287
|
+
server.close();
|
|
1288
|
+
}
|
|
1289
|
+
const ok = errors.length === 0 && rendered;
|
|
1290
|
+
console.log("");
|
|
1291
|
+
console.log(pc6.bold("\u25B6 [verify] \u7ED3\u679C"));
|
|
1292
|
+
console.log(` canvas:${canvasInfo ? `${canvasInfo.w}\xD7${canvasInfo.h}` : "\u65E0"};\u753B\u9762\u989C\u8272\u6570:${distinctColors}(>3 \u89C6\u4E3A\u5DF2\u6E32\u67D3)`);
|
|
1293
|
+
if (errors.length) {
|
|
1294
|
+
console.log(pc6.red(` \u63A7\u5236\u53F0/\u9875\u9762\u9519\u8BEF(${errors.length}):`));
|
|
1295
|
+
errors.slice(0, 12).forEach((e) => console.log(pc6.red(" " + e)));
|
|
1296
|
+
} else {
|
|
1297
|
+
console.log(pc6.green(" \u65E0\u63A7\u5236\u53F0/\u9875\u9762\u9519\u8BEF"));
|
|
1298
|
+
}
|
|
1299
|
+
if (ok) {
|
|
1300
|
+
console.log(pc6.green(pc6.bold(`
|
|
1301
|
+
\u2713 [verify] ${platform} \u5B9E\u8DD1\u901A\u8FC7(\u6E32\u67D3\u6B63\u5E38\u3001\u65E0\u8FD0\u884C\u671F\u9519\u8BEF)`)));
|
|
1302
|
+
} else {
|
|
1303
|
+
console.log(pc6.red(pc6.bold(`
|
|
1304
|
+
\u2717 [verify] ${platform} \u672A\u901A\u8FC7:${!rendered ? "\u753B\u9762\u672A\u6E32\u67D3\u51FA\u5185\u5BB9(\u7591\u4F3C\u5D29\u6E83/\u9ED1\u5C4F)" : "\u5B58\u5728\u8FD0\u884C\u671F\u9519\u8BEF"}`)));
|
|
1305
|
+
}
|
|
1306
|
+
return ok;
|
|
1307
|
+
}
|
|
1308
|
+
function invalid(target) {
|
|
1309
|
+
console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
|
|
1118
1310
|
process.exit(1);
|
|
1119
1311
|
}
|
|
1120
1312
|
function spawnCap(projectRoot, args) {
|
|
1121
1313
|
const npx = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
1122
|
-
console.log(
|
|
1314
|
+
console.log(pc6.gray(` $ ${npx} cap ${args.join(" ")}`));
|
|
1123
1315
|
const res = spawnSync(npx, ["cap", ...args], {
|
|
1124
1316
|
cwd: projectRoot,
|
|
1125
1317
|
stdio: "inherit",
|
|
@@ -1127,9 +1319,9 @@ function spawnCap(projectRoot, args) {
|
|
|
1127
1319
|
shell: process.platform === "win32"
|
|
1128
1320
|
});
|
|
1129
1321
|
if (res.error) {
|
|
1130
|
-
console.log(
|
|
1322
|
+
console.log(pc6.red(` \u2717 \u6267\u884C\u5931\u8D25:${res.error.message}`));
|
|
1131
1323
|
console.log(
|
|
1132
|
-
|
|
1324
|
+
pc6.yellow(
|
|
1133
1325
|
" \u8BF7\u786E\u8BA4\u5DF2\u5B89\u88C5 Capacitor CLI:npm i -D @capacitor/cli @capacitor/android @capacitor/ios"
|
|
1134
1326
|
)
|
|
1135
1327
|
);
|
|
@@ -1140,11 +1332,11 @@ function spawnCap(projectRoot, args) {
|
|
|
1140
1332
|
function runCap(action, platform) {
|
|
1141
1333
|
const ctx = resolveProject();
|
|
1142
1334
|
if (action === "sync") {
|
|
1143
|
-
console.log(
|
|
1335
|
+
console.log(pc6.cyan(pc6.bold("\u25B6 Capacitor sync")));
|
|
1144
1336
|
const distDir = resolve(ctx.root, "dist", "capacitor");
|
|
1145
1337
|
if (!fse4.existsSync(distDir)) {
|
|
1146
|
-
console.log(
|
|
1147
|
-
console.log(
|
|
1338
|
+
console.log(pc6.red("\u2717 dist/capacitor \u4E0D\u5B58\u5728"));
|
|
1339
|
+
console.log(pc6.yellow(" \u8BF7\u5148\u6784\u5EFA:pf build capacitor"));
|
|
1148
1340
|
return false;
|
|
1149
1341
|
}
|
|
1150
1342
|
const args = platform ? ["sync", platform] : ["sync"];
|
|
@@ -1152,13 +1344,13 @@ function runCap(action, platform) {
|
|
|
1152
1344
|
}
|
|
1153
1345
|
if (action === "open") {
|
|
1154
1346
|
if (platform !== "android" && platform !== "ios") {
|
|
1155
|
-
console.log(
|
|
1347
|
+
console.log(pc6.red("\u2717 open \u9700\u6307\u5B9A\u5E73\u53F0:pf cap open <android|ios>"));
|
|
1156
1348
|
return false;
|
|
1157
1349
|
}
|
|
1158
|
-
console.log(
|
|
1350
|
+
console.log(pc6.cyan(pc6.bold(`\u25B6 Capacitor open ${platform}`)));
|
|
1159
1351
|
return capExec(ctx.root, ["open", platform]);
|
|
1160
1352
|
}
|
|
1161
|
-
console.log(
|
|
1353
|
+
console.log(pc6.red("\u7528\u6CD5:"));
|
|
1162
1354
|
console.log(" pf cap sync [android|ios]");
|
|
1163
1355
|
console.log(" pf cap open <android|ios>");
|
|
1164
1356
|
return false;
|
|
@@ -1197,35 +1389,43 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1197
1389
|
process.exitCode = ok ? 0 : 1;
|
|
1198
1390
|
return;
|
|
1199
1391
|
}
|
|
1392
|
+
case "verify": {
|
|
1393
|
+
const noBuild = rest.includes("--no-build");
|
|
1394
|
+
const platform = rest.find((a) => !a.startsWith("-"));
|
|
1395
|
+
const ok = await runVerify(platform, { noBuild });
|
|
1396
|
+
process.exitCode = ok ? 0 : 1;
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1200
1399
|
case "cap": {
|
|
1201
1400
|
const ok = runCap(rest[0], rest[1]);
|
|
1202
1401
|
process.exitCode = ok ? 0 : 1;
|
|
1203
1402
|
return;
|
|
1204
1403
|
}
|
|
1205
1404
|
default: {
|
|
1206
|
-
console.log(
|
|
1207
|
-
console.log(
|
|
1405
|
+
console.log(pc6.yellow(`[pf] \u672A\u77E5\u547D\u4EE4 "${command}"\u3002`));
|
|
1406
|
+
console.log(pc6.dim("\u8FD0\u884C `pf help` \u67E5\u770B\u53EF\u7528\u547D\u4EE4\u3002"));
|
|
1208
1407
|
process.exitCode = 1;
|
|
1209
1408
|
}
|
|
1210
1409
|
}
|
|
1211
1410
|
} catch (e) {
|
|
1212
|
-
console.log(
|
|
1213
|
-
if (e.stack) console.log(
|
|
1411
|
+
console.log(pc6.red(`[pf] \u6267\u884C "${command}" \u51FA\u9519:${e.message}`));
|
|
1412
|
+
if (e.stack) console.log(pc6.gray(e.stack ?? ""));
|
|
1214
1413
|
process.exitCode = 1;
|
|
1215
1414
|
}
|
|
1216
1415
|
}
|
|
1217
1416
|
function printHelp() {
|
|
1218
|
-
console.log(
|
|
1219
|
-
console.log(
|
|
1417
|
+
console.log(pc6.bold("@maoyugames/phaser-framework CLI (pf)"));
|
|
1418
|
+
console.log(pc6.dim("\u591A\u5E73\u53F0 Phaser \u6846\u67B6\u6784\u5EFA\u5DE5\u5177\u3002"));
|
|
1220
1419
|
console.log("");
|
|
1221
1420
|
console.log("\u547D\u4EE4:");
|
|
1222
|
-
console.log(` ${
|
|
1223
|
-
console.log(` ${
|
|
1224
|
-
console.log(` ${
|
|
1225
|
-
console.log(` ${
|
|
1226
|
-
console.log(` ${
|
|
1421
|
+
console.log(` ${pc6.cyan("pf dev [platform]")} \u542F\u52A8\u67D0\u5E73\u53F0 dev server(\u9ED8\u8BA4 web)`);
|
|
1422
|
+
console.log(` ${pc6.cyan("pf build <platform|all>")} \u6784\u5EFA\u67D0\u5E73\u53F0/\u5168\u90E8\u5E73\u53F0`);
|
|
1423
|
+
console.log(` ${pc6.cyan("pf size-check [platform]")} \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5`);
|
|
1424
|
+
console.log(` ${pc6.cyan("pf verify-isolation [platform]")} SDK \u9694\u79BB\u6821\u9A8C`);
|
|
1425
|
+
console.log(` ${pc6.cyan("pf verify [platform] [--no-build]")} \u5B9E\u8DD1\u5192\u70DF\u9A8C\u8BC1(Playwright \u65E0\u5934:\u6E32\u67D3+\u65E0\u8FD0\u884C\u671F\u9519\u8BEF)`);
|
|
1426
|
+
console.log(` ${pc6.cyan("pf cap <sync|open> [android|ios]")} Capacitor \u539F\u751F\u5DE5\u7A0B\u64CD\u4F5C`);
|
|
1227
1427
|
console.log("");
|
|
1228
|
-
console.log(
|
|
1428
|
+
console.log(pc6.dim("\u5E73\u53F0:web / tiktok / wechat / facebook / capacitor"));
|
|
1229
1429
|
}
|
|
1230
1430
|
void main();
|
|
1231
1431
|
|
package/dist/index.js
CHANGED
|
@@ -2091,6 +2091,15 @@ var AccountService = class {
|
|
|
2091
2091
|
}
|
|
2092
2092
|
};
|
|
2093
2093
|
|
|
2094
|
+
// src/scene/active-scene.ts
|
|
2095
|
+
var _active = null;
|
|
2096
|
+
function setActiveScene(scene) {
|
|
2097
|
+
_active = scene;
|
|
2098
|
+
}
|
|
2099
|
+
function getActiveScene() {
|
|
2100
|
+
return _active;
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2094
2103
|
// src/services/SceneManager.ts
|
|
2095
2104
|
var SceneManager = class {
|
|
2096
2105
|
constructor() {
|
|
@@ -2108,19 +2117,18 @@ var SceneManager = class {
|
|
|
2108
2117
|
return;
|
|
2109
2118
|
}
|
|
2110
2119
|
const sceneData = asSceneData(data);
|
|
2111
|
-
const
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2120
|
+
const active = getActiveScene();
|
|
2121
|
+
if (active && active.scene && typeof active.scene.start === "function") {
|
|
2122
|
+
for (const scene of manager.getScenes(true)) {
|
|
2123
|
+
const sceneKey = scene.scene.key;
|
|
2124
|
+
if (sceneKey !== key && scene !== active) {
|
|
2125
|
+
manager.stop(sceneKey);
|
|
2126
|
+
}
|
|
2117
2127
|
}
|
|
2128
|
+
active.scene.start(key, sceneData);
|
|
2129
|
+
return;
|
|
2118
2130
|
}
|
|
2119
|
-
|
|
2120
|
-
vehicle.scene.start(key, sceneData);
|
|
2121
|
-
} else {
|
|
2122
|
-
manager.start(key, sceneData);
|
|
2123
|
-
}
|
|
2131
|
+
manager.start(key, sceneData);
|
|
2124
2132
|
}
|
|
2125
2133
|
push(key, data) {
|
|
2126
2134
|
const manager = this.game?.scene;
|
|
@@ -2868,9 +2876,6 @@ var PanelManager = class {
|
|
|
2868
2876
|
return actives[actives.length - 1];
|
|
2869
2877
|
}
|
|
2870
2878
|
};
|
|
2871
|
-
|
|
2872
|
-
// src/bootstrap.ts
|
|
2873
|
-
var _game = null;
|
|
2874
2879
|
async function startGame(opts) {
|
|
2875
2880
|
const { platform, config, scenes } = opts;
|
|
2876
2881
|
PlatformContext.set(platform);
|
|
@@ -2932,31 +2937,34 @@ async function startGame(opts) {
|
|
|
2932
2937
|
await opts.setup(App);
|
|
2933
2938
|
}
|
|
2934
2939
|
log.info(`[bootstrap] \u5E73\u53F0 ${platform.info.name} \u521D\u59CB\u5316\u5B8C\u6210,\u542F\u52A8 Phaser`);
|
|
2935
|
-
|
|
2936
|
-
audio.bindGame(
|
|
2937
|
-
sceneManager.bindGame(
|
|
2938
|
-
panelManager.bindGame(
|
|
2940
|
+
const game = createPhaserGameInstance(config, scenes);
|
|
2941
|
+
audio.bindGame(game);
|
|
2942
|
+
sceneManager.bindGame(game);
|
|
2943
|
+
panelManager.bindGame(game);
|
|
2944
|
+
await waitForGameReady(game);
|
|
2939
2945
|
await App.modules.initAll();
|
|
2940
2946
|
log.info("[bootstrap] \u6E38\u620F\u542F\u52A8\u5B8C\u6210");
|
|
2941
2947
|
}
|
|
2942
|
-
function
|
|
2948
|
+
function createPhaserGameInstance(config, scenes) {
|
|
2949
|
+
const gameConfig = {
|
|
2950
|
+
type: Phaser4.AUTO,
|
|
2951
|
+
// 透明背景占位;业务场景自行绘制背景
|
|
2952
|
+
backgroundColor: "#1f2937",
|
|
2953
|
+
scale: {
|
|
2954
|
+
// FIT:按设计分辨率等比缩放铺满容器(保持比例,留黑边);CENTER_BOTH:居中
|
|
2955
|
+
mode: Phaser4.Scale.FIT,
|
|
2956
|
+
autoCenter: Phaser4.Scale.CENTER_BOTH,
|
|
2957
|
+
width: config.designWidth,
|
|
2958
|
+
height: config.designHeight
|
|
2959
|
+
},
|
|
2960
|
+
scene: scenes
|
|
2961
|
+
// 微信等无 DOM 平台由 weapp-adapter 提供 canvas;有 DOM 平台 Phaser 自动建 canvas
|
|
2962
|
+
};
|
|
2963
|
+
return new Phaser4.Game(gameConfig);
|
|
2964
|
+
}
|
|
2965
|
+
function waitForGameReady(game) {
|
|
2943
2966
|
return new Promise((resolve) => {
|
|
2944
|
-
|
|
2945
|
-
type: Phaser4.AUTO,
|
|
2946
|
-
// 透明背景占位;业务场景自行绘制背景
|
|
2947
|
-
backgroundColor: "#1f2937",
|
|
2948
|
-
scale: {
|
|
2949
|
-
// FIT:按设计分辨率等比缩放铺满容器(保持比例,留黑边);CENTER_BOTH:居中
|
|
2950
|
-
mode: Phaser4.Scale.FIT,
|
|
2951
|
-
autoCenter: Phaser4.Scale.CENTER_BOTH,
|
|
2952
|
-
width: config.designWidth,
|
|
2953
|
-
height: config.designHeight
|
|
2954
|
-
},
|
|
2955
|
-
scene: scenes
|
|
2956
|
-
// 微信等无 DOM 平台由 weapp-adapter 提供 canvas;有 DOM 平台 Phaser 自动建 canvas
|
|
2957
|
-
};
|
|
2958
|
-
const game = new Phaser4.Game(gameConfig);
|
|
2959
|
-
game.events.once(Phaser4.Core.Events.READY, () => resolve(game));
|
|
2967
|
+
game.events.once(Phaser4.Core.Events.READY, () => resolve());
|
|
2960
2968
|
});
|
|
2961
2969
|
}
|
|
2962
2970
|
|
|
@@ -3094,6 +3102,7 @@ var BaseScene = class extends Phaser4.Scene {
|
|
|
3094
3102
|
* 注意:业务场景若覆写 init(data),请调用 super.init(data) 以保留自动清理(this.bind / this.scheduler)。
|
|
3095
3103
|
*/
|
|
3096
3104
|
init(_data) {
|
|
3105
|
+
setActiveScene(this);
|
|
3097
3106
|
this.armCleanupHooks();
|
|
3098
3107
|
}
|
|
3099
3108
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maoyugames/phaser-framework",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "多平台 Phaser 游戏框架:业务/底层分离,HTTP/WebSocket/KCP,Web/TikTok/微信/Facebook/App 隔离打包",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,11 +53,15 @@
|
|
|
53
53
|
"phaser": "^3.60.0 || ^3.80.0 || ^3.90.0",
|
|
54
54
|
"vite": "^5.0.0",
|
|
55
55
|
"typescript": "^5.0.0",
|
|
56
|
-
"terser": "^5.0.0"
|
|
56
|
+
"terser": "^5.0.0",
|
|
57
|
+
"playwright": "^1.40.0"
|
|
57
58
|
},
|
|
58
59
|
"peerDependenciesMeta": {
|
|
59
60
|
"terser": {
|
|
60
61
|
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"playwright": {
|
|
64
|
+
"optional": true
|
|
61
65
|
}
|
|
62
66
|
},
|
|
63
67
|
"dependencies": {
|