@playcraft/devkit 1.0.31-beta.11 → 1.0.31-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/cli/bin/playable-scripts.js +6 -53
  2. package/cli/commands/build.js +32 -241
  3. package/cli/commands/builds.js +2 -13
  4. package/cli/commands/dev.js +1 -22
  5. package/cli/commands/pack.js +40 -320
  6. package/cli/commands/vite-dev.js +1 -7
  7. package/core/artifacts/emit-fonts.test.js +1 -0
  8. package/core/artifacts/emit.js +4 -98
  9. package/core/artifacts/fflate.js +1 -31
  10. package/core/artifacts/zip.js +1 -39
  11. package/core/batch-build.js +147 -1261
  12. package/core/constants.js +2 -20
  13. package/core/cos-uploader.js +23 -289
  14. package/core/engines/cocos/adapter-vfs-path.test.js +1 -0
  15. package/core/engines/cocos/clean-cache.js +5 -179
  16. package/core/engines/cocos/clean-cache.test.js +1 -75
  17. package/core/engines/cocos/cli-build.js +2 -116
  18. package/core/engines/cocos/cli.js +11 -38
  19. package/core/engines/cocos/constants.js +1 -21
  20. package/core/engines/cocos/creator-cli.js +1 -108
  21. package/core/engines/cocos/dev-server.js +4 -412
  22. package/core/engines/cocos/fs.js +1 -105
  23. package/core/engines/cocos/injects/3x/init.js +19 -438
  24. package/core/engines/cocos/injects/3x/main.js +2 -52
  25. package/core/engines/cocos/injects/libs/pako.js +1 -2
  26. package/core/engines/cocos/mcp-refresh.js +2 -76
  27. package/core/engines/cocos/merge-inline.test.js +1 -0
  28. package/core/engines/cocos/merge.js +9 -148
  29. package/core/engines/cocos/omit-playable-weight.js +10 -0
  30. package/core/engines/cocos/omit-playable-weight.test.js +2 -0
  31. package/core/engines/cocos/pack.js +1 -187
  32. package/core/engines/cocos/preview-cache.js +2 -48
  33. package/core/engines/cocos/preview-cache.test.js +1 -32
  34. package/core/engines/cocos/preview-concat.js +6 -189
  35. package/core/engines/cocos/preview-concat.test.js +1 -73
  36. package/core/engines/cocos/preview-json-hook.js +1 -200
  37. package/core/engines/cocos/preview-json-pack.js +3 -376
  38. package/core/engines/cocos/preview-json-pack.test.js +2 -226
  39. package/core/engines/cocos/preview-proxy.js +1 -132
  40. package/core/engines/cocos/rebundle-preview.js +2 -54
  41. package/core/engines/cocos/strip-social-share.js +3 -115
  42. package/core/engines/cocos/theme-assets.js +2 -161
  43. package/core/engines/cocos/theme-levels.js +1 -0
  44. package/core/engines/cocos/writable-cli.js +2 -248
  45. package/core/engines/cocos/writable-cli.test.js +1 -112
  46. package/core/engines/web/index.js +1 -20
  47. package/core/engines/web/vite.dev.js +17 -322
  48. package/core/engines/web/webpack.build.js +37 -522
  49. package/core/engines/web/webpack.common.js +11 -177
  50. package/core/engines/web/webpack.dev.js +6 -88
  51. package/core/index.js +7 -101
  52. package/core/injectors/apply.js +1 -94
  53. package/core/injectors/check-channel-matrix.js +2 -130
  54. package/core/injectors/spec.js +10 -217
  55. package/core/loaders/gltf-loader.js +28 -74
  56. package/core/options.js +16 -353
  57. package/core/plugins/AdikteevInjectorPlugin.js +4 -26
  58. package/core/plugins/BigoAdsInjectorPlugin.js +4 -21
  59. package/core/plugins/DAPIInjectorPlugin.js +2 -25
  60. package/core/plugins/DebuggerInjectionPlugin.js +3 -31
  61. package/core/plugins/ExitAPIInjectorPlugin.js +3 -56
  62. package/core/plugins/FflateCompressionPlugin.js +160 -307
  63. package/core/plugins/FflateCompressionPlugin.test.js +13 -0
  64. package/core/plugins/FontInjectionWebpackPlugin.js +4 -46
  65. package/core/plugins/LiftoffInjectorPlugin.js +4 -26
  66. package/core/plugins/MRAIDInjectorPlugin.js +2 -24
  67. package/core/plugins/MintegralInjectorPlugin.js +2 -25
  68. package/core/plugins/PangleInjectorPlugin.js +2 -24
  69. package/core/plugins/PlaycraftOrientationInjectorPlugin.js +3 -29
  70. package/core/plugins/SnapchatInjectorPlugin.js +4 -26
  71. package/core/plugins/SocialMediaInjectorPlugin.js +7 -119
  72. package/core/plugins/TikTokInjectorPlugin.js +2 -24
  73. package/core/plugins/UnityInjectorPlugin.js +8 -37
  74. package/core/plugins/ZipPlugin.js +20 -154
  75. package/core/plugins/socialMediaVitePlugin.js +2 -108
  76. package/core/utils/buildDefines.js +2 -30
  77. package/core/utils/buildTemplateString.js +5 -39
  78. package/core/utils/date.js +1 -16
  79. package/core/utils/fontRegistry.js +13 -81
  80. package/core/utils/fontResolver.js +37 -335
  81. package/core/utils/generateAdikteevHtmlWebpackPluginConfig.js +8 -42
  82. package/core/utils/generateBigabidHtmlWebpackPluginConfig.js +3 -30
  83. package/core/utils/generateInMobiHtmlWebpackPluginConfig.js +7 -43
  84. package/core/utils/getPlaycraftOrientationSuffix.js +2 -9
  85. package/core/utils/injectSDKPlugins.js +13 -68
  86. package/core/utils/logOptions.js +5 -46
  87. package/core/utils/mergeOptions.js +2 -21
  88. package/core/utils/obfuscateLevels.js +14 -0
  89. package/core/utils/obfuscateLevels.test.js +10 -0
  90. package/core/utils/parseArgvOptions.js +5 -125
  91. package/core/utils/resolveChannelFold2Zip.js +3 -15
  92. package/core/utils/validateThemeData.js +26 -227
  93. package/core/validators/pre-build-checker.js +25 -287
  94. package/core/validators/tracking-validator.js +40 -441
  95. package/core/validators/tracking-validator.test.js +2 -84
  96. package/core/vite.dev.js +1 -1
  97. package/core/webpack.build.js +1 -1
  98. package/core/webpack.common.js +1 -1
  99. package/core/webpack.dev.js +1 -1
  100. package/package.json +2 -3
  101. package/README.md +0 -262
