@ttmg/cli 0.2.7-beta.1 → 0.2.7-unity.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,8 +12,8 @@
12
12
  rel="stylesheet"
13
13
  />
14
14
  <title>TikTok Mini Games DevTool</title>
15
- <script type="module" crossorigin src="/assets/index-8YuJCDkr.js"></script>
16
- <link rel="stylesheet" crossorigin href="/assets/index-DwF7jabB.css">
15
+ <script type="module" crossorigin src="/assets/index-HQmYB1jW.js"></script>
16
+ <link rel="stylesheet" crossorigin href="/assets/index-yQFyt16Q.css">
17
17
  </head>
18
18
  <body>
19
19
  <div id="root"></div>
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 子线程进行编译
2
+ * 子线程进行编译(Worker)
3
3
  */
4
4
  const { debugPkgs } = require('ttmg-pack');
5
5
  const https = require('https');
@@ -10,57 +10,92 @@ const semver = require('semver');
10
10
  const { parentPort } = require('worker_threads');
11
11
  const { execSync } = require('child_process');
12
12
 
13
- // 获取 npm 最新版本
13
+ /**
14
+ * 获取 npm 最新版本
15
+ */
14
16
  function getLatestVersion(pkgName) {
15
17
  return new Promise((resolve, reject) => {
16
- https
17
- .get(
18
- `https://registry.npmjs.org/${encodeURIComponent(pkgName)}/latest`,
19
- res => {
20
- let data = '';
21
- res.on('data', chunk => (data += chunk));
22
- res.on('end', () => {
23
- try {
24
- const info = JSON.parse(data);
25
- resolve(info.version);
26
- } catch (err) {
27
- resolve(null);
28
- }
29
- });
30
- },
31
- )
32
- .on('error', reject);
18
+ const req = https.get(
19
+ `https://registry.npmjs.org/${encodeURIComponent(pkgName)}/latest`,
20
+ res => {
21
+ if (res.statusCode && res.statusCode >= 400) {
22
+ // 2xx 状态码直接返回 null(不阻断主流程)
23
+ res.resume(); // 消耗流避免 socket 泄漏
24
+ return resolve(null);
25
+ }
26
+ let data = '';
27
+ res.setEncoding('utf8');
28
+ res.on('data', chunk => (data += chunk));
29
+ res.on('end', () => {
30
+ try {
31
+ const info = JSON.parse(data);
32
+ resolve(info?.version ?? null);
33
+ } catch {
34
+ resolve(null);
35
+ }
36
+ });
37
+ res.on('error', () => resolve(null));
38
+ },
39
+ );
40
+ req.on('error', () => resolve(null));
41
+ req.setTimeout(8000, () => {
42
+ req.destroy();
43
+ resolve(null);
44
+ });
33
45
  });
34
46
  }
35
47
 
36
- // 获取全局已安装版本
48
+ /**
49
+ * 获取全局已安装版本
50
+ * 显式设置 stdio,避免在 worker/CI/守护环境中继承到非法 fd 触发 EBADF
51
+ */
37
52
  function getGlobalVersion(pkgName) {
38
53
  try {
39
- const output = execSync(`npm ls -g ${pkgName} --depth=0 --json`).toString();
54
+ const output = execSync(`npm ls -g ${pkgName} --depth=0 --json`, {
55
+ stdio: ['ignore', 'pipe', 'pipe'],
56
+ });
40
57
  const json = JSON.parse(output);
41
- return json.dependencies[pkgName].version;
42
- } catch (e) {
58
+ return json?.dependencies?.[pkgName]?.version ?? null;
59
+ } catch {
43
60
  return null;
44
61
  }
45
62
  }
46
63
 