@@ -1,118 +1,4 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { spawnCocosSync, needsXvfb } = require('./cli.js');
6
- const { resolveCreatorOutputDir } = require('./creator-cli.js');
7
- const { stripAdsdkCjsImport } = require('./strip-social-share.js');
8
- const { prepareWritableCocosCli } = require('./writable-cli.js');
9
- const { cleanCocosProjectCaches, ensureWritableCocosWorkdirs, shouldCleanCocosCache } = require('./clean-cache.js');
10
-
11
- function shouldSkipEngineBuild(buildOptions = {}) {
12
- const cocos = buildOptions.cocos || {};
13
- return Boolean(
14
- buildOptions.skipEngineBuild ||
15
- cocos.skipEngineBuild ||
16
- process.env.PLAYABLE_SKIP_ENGINE_BUILD === '1'
17
- );
18
- }
19
-
20
- function resolveWebMobileDest(projectRoot, buildOptions = {}) {
21
- const cocos = buildOptions.cocos || {};
22
- const fromConfig = resolveCreatorOutputDir(projectRoot, cocos.buildConfig || 'build-configs/web-mobile.json');
23
- const explicit = cocos.webMobileDir ? path.resolve(projectRoot, cocos.webMobileDir) : null;
24
- if (shouldSkipEngineBuild(buildOptions)) {
25
- return explicit || fromConfig || path.resolve(projectRoot, 'dist/web-mobile');
26
- }
27
- return fromConfig || explicit || path.resolve(projectRoot, 'dist/web-mobile');
28
- }
29
-
30
- function logStrip(result) {
31
- if (result.skipped && result.reason === 'missing') {
32
- console.warn('[cocos] adsdk CJS missing, skip social-share strip');
33
- return;
34
- }
35
- if (result.skipped && result.reason === 'already') {
36
- console.log('[cocos] social-share import() already stripped');
37
- return;
38
- }
39
- if (result.skipped) {
40
- console.warn('[cocos] social-share import() not found in CJS');
41
- return;
42
- }
43
- console.log('[cocos] stripped social-share import() from adsdk CJS');
44
- }
45
-
46
- /**
1
+ "use strict";const fs=require("fs");const path=require("path");const{spawnCocosSync,needsXvfb}=require("./cli.js");const{resolveCreatorOutputDir}=require("./creator-cli.js");const{stripAdsdkCjsImport}=require("./strip-social-share.js");const{prepareWritableCocosCli}=require("./writable-cli.js");const{cleanCocosProjectCaches,ensureWritableCocosWorkdirs,shouldCleanCocosCache}=require("./clean-cache.js");function shouldSkipEngineBuild(buildOptions={}){const cocos=buildOptions.cocos||{};return Boolean(buildOptions.skipEngineBuild||cocos.skipEngineBuild||process.env.PLAYABLE_SKIP_ENGINE_BUILD==="1")}function resolveWebMobileDest(projectRoot,buildOptions={}){const cocos=buildOptions.cocos||{};const fromConfig=resolveCreatorOutputDir(projectRoot,cocos.buildConfig||"build-configs/web-mobile.json");const explicit=cocos.webMobileDir?path.resolve(projectRoot,cocos.webMobileDir):null;if(shouldSkipEngineBuild(buildOptions)){return explicit||fromConfig||path.resolve(projectRoot,"dist/web-mobile")}return fromConfig||explicit||path.resolve(projectRoot,"dist/web-mobile")}function logStrip(result){if(result.skipped&&result.reason==="missing"){console.warn("[cocos] adsdk CJS missing, skip social-share strip");return}if(result.skipped&&result.reason==="already"){console.log("[cocos] social-share import() already stripped");return}if(result.skipped){console.warn("[cocos] social-share import() not found in CJS");return}console.log("[cocos] stripped social-share import() from adsdk CJS")}/**
47
2
  * 用官方 cocos CLI 打 web-mobile(不再走 Creator 编辑器)。
48
3
  * Linux 上自动套 xvfb-run -a(shader 编译需要虚拟显示)。
49
- */
50
- function runCocosEngineBuild(projectRoot, buildOptions = {}) {
51
- logStrip(stripAdsdkCjsImport(projectRoot));
52
-
53
- const dest = resolveWebMobileDest(projectRoot, buildOptions);
54
- if (shouldSkipEngineBuild(buildOptions)) {
55
- if (!fs.existsSync(dest)) {
56
- throw new Error(`[cocos] skipEngineBuild but missing ${path.relative(projectRoot, dest)}`);
57
- }
58
- console.log(`[cocos] skip engine build, using ${path.relative(projectRoot, dest)}`);
59
- return dest;
60
- }
61
-
62
- if (shouldCleanCocosCache(buildOptions)) {
63
- const removed = cleanCocosProjectCaches(projectRoot);
64
- console.log(`[cocos] cleaned project caches: ${removed.join(', ') || '(none)'}`);
65
- }
66
- ensureWritableCocosWorkdirs(projectRoot);
67
-
68
- const cocos = buildOptions.cocos || {};
69
- const configRel = cocos.buildConfig || 'build-configs/web-mobile.json';
70
- const configPath = path.resolve(projectRoot, configRel);
71
- if (!fs.existsSync(configPath)) {
72
- throw new Error(`[cocos] missing build config: ${configRel}`);
73
- }
74
-
75
- const args = [
76
- '--no-interactive',
77
- 'build',
78
- '--project',
79
- projectRoot,
80
- '--platform',
81
- 'web-mobile',
82
- '--build-config',
83
- configPath,
84
- ];
85
-
86
- const prepared = prepareWritableCocosCli(projectRoot);
87
- const env = { ...process.env, ...prepared.env };
88
-
89
- if (needsXvfb()) {
90
- console.log('[cocos] linux, wrapping xvfb-run -a');
91
- }
92
- console.log(`[cocos] build web-mobile ← ${configRel}`);
93
-
94
- const result = spawnCocosSync(args, {
95
- cwd: projectRoot,
96
- stdio: 'inherit',
97
- env,
98
- });
99
-
100
- if (result.error) {
101
- throw result.error;
102
- }
103
- if (result.status !== 0) {
104
- throw new Error(`[cocos] build failed, exit ${result.status}`);
105
- }
106
-
107
- console.log(`[cocos] web-mobile ready at ${path.relative(projectRoot, dest)}`);
108
- return dest;
109
- }
110
-
111
- module.exports = {
112
- runCocosEngineBuild,
113
- resolveWebMobileDest,
114
- shouldSkipEngineBuild,
115
- cleanCocosProjectCaches,
116
- ensureWritableCocosWorkdirs,
117
- shouldCleanCocosCache,
118
- };
4
+ */function runCocosEngineBuild(projectRoot,buildOptions={}){logStrip(stripAdsdkCjsImport(projectRoot));const dest=resolveWebMobileDest(projectRoot,buildOptions);if(shouldSkipEngineBuild(buildOptions)){if(!fs.existsSync(dest)){throw new Error(`[cocos] skipEngineBuild but missing ${path.relative(projectRoot,dest)}`)}console.log(`[cocos] skip engine build, using ${path.relative(projectRoot,dest)}`);return dest}if(shouldCleanCocosCache(buildOptions)){const removed=cleanCocosProjectCaches(projectRoot);console.log(`[cocos] cleaned project caches: ${removed.join(", ")||"(none)"}`)}ensureWritableCocosWorkdirs(projectRoot);const cocos=buildOptions.cocos||{};const configRel=cocos.buildConfig||"build-configs/web-mobile.json";const configPath=path.resolve(projectRoot,configRel);if(!fs.existsSync(configPath)){throw new Error(`[cocos] missing build config: ${configRel}`)}const args=["--no-interactive","build","--project",projectRoot,"--platform","web-mobile","--build-config",configPath];const prepared=prepareWritableCocosCli(projectRoot);const env={...process.env,...prepared.env};if(needsXvfb()){console.log("[cocos] linux, wrapping xvfb-run -a")}console.log(`[cocos] build web-mobile ← ${configRel}`);const result=spawnCocosSync(args,{cwd:projectRoot,stdio:"inherit",env});if(result.error){throw result.error}if(result.status!==0){throw new Error(`[cocos] build failed, exit ${result.status}`)}console.log(`[cocos] web-mobile ready at ${path.relative(projectRoot,dest)}`);return dest}module.exports={runCocosEngineBuild,resolveWebMobileDest,shouldSkipEngineBuild,cleanCocosProjectCaches,ensureWritableCocosWorkdirs,shouldCleanCocosCache};
@@ -1,38 +1,11 @@
1
- 'use strict';
2
-
3
- const { spawn, spawnSync } = require('child_process');
4
-
5
- function resolveCocosBin(env = process.env) {
6
- return env.COCOS_CLI || 'cocos';
7
- }
8
-
9
- function needsXvfb() {
10
- return process.platform === 'linux';
11
- }
12
-
13
- function cocosCommand(args, env = process.env) {
14
- const bin = resolveCocosBin(env);
15
- if (needsXvfb()) {
16
- return { cmd: 'xvfb-run', args: ['-a', bin, ...args] };
17
- }
18
- return { cmd: bin, args };
19
- }
20
-
21
- function spawnCocos(args, options = {}) {
22
- const env = options.env || process.env;
23
- const { cmd, args: fullArgs } = cocosCommand(args, env);
24
- return spawn(cmd, fullArgs, options);
25
- }
26
-
27
- function spawnCocosSync(args, options = {}) {
28
- const env = options.env || process.env;
29
- const { cmd, args: fullArgs } = cocosCommand(args, env);
30
- return spawnSync(cmd, fullArgs, options);
31
- }
32
-
33
- module.exports = {
34
- resolveCocosBin,
35
- needsXvfb,
36
- spawnCocos,
37
- spawnCocosSync,
38
- };
1
+ "use strict";const fs=require("fs");const path=require("path");const{spawn,spawnSync}=require("child_process");function resolveCocosBin(env=process.env){return env.COCOS_CLI||"cocos"}function needsXvfb(){return process.platform==="linux"}/**
2
+ * Windows 上 `cocos` 是 npm 生成的 cmd shim(cocos / cocos.cmd / cocos.ps1),不是 exe:
3
+ * spawn('cocos') → CreateProcess 只补 .exe,找不到 → ENOENT
4
+ * spawn('cocos.cmd') → Node 拒绝无 shell 的 .cmd/.bat → EINVAL
5
+ * 套 cmd.exe 能跑,但 kill 只会杀掉 cmd.exe,cocos 进程会变成孤儿占着端口,
6
+ * 所以这里把 shim 里那条 `node <cli.js>` 解出来,用当前 node 直接跑。
7
+ */function findWindowsShim(bin){if(/[\\/]/.test(bin))return fs.existsSync(bin)?bin:"";const result=spawnSync("where",[bin],{encoding:"utf8",windowsHide:true});if(result.error||result.status!==0)return"";const found=String(result.stdout||"").split(/\r?\n/).map(line=>line.trim()).filter(Boolean);return found.find(file=>/\.cmd$/i.test(file))||found.find(file=>/\.exe$/i.test(file))||found[0]||""}/** npm 的 cmd shim 结尾形如: ... "%_prog%" "%dp0%\node_modules\cocos-cli\dist\cli.js" %* */function readShimScript(shimPath){try{const source=fs.readFileSync(shimPath,"utf8");const match=source.match(/%dp0%[\\/]([^"%\r\n]+\.(?:[cm]?js))/i)||source.match(/"([^"\r\n]+\.(?:[cm]?js))"/i);if(!match)return"";const script=path.resolve(path.dirname(shimPath),match[1]);return fs.existsSync(script)?script:""}catch(_){return""}}/**
8
+ * cocos 命令实际落到的文件路径:Windows 上会穿透 npm 的 .cmd shim 拿到 cli.js。
9
+ * 除了 spawn,preview-json-pack 也要靠它往上找 engine/library。
10
+ */function resolveCocosEntryPoint(env=process.env){const bin=resolveCocosBin(env);const isWin=process.platform==="win32";if(path.isAbsolute(bin)){if(!isWin||/\.(?:com|exe|[cm]?js)$/i.test(bin))return bin;return readShimScript(bin)||bin}if(isWin){if(/\.(?:[cm]?js)$/i.test(bin)&&fs.existsSync(bin))return bin;const shim=findWindowsShim(bin);if(!shim)return"";if(/\.exe$/i.test(shim))return shim;return readShimScript(shim)||shim}try{const{execSync}=require("child_process");const found=execSync(`command -v ${JSON.stringify(bin)}`,{encoding:"utf8"}).trim();return found.split(/\r?\n/)[0]||""}catch(_){return""}}function windowsCocosCommand(bin,args,env){if(/\.(?:com|exe)$/i.test(bin))return{cmd:bin,args};const entry=resolveCocosEntryPoint(env);if(entry&&/\.(?:[cm]?js)$/i.test(entry))return{cmd:process.execPath,args:[entry,...args]};if(entry&&/\.exe$/i.test(entry))return{cmd:entry,args};// shim 解不出来时退回 shell,交给 cmd.exe 按 PATHEXT 找(kill 语义会差一些)
11
+ return{cmd:entry||bin,args,shell:true}}function cocosCommand(args,env=process.env){const bin=resolveCocosBin(env);if(needsXvfb()){return{cmd:"xvfb-run",args:["-a",bin,...args]}}if(process.platform==="win32"){return windowsCocosCommand(bin,args,env)}return{cmd:bin,args}}function spawnCocos(args,options={}){const env=options.env||process.env;const{cmd,args:fullArgs,shell}=cocosCommand(args,env);return spawn(cmd,fullArgs,shell?{...options,shell}:options)}function spawnCocosSync(args,options={}){const env=options.env||process.env;const{cmd,args:fullArgs,shell}=cocosCommand(args,env);return spawnSync(cmd,fullArgs,shell?{...options,shell}:options)}module.exports={resolveCocosBin,resolveCocosEntryPoint,needsXvfb,cocosCommand,spawnCocos,spawnCocosSync};
@@ -1,21 +1 @@
1
- 'use strict';
2
-
3
- const ADAPTER_FETCH = 'adapterFetch';
4
- const TO_STRING_EXTNAME = [
5
- '.txt', '.xml', '.vsh', '.fsh', '.atlas', '.tmx', '.tsx', '.json',
6
- '.ExportJson', '.plist', '.fnt', '.js', '.zip'
7
- ];
8
- const TO_SKIP_EXTNAME = ['.ico', '.html', '.css'];
9
- const TRANSPARENT_GIF =
10
- 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
11
- const FILE_MAX_SIZE = 2 * 1024 * 1024 * 0.8;
12
- const THEME_ASSET_EXT = /\.(png|webp|jpe?g|gif|svg|mp3|mpeg|wav|m4a|aac|ogg|mp4)$/i;
13
-
14
- module.exports = {
15
- ADAPTER_FETCH,
16
- TO_STRING_EXTNAME,
17
- TO_SKIP_EXTNAME,
18
- TRANSPARENT_GIF,
19
- FILE_MAX_SIZE,
20
- THEME_ASSET_EXT,
21
- };
1
+ "use strict";const ADAPTER_FETCH="adapterFetch";const TO_STRING_EXTNAME=[".txt",".xml",".vsh",".fsh",".atlas",".tmx",".tsx",".json",".ExportJson",".plist",".fnt",".js",".zip"];const TO_SKIP_EXTNAME=[".ico",".html",".css"];const TRANSPARENT_GIF="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";const FILE_MAX_SIZE=2*1024*1024*0.8;const THEME_ASSET_EXT=/\.(png|webp|jpe?g|gif|svg|mp3|mpeg|wav|m4a|aac|ogg|mp4)$/i;module.exports={ADAPTER_FETCH,TO_STRING_EXTNAME,TO_SKIP_EXTNAME,TRANSPARENT_GIF,FILE_MAX_SIZE,THEME_ASSET_EXT};
@@ -1,108 +1 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { spawnSync } = require('child_process');
6
-
7
- function readCreatorVersion(root) {
8
- try {
9
- const pkg = require(path.join(root, 'package.json'));
10
- return (pkg.creator && pkg.creator.version) || '3.8.6';
11
- } catch {
12
- return '3.8.6';
13
- }
14
- }
15
-
16
- function resolveCreator(root, creatorBin) {
17
- if (creatorBin) return creatorBin;
18
- if (process.env.COCOS_CREATOR) return process.env.COCOS_CREATOR;
19
-
20
- const version = readCreatorVersion(root);
21
- const darwin = [
22
- `/Applications/Cocos/Creator/${version}/CocosCreator.app/Contents/MacOS/CocosCreator`,
23
- `/Applications/CocosCreator/Creator/${version}/CocosCreator.app/Contents/MacOS/CocosCreator`,
24
- ];
25
- const win32 = [
26
- `C:\\ProgramData\\cocos\\editors\\Creator\\${version}\\CocosCreator.exe`,
27
- `C:\\Cocos\\Creator\\${version}\\CocosCreator.exe`,
28
- `C:\\CocosCreator\\Creator\\${version}\\CocosCreator.exe`,
29
- ];
30
- const linux = [
31
- `/opt/Cocos/Creator/${version}/CocosCreator`,
32
- `${process.env.HOME || ''}/Cocos/Creator/${version}/CocosCreator`,
33
- ];
34
- const candidates = process.platform === 'darwin' ? darwin : process.platform === 'win32' ? win32 : linux;
35
- return candidates.find((p) => p && fs.existsSync(p));
36
- }
37
-
38
- function creatorEnv() {
39
- const env = { ...process.env };
40
- delete env.ELECTRON_RUN_AS_NODE;
41
- return env;
42
- }
43
-
44
- function resolveCreatorOutputDir(root, buildConfigRel) {
45
- const configPath = path.resolve(root, buildConfigRel || 'build-configs/web-mobile.json');
46
- if (!fs.existsSync(configPath)) return null;
47
- try {
48
- const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
49
- const outputName = cfg.outputName || 'web-mobile';
50
- const buildPath = cfg.buildPath || 'project://build';
51
- if (buildPath.startsWith('project://')) {
52
- const rel = buildPath.slice('project://'.length).replace(/^\/+/, '');
53
- return path.resolve(root, rel, outputName);
54
- }
55
- if (path.isAbsolute(buildPath)) return path.join(buildPath, outputName);
56
- return path.resolve(root, buildPath, outputName);
57
- } catch {
58
- return null;
59
- }
60
- }
61
-
62
- function runCreatorBuild(root, buildOptions) {
63
- const cocos = buildOptions.cocos || {};
64
- if (cocos.skipEngineBuild) {
65
- console.log('[cocos] skipEngineBuild: using existing web-mobile');
66
- return;
67
- }
68
-
69
- const configPath = path.resolve(root, cocos.buildConfig || 'build-configs/web-mobile.json');
70
- if (!fs.existsSync(configPath)) {
71
- throw new Error(`[cocos] missing Creator build config: ${configPath}`);
72
- }
73
-
74
- const bin = resolveCreator(root, cocos.creatorBin);
75
- if (!bin) {
76
- throw new Error('[cocos] Cocos Creator not found. Set COCOS_CREATOR or cocos.creatorBin.');
77
- }
78
-
79
- if (process.platform === 'linux') {
80
- console.warn('[cocos] Creator fallback on linux; prefer official cocos CLI (xvfb-run -a).');
81
- }
82
-
83
- const buildArg = `configPath=${configPath.replace(/\\/g, '/')};stage=build`;
84
- console.log(`[cocos] ${bin}`);
85
- console.log(`[cocos] --build ${buildArg}`);
86
-
87
- const result = spawnSync(bin, ['--project', root, '--nologin', '--build', buildArg], {
88
- cwd: root,
89
- stdio: 'inherit',
90
- env: creatorEnv(),
91
- });
92
-
93
- if (result.error) throw result.error;
94
- const code = result.status;
95
- if (code === 36 || code === 0) {
96
- console.log('[cocos] web-mobile ready');
97
- return;
98
- }
99
- throw new Error(`[cocos] Creator build failed, exit ${code}`);
100
- }
101
-
102
- module.exports = {
103
- readCreatorVersion,
104
- resolveCreator,
105
- resolveCreatorOutputDir,
106
- creatorEnv,
107
- runCreatorBuild,
108
- };
1
+ "use strict";const fs=require("fs");const path=require("path");const{spawnSync}=require("child_process");function readCreatorVersion(root){try{const pkg=require(path.join(root,"package.json"));return pkg.creator&&pkg.creator.version||"3.8.6"}catch{return"3.8.6"}}function resolveCreator(root,creatorBin){if(creatorBin)return creatorBin;if(process.env.COCOS_CREATOR)return process.env.COCOS_CREATOR;const version=readCreatorVersion(root);const darwin=[`/Applications/Cocos/Creator/${version}/CocosCreator.app/Contents/MacOS/CocosCreator`,`/Applications/CocosCreator/Creator/${version}/CocosCreator.app/Contents/MacOS/CocosCreator`];const win32=[`C:\\ProgramData\\cocos\\editors\\Creator\\${version}\\CocosCreator.exe`,`C:\\Cocos\\Creator\\${version}\\CocosCreator.exe`,`C:\\CocosCreator\\Creator\\${version}\\CocosCreator.exe`];const linux=[`/opt/Cocos/Creator/${version}/CocosCreator`,`${process.env.HOME||""}/Cocos/Creator/${version}/CocosCreator`];const candidates=process.platform==="darwin"?darwin:process.platform==="win32"?win32:linux;return candidates.find(p=>p&&fs.existsSync(p))}function creatorEnv(){const env={...process.env};delete env.ELECTRON_RUN_AS_NODE;return env}function resolveCreatorOutputDir(root,buildConfigRel){const configPath=path.resolve(root,buildConfigRel||"build-configs/web-mobile.json");if(!fs.existsSync(configPath))return null;try{const cfg=JSON.parse(fs.readFileSync(configPath,"utf8"));const outputName=cfg.outputName||"web-mobile";const buildPath=cfg.buildPath||"project://build";if(buildPath.startsWith("project://")){const rel=buildPath.slice("project://".length).replace(/^\/+/,"");return path.resolve(root,rel,outputName)}if(path.isAbsolute(buildPath))return path.join(buildPath,outputName);return path.resolve(root,buildPath,outputName)}catch{return null}}function runCreatorBuild(root,buildOptions){const cocos=buildOptions.cocos||{};if(cocos.skipEngineBuild){console.log("[cocos] skipEngineBuild: using existing web-mobile");return}const configPath=path.resolve(root,cocos.buildConfig||"build-configs/web-mobile.json");if(!fs.existsSync(configPath)){throw new Error(`[cocos] missing Creator build config: ${configPath}`)}const bin=resolveCreator(root,cocos.creatorBin);if(!bin){throw new Error("[cocos] Cocos Creator not found. Set COCOS_CREATOR or cocos.creatorBin.")}if(process.platform==="linux"){console.warn("[cocos] Creator fallback on linux; prefer official cocos CLI (xvfb-run -a).")}const buildArg=`configPath=${configPath.replace(/\\/g,"/")};stage=build`;console.log(`[cocos] ${bin}`);console.log(`[cocos] --build ${buildArg}`);const result=spawnSync(bin,["--project",root,"--nologin","--build",buildArg],{cwd:root,stdio:"inherit",env:creatorEnv()});if(result.error)throw result.error;const code=result.status;if(code===36||code===0){console.log("[cocos] web-mobile ready");return}throw new Error(`[cocos] Creator build failed, exit ${code}`)}module.exports={readCreatorVersion,resolveCreator,resolveCreatorOutputDir,creatorEnv,runCreatorBuild};