47
64
  async function compile(context = {}) {
48
65
  try {
49
- const { clientKey, outputDir, entryDir, devPort } = context;
66
+ const { clientKey, outputDir, entryDir, devPort, mode } = context;
67
+
68
+ // 参数校验
50
69
  if (!clientKey) {
51
- if (context?.mode !== 'watch') {
52
- // 通知主线程错误
53
- parentPort.postMessage({ type: 'error', error: msg });
70
+ const message = '缺少 clientKey';
71
+ if (mode !== 'watch') {
72
+ parentPort?.postMessage({ type: 'error', error: message });
54
73
  return;
55
74
  }
56
- throw new Error(msg);
75
+ throw new Error(message);
57
76
  }
58
- if (!fs.existsSync(outputDir)) {
59
- fs.mkdirSync(outputDir, { recursive: true });
77
+
78
+ // 输出目录重建
79
+ try {
80
+ console.log(chalk(`🔍 Game local debug assets temp directory`, chalk.yellow.underline(outputDir)));
81
+ if (outputDir && fs.existsSync(outputDir)) {
82
+ fs.rmSync(outputDir, { recursive: true, force: true });
83
+ }
84
+ if (outputDir) {
85
+ fs.mkdirSync(outputDir, { recursive: true });
86
+ }
87
+ } catch (e) {
88
+ // 目录操作失败也上报
89
+ parentPort?.postMessage({
90
+ type: 'error',
91
+ error: `初始化输出目录失败: ${e?.message || e}`,
92
+ });
93
+ return;
60
94
  }
61
95
 
62
- parentPort.postMessage({ type: 'status', status: 'start' });
96
+ parentPort?.postMessage({ type: 'status', status: 'start' });
63
97
 
98
+ // 调用打包
64
99
  const { isSuccess, errorMsg, packages } = await debugPkgs({
65
100
  entry: entryDir,
66
101
  output: outputDir,
@@ -78,17 +113,22 @@ async function compile(context = {}) {
78
113
  mainPkgSizeLimit: 4 * 1024 * 1024,
79
114
  independentSubPkgSizeLimit: 4 * 1024 * 1024,
80
115
  },
116
+ // 如果 ttmg-pack 支持透传选项,可考虑加上 stdio/并发等设置:
117
+ // spawnOptions: { stdio: ['ignore', 'pipe', 'pipe'] },
118
+ // concurrency: 4,
81
119
  });
82
120
 
121
+ console.log(isSuccess, errorMsg, packages);
122
+
83
123
  if (!isSuccess) {
84
- parentPort.postMessage({
124
+ parentPort?.postMessage({
85
125
  type: 'status',
86
126
  status: 'end',
87
127
  isSuccess: false,
88
- errorMsg,
128
+ errorMsg: errorMsg || '构建失败',
89
129
  });
90
130
  } else {
91
- parentPort.postMessage({
131
+ parentPort?.postMessage({
92
132
  type: 'status',
93
133
  status: 'end',
94
134
  isSuccess: true,
@@ -96,40 +136,47 @@ async function compile(context = {}) {
96
136
  });
97
137
  }
98
138
  } catch (err) {
99
- parentPort.postMessage({ type: 'error', error: err.message || err });
139
+ parentPort?.postMessage({
140
+ type: 'error',
141
+ error: err?.message || String(err),
142
+ });
100
143
  }
101
144
  }
102
145
 
103
146
  async function checkUpdate() {
104
- const pkgName = '@ttmg/cli';
105
- const oldVersion = getGlobalVersion(pkgName);
106
- const newVersion = await getLatestVersion(pkgName);
107
- if (!newVersion) {
108
- return;
109
- }
147
+ try {
148
+ const pkgName = '@ttmg/cli';
149
+ const [oldVersion, newVersion] = await Promise.all([
150
+ getGlobalVersion(pkgName),
151
+ getLatestVersion(pkgName),
152
+ ]);
110
153
 
111
- if (!oldVersion) {
112
- console.log(chalk.yellow(`未检测到全局安装的 ${pkgName}`));
113
- return;
114
- }
154
+ if (!newVersion) {
155
+ return;
156
+ }
115
157
 
116
- if (oldVersion !== newVersion) {
117
- const oldVersionIsBeta = oldVersion.includes('beta');
118
- const newVersionIsBeta = newVersion.includes('beta');
119
- if (oldVersionIsBeta && newVersionIsBeta) {
158
+ if (!oldVersion) {
159
+ console.log(chalk.yellow(`未检测到全局安装的 ${pkgName}`));
120
160
  return;
121
161
  }
162
+
163
+ if (oldVersion === newVersion) return;
164
+
165
+ const oldVersionIsBeta = oldVersion.includes('beta');
166
+ const newVersionIsBeta = newVersion.includes('beta');
167
+ if (oldVersionIsBeta && newVersionIsBeta) return;
168
+
122
169
  const oldVersionMajor = semver.major(oldVersion);
123
170
  const newVersionMajor = semver.major(newVersion);
124
- if (oldVersionIsBeta && oldVersionMajor >= newVersionMajor) {
125
- return;
126
- }
171
+ if (oldVersionIsBeta && oldVersionMajor >= newVersionMajor) return;
127
172
 
128
173
  const message = `
129
174
  ${chalk.bold('Update available!')} ${chalk.red(oldVersion)} ${chalk.white('→')} ${chalk.green(newVersion)}.
130
175
  ${chalk.magenta('Changelog:')} ${chalk.cyan(`https://npmjs.com/package/${pkgName}/v/${newVersion}`)}
131
176
  To update, run: ${chalk.magenta(`npm i -g ${pkgName}`)}
132
177
  `.trim();
178
+
179
+ // 动态引入 boxen,避免主线程初始化时不必要的 require
133
180
  const boxen = require('boxen').default;
134
181
  console.log(
135
182
  boxen(message, {
@@ -139,15 +186,22 @@ To update, run: ${chalk.magenta(`npm i -g ${pkgName}`)}
139
186
  borderColor: 'yellowBright',
140
187
  }),
141
188
  );
189
+ } catch (e) {
190
+ // 更新检查失败不影响主流程
142
191
  }
143
192
  }
144
193
 
145
- // worker入口
146
- parentPort.on('message', async msg => {
147
- if (msg.type === 'compile') {
148
- await compile(msg.context);
149
- }
150
- if (msg.type === 'checkUpdate') {
151
- await checkUpdate();
152
- }
153
- });
194
+ // worker 入口
195
+ if (parentPort) {
196
+ parentPort.on('message', async msg => {
197
+ try {
198
+ if (msg?.type === 'compile') {
199
+ await compile(msg.context);
200
+ } else if (msg?.type === 'checkUpdate') {
201
+ await checkUpdate();
202
+ }
203
+ } catch (e) {
204
+ parentPort.postMessage({ type: 'error', error: e?.message || String(e) });
205
+ }
206
+ });
207
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttmg/cli",
3
- "version": "0.2.7-beta.1",
3
+ "version": "0.2.7-unity.1",
4
4
  "description": "TikTok Mini Game Command Line Tool",
5
5
  "license": "ISC",
6
6
  "bin": {
@@ -47,7 +47,7 @@
47
47
  "prettier": "^3.6.2",
48
48
  "qrcode": "^1.5.4",
49
49
  "semver": "^7.7.2",
50
- "ttmg-pack": "0.1.8",
50
+ "ttmg-pack": "0.2.2-unity.2",
51
51
  "ws": "^8.18.3"
52
52
  },
53
53
  "devDependencies": {