@playcraft/devkit 1.0.28 → 1.0.30

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 (55) hide show
  1. package/cli/bin/playable-scripts.js +6 -44
  2. package/cli/commands/build.js +40 -220
  3. package/cli/commands/builds.js +2 -13
  4. package/cli/commands/dev.js +1 -7
  5. package/cli/commands/pack.js +39 -308
  6. package/cli/commands/vite-dev.js +1 -7
  7. package/core/batch-build.js +149 -1255
  8. package/core/constants.js +2 -16
  9. package/core/cos-uploader.js +24 -286
  10. package/core/index.d.ts +4 -1
  11. package/core/index.js +7 -76
  12. package/core/loaders/gltf-loader.js +28 -74
  13. package/core/options.js +15 -326
  14. package/core/plugins/AdikteevInjectorPlugin.js +4 -26
  15. package/core/plugins/BigoAdsInjectorPlugin.js +4 -21
  16. package/core/plugins/DAPIInjectorPlugin.js +2 -25
  17. package/core/plugins/DebuggerInjectionPlugin.js +3 -31
  18. package/core/plugins/ExitAPIInjectorPlugin.js +3 -56
  19. package/core/plugins/FflateCompressionPlugin.js +40 -231
  20. package/core/plugins/FontInjectionWebpackPlugin.js +4 -46
  21. package/core/plugins/LiftoffInjectorPlugin.js +4 -26
  22. package/core/plugins/MRAIDInjectorPlugin.js +2 -24
  23. package/core/plugins/MintegralInjectorPlugin.js +2 -25
  24. package/core/plugins/PangleInjectorPlugin.js +2 -24
  25. package/core/plugins/PlaycraftOrientationInjectorPlugin.js +3 -29
  26. package/core/plugins/SnapchatInjectorPlugin.js +4 -26
  27. package/core/plugins/SocialMediaInjectorPlugin.js +7 -119
  28. package/core/plugins/TikTokInjectorPlugin.js +2 -24
  29. package/core/plugins/UnityInjectorPlugin.js +8 -37
  30. package/core/plugins/ZipPlugin.js +20 -138
  31. package/core/plugins/socialMediaVitePlugin.js +2 -108
  32. package/core/utils/buildDefines.js +2 -30
  33. package/core/utils/buildTemplateString.js +5 -39
  34. package/core/utils/date.js +1 -16
  35. package/core/utils/fontRegistry.js +13 -81
  36. package/core/utils/fontResolver.js +37 -335
  37. package/core/utils/generateAdikteevHtmlWebpackPluginConfig.js +7 -42
  38. package/core/utils/generateBigabidHtmlWebpackPluginConfig.js +3 -30
  39. package/core/utils/generateInMobiHtmlWebpackPluginConfig.js +7 -43
  40. package/core/utils/getPlaycraftOrientationSuffix.js +2 -9
  41. package/core/utils/injectSDKPlugins.js +13 -68
  42. package/core/utils/logOptions.js +5 -46
  43. package/core/utils/mergeOptions.js +2 -19
  44. package/core/utils/parseArgvOptions.js +5 -111
  45. package/core/utils/resolveChannelFold2Zip.js +5 -17
  46. package/core/utils/validateThemeData.js +26 -227
  47. package/core/validators/pre-build-checker.js +26 -286
  48. package/core/validators/tracking-validator.js +40 -358
  49. package/core/vite.dev.js +17 -322
  50. package/core/webpack.build.js +66 -520
  51. package/core/webpack.common.js +11 -177
  52. package/core/webpack.dev.js +6 -88
  53. package/defines.d.ts +1 -0
  54. package/package.json +3 -4
  55. package/README.md +0 -262
@@ -1,9 +1,6 @@
1
- const { validateTracking, printValidationResult } = require('./tracking-validator.js');
2
-
3
- // ============================================================
1
+ "use strict";const{validateTracking,printValidationResult}=require("./tracking-validator.js");// ============================================================
4
2
  // 检查器注册表
5
3
  // ============================================================
6
-
7
4
  /**
8
5
  * 检查器定义
9
6
  * @typedef {Object} Checker
@@ -11,145 +8,35 @@ const { validateTracking, printValidationResult } = require('./tracking-validato
11
8
  * @property {string} description - 检查器描述
12
9
  * @property {boolean} enabled - 是否启用
13
10
  * @property {(projectRoot: string, options: any) => Promise<CheckResult>|CheckResult} validator - 验证函数
14
- */
15
-
16
- /**
11
+ *//**
17
12
  * 检查结果
18
13
  * @typedef {Object} CheckResult
19
14
  * @property {boolean} success - 是否通过
20
15
  * @property {string} message - 结果消息
21
16
  * @property {any} [data] - 额外数据
22
- */
23
-
24
- /**
17
+ *//**
25
18
  * 所有注册的检查器
26
19
  * @type {Map<string, Checker>}
27
- */
28
- const checkers = new Map();
29
-
30
- // ============================================================
20
+ */const checkers=new Map;// ============================================================
31
21
  // 内置检查器
32
22
  // ============================================================
33
-
34
23
  /**
35
24
  * 埋点验证检查器
36
- */
37
- checkers.set('tracking', {
38
- name: '埋点验证',
39
- description: '验证项目中是否正确调用了所有必须的埋点方法',
40
- enabled: true,
41
- validator: (projectRoot, options = {}) => {
42
- const result = validateTracking(projectRoot, {
43
- verbose: options.verbose || false,
44
- extensions: options.extensions,
45
- excludeDirs: options.excludeDirs
46
- });
47
-
48
- return {
49
- success: result.success,
50
- message: result.success
51
- ? '✅ 埋点验证通过'
52
- : `❌ 埋点验证失败:缺少 ${result.errors.length} 个必须的埋点方法`,
53
- data: result
54
- };
55
- }
56
- });
57
-
58
- /**
25
+ */checkers.set("tracking",{name:"\u57CB\u70B9\u9A8C\u8BC1",description:"\u9A8C\u8BC1\u9879\u76EE\u4E2D\u662F\u5426\u6B63\u786E\u8C03\u7528\u4E86\u6240\u6709\u5FC5\u987B\u7684\u57CB\u70B9\u65B9\u6CD5",enabled:true,validator:(projectRoot,options={})=>{const result=validateTracking(projectRoot,{verbose:options.verbose||false,extensions:options.extensions,excludeDirs:options.excludeDirs});return{success:result.success,message:result.success?"\u2705 \u57CB\u70B9\u9A8C\u8BC1\u901A\u8FC7":`❌ 埋点验证失败:缺少 ${result.errors.length} 个必须的埋点方法`,data:result}}});/**
59
26
  * 主题名称检查器
60
27
  * 校验本次构建涉及的主题名称长度是否超过限制(不超过 50 个字符)。
61
28
  * 主题名称过长可能导致下游文件名 / 目录名 / COS Key 超出系统或第三方平台限制。
62
29
  *
63
30
  * 分两种情况校验:
64
31
  * 1. 主题名称自身长度(无论是否拼接渠道名都会超限的情况)。
65
- * 2. 「主题名_渠道名」组合后的长度(对应批量构建产物的第二级目录名 / zip 文件名)。
32
+ * 2. 「主题名_渠道名」组合后的长度(对应批量构建产物的 zip 文件名)。
66
33
  * 渠道名可能带有锁定 UI 等后缀变体(如 google_L / google_P),
67
34
  * 因此必须以传入的 options.channels 实际渠道列表为准逐一比对,
68
35
  * 而不能只校验主题名称本身。
69
- */
70
- checkers.set('themeName', {
71
- name: '主题名称检查',
72
- description: '验证主题名称、以及「主题名_渠道名」组合后的长度是否超过限制(不超过 50 个字符)',
73
- enabled: true,
74
- validator: (projectRoot, options = {}) => {
75
- const MAX_LENGTH = 50;
76
- const themeNames = Array.isArray(options.themes)
77
- ? options.themes.filter(name => typeof name === 'string' && name.length > 0)
78
- : [];
79
- const channelNames = Array.isArray(options.channels)
80
- ? options.channels.filter(name => typeof name === 'string' && name.length > 0)
81
- : [];
82
-
83
- if (themeNames.length === 0) {
84
- return {
85
- success: true,
86
- message: 'ℹ️ 未提供主题名称,跳过主题名称检查'
87
- };
88
- }
89
-
90
- // 情况一:主题名称自身已超过限制(拼不拼渠道名都会超)
91
- const bareInvalidThemes = themeNames.filter(name => name.length > MAX_LENGTH);
92
- const bareInvalidThemeSet = new Set(bareInvalidThemes);
93
-
94
- // 情况二:主题名称自身未超限,但拼接渠道名(含锁定 UI 后缀,如 google_L / google_P)后超限
95
- const combinedViolations = [];
96
- if (channelNames.length > 0) {
97
- themeNames.forEach(theme => {
98
- if (bareInvalidThemeSet.has(theme)) return; // 已在情况一中报告,避免重复
99
-
100
- channelNames.forEach(channel => {
101
- const combined = `${theme}_${channel}`;
102
- if (combined.length > MAX_LENGTH) {
103
- combinedViolations.push({
104
- theme,
105
- channel,
106
- combined,
107
- length: combined.length,
108
- exceededBy: combined.length - MAX_LENGTH
109
- });
110
- }
111
- });
112
- });
113
- }
114
-
115
- if (bareInvalidThemes.length === 0 && combinedViolations.length === 0) {
116
- return {
117
- success: true,
118
- message: channelNames.length > 0
119
- ? `✅ 主题名称检查通过(共 ${themeNames.length} 个主题 × ${channelNames.length} 个渠道,「主题名_渠道名」组合均未超过 ${MAX_LENGTH} 个字符)`
120
- : `✅ 主题名称检查通过(共 ${themeNames.length} 个主题,均未超过 ${MAX_LENGTH} 个字符)`
121
- };
122
- }
123
-
124
- const lines = [];
125
-
126
- if (bareInvalidThemes.length > 0) {
127
- lines.push('主题名称自身已超过长度限制:');
128
- bareInvalidThemes.forEach(name => {
129
- lines.push(` - "${name}" (${name.length} 个字符,超出 ${name.length - MAX_LENGTH} 个字符)`);
130
- });
131
- }
132
-
133
- if (combinedViolations.length > 0) {
134
- lines.push('主题名称本身未超限,但与渠道名拼接后(第二级输出目录名 / zip 文件名)超过长度限制:');
135
- combinedViolations.forEach(v => {
136
- lines.push(
137
- ` - 主题 "${v.theme}" + 渠道 "${v.channel}" → "${v.combined}" ` +
138
- `(${v.length} 个字符,超出 ${v.exceededBy} 个字符)`
139
- );
140
- });
141
- lines.push(' 提示:部分渠道可能带有锁定 UI 后缀(如 google_L / google_P),拼接后长度会更长,请一并纳入考量。');
142
- }
143
-
144
- return {
145
- success: false,
146
- message: `❌ 主题名称检查失败:\n${lines.join('\n')}`,
147
- data: { bareInvalidThemes, combinedViolations, maxLength: MAX_LENGTH }
148
- };
149
- }
150
- });
151
-
152
- // 预留:未来可添加更多检查器
36
+ */checkers.set("themeName",{name:"\u4E3B\u9898\u540D\u79F0\u68C0\u67E5",description:"\u9A8C\u8BC1\u4E3B\u9898\u540D\u79F0\u3001\u4EE5\u53CA\u300C\u4E3B\u9898\u540D_\u6E20\u9053\u540D\u300D\u7EC4\u5408\u540E\u7684\u957F\u5EA6\u662F\u5426\u8D85\u8FC7\u9650\u5236\uFF08\u4E0D\u8D85\u8FC7 50 \u4E2A\u5B57\u7B26\uFF09",enabled:true,validator:(projectRoot,options={})=>{const MAX_LENGTH=50;const themeNames=Array.isArray(options.themes)?options.themes.filter(name=>typeof name==="string"&&name.length>0):[];const channelNames=Array.isArray(options.channels)?options.channels.filter(name=>typeof name==="string"&&name.length>0):[];if(themeNames.length===0){return{success:true,message:"\u2139\uFE0F \u672A\u63D0\u4F9B\u4E3B\u9898\u540D\u79F0\uFF0C\u8DF3\u8FC7\u4E3B\u9898\u540D\u79F0\u68C0\u67E5"}}// 情况一:主题名称自身已超过限制(拼不拼渠道名都会超)
37
+ const bareInvalidThemes=themeNames.filter(name=>name.length>MAX_LENGTH);const bareInvalidThemeSet=new Set(bareInvalidThemes);// 情况二:主题名称自身未超限,但拼接渠道名(含锁定 UI 后缀,如 google_L / google_P)后超限
38
+ const combinedViolations=[];if(channelNames.length>0){themeNames.forEach(theme=>{if(bareInvalidThemeSet.has(theme))return;// 已在情况一中报告,避免重复
39
+ channelNames.forEach(channel=>{const combined=`${theme}_${channel}`;if(combined.length>MAX_LENGTH){combinedViolations.push({theme,channel,combined,length:combined.length,exceededBy:combined.length-MAX_LENGTH})}})})}if(bareInvalidThemes.length===0&&combinedViolations.length===0){return{success:true,message:channelNames.length>0?`✅ 主题名称检查通过(共 ${themeNames.length} 个主题 × ${channelNames.length} 个渠道,「主题名_渠道名」组合均未超过 ${MAX_LENGTH} 个字符)`:`✅ 主题名称检查通过(共 ${themeNames.length} 个主题,均未超过 ${MAX_LENGTH} 个字符)`}}const lines=[];if(bareInvalidThemes.length>0){lines.push("\u4E3B\u9898\u540D\u79F0\u81EA\u8EAB\u5DF2\u8D85\u8FC7\u957F\u5EA6\u9650\u5236\uFF1A");bareInvalidThemes.forEach(name=>{lines.push(` - "${name}" (${name.length} 个字符,超出 ${name.length-MAX_LENGTH} 个字符)`)})}if(combinedViolations.length>0){lines.push("\u4E3B\u9898\u540D\u79F0\u672C\u8EAB\u672A\u8D85\u9650\uFF0C\u4F46\u4E0E\u6E20\u9053\u540D\u62FC\u63A5\u540E\uFF08zip \u6587\u4EF6\u540D\uFF09\u8D85\u8FC7\u957F\u5EA6\u9650\u5236\uFF1A");combinedViolations.forEach(v=>{lines.push(` - 主题 "${v.theme}" + 渠道 "${v.channel}" → "${v.combined}" `+`(${v.length} 个字符,超出 ${v.exceededBy} 个字符)`)});lines.push(" \u63D0\u793A\uFF1A\u90E8\u5206\u6E20\u9053\u53EF\u80FD\u5E26\u6709\u9501\u5B9A UI \u540E\u7F00\uFF08\u5982 google_L / google_P\uFF09\uFF0C\u62FC\u63A5\u540E\u957F\u5EA6\u4F1A\u66F4\u957F\uFF0C\u8BF7\u4E00\u5E76\u7EB3\u5165\u8003\u91CF\u3002")}return{success:false,message:`❌ 主题名称检查失败:\n${lines.join("\n")}`,data:{bareInvalidThemes,combinedViolations,maxLength:MAX_LENGTH}}}});// 预留:未来可添加更多检查器
153
40
  // checkers.set('assets', {
154
41
  // name: '资源检查',
155
42
  // description: '验证项目资源文件的完整性和规范性',
@@ -159,7 +46,6 @@ checkers.set('themeName', {
159
46
  // return { success: true, message: '资源检查通过' };
160
47
  // }
161
48
  // });
162
-
163
49
  // checkers.set('config', {
164
50
  // name: '配置检查',
165
51
  // description: '验证项目配置文件的正确性',
@@ -169,54 +55,23 @@ checkers.set('themeName', {
169
55
  // return { success: true, message: '配置检查通过' };
170
56
  // }
171
57
  // });
172
-
173
58
  // ============================================================
174
59
  // 检查器管理
175
60
  // ============================================================
176
-
177
61
  /**
178
62
  * 注册自定义检查器
179
63
  * @param {string} id - 检查器 ID
180
64
  * @param {Checker} checker - 检查器配置
181
- */
182
- function registerChecker(id, checker) {
183
- if (checkers.has(id)) {
184
- console.warn(`[警告] 检查器 "${id}" 已存在,将被覆盖`);
185
- }
186
- checkers.set(id, checker);
187
- }
188
-
189
- /**
65
+ */function registerChecker(id,checker){if(checkers.has(id)){console.warn(`[警告] 检查器 "${id}" 已存在,将被覆盖`)}checkers.set(id,checker)}/**
190
66
  * 启用/禁用检查器
191
67
  * @param {string} id - 检查器 ID
192
68
  * @param {boolean} enabled - 是否启用
193
- */
194
- function toggleChecker(id, enabled) {
195
- const checker = checkers.get(id);
196
- if (checker) {
197
- checker.enabled = enabled;
198
- } else {
199
- console.warn(`[警告] 未找到检查器: ${id}`);
200
- }
201
- }
202
-
203
- /**
69
+ */function toggleChecker(id,enabled){const checker=checkers.get(id);if(checker){checker.enabled=enabled}else{console.warn(`[警告] 未找到检查器: ${id}`)}}/**
204
70
  * 获取所有检查器列表
205
71
  * @returns {Array<{id: string, name: string, description: string, enabled: boolean}>}
206
- */
207
- function listCheckers() {
208
- return Array.from(checkers.entries()).map(([id, checker]) => ({
209
- id,
210
- name: checker.name,
211
- description: checker.description,
212
- enabled: checker.enabled
213
- }));
214
- }
215
-
216
- // ============================================================
72
+ */function listCheckers(){return Array.from(checkers.entries()).map(([id,checker])=>({id,name:checker.name,description:checker.description,enabled:checker.enabled}))}// ============================================================
217
73
  // 执行检查
218
74
  // ============================================================
219
-
220
75
  /**
221
76
  * 执行所有已启用的检查器
222
77
  * @param {string} projectRoot - 项目根目录
@@ -229,137 +84,22 @@ function listCheckers() {
229
84
  * @param {string[]} [options.themes] - 本次构建涉及的主题名称列表(供 themeName 检查器使用)
230
85
  * @param {string[]} [options.channels] - 本次构建涉及的渠道名称列表(供 themeName 检查器校验「主题名_渠道名」组合长度,可包含锁定 UI 后缀如 google_L / google_P)
231
86
  * @returns {Promise<{success: boolean, results: Map<string, CheckResult>}>}
232
- */
233
- async function runPreBuildChecks(projectRoot, options = {}) {
234
- const {
235
- only = [],
236
- skip = [],
237
- verbose = false,
238
- showDetails = true,
239
- failFast = false
240
- } = options;
241
-
242
- const results = new Map();
243
- let allSuccess = true;
244
-
245
- console.log('\n' + '═'.repeat(70));
246
- console.log('🔍 编译前检查');
247
- console.log('═'.repeat(70));
248
-
249
- // 确定要执行的检查器
250
- let checkersToRun = Array.from(checkers.entries()).filter(([id, checker]) => {
251
- // 如果指定了 only,只运行指定的
252
- if (only.length > 0 && !only.includes(id)) return false;
253
- // 跳过 skip 列表中的
254
- if (skip.includes(id)) return false;
255
- // 只运行启用的
256
- return checker.enabled;
257
- });
258
-
259
- if (checkersToRun.length === 0) {
260
- console.log('\n⚠️ 没有启用的检查器');
261
- console.log('═'.repeat(70) + '\n');
262
- return { success: true, results };
263
- }
264
-
265
- if (verbose) {
266
- console.log(`\n📋 将执行 ${checkersToRun.length} 个检查器:`);
267
- checkersToRun.forEach(([id, checker]) => {
268
- console.log(` - ${checker.name} (${id})`);
269
- });
270
- console.log('');
271
- }
272
-
273
- // 执行检查器
274
- for (const [id, checker] of checkersToRun) {
275
- try {
276
- console.log(`\n▶️ 执行检查: ${checker.name}`);
277
- console.log('-'.repeat(70));
278
-
279
- const result = await Promise.resolve(checker.validator(projectRoot, options));
280
- results.set(id, result);
281
-
282
- console.log(result.message);
283
-
284
- // 详细输出(针对埋点验证)
285
- if (showDetails && id === 'tracking' && result.data) {
286
- printValidationResult(result.data, showDetails);
287
- }
288
-
289
- if (!result.success) {
290
- allSuccess = false;
291
- if (failFast) {
292
- console.log('\n⚠️ failFast 模式:检测到失败,终止后续检查');
293
- break;
294
- }
295
- }
296
-
297
- } catch (error) {
298
- console.error(`\n❌ 检查器 "${checker.name}" 执行失败:`, error.message);
299
- results.set(id, {
300
- success: false,
301
- message: `执行出错: ${error.message}`,
302
- error
303
- });
304
- allSuccess = false;
305
-
306
- if (failFast) break;
307
- }
308
- }
309
-
310
- // 总结
311
- console.log('\n' + '═'.repeat(70));
312
- console.log('📊 检查总结');
313
- console.log('═'.repeat(70));
314
-
315
- const successCount = Array.from(results.values()).filter(r => r.success).length;
316
- const totalCount = results.size;
317
-
318
- console.log(`\n通过: ${successCount}/${totalCount}`);
319
-
320
- if (allSuccess) {
321
- console.log('\n✅ 所有检查通过,可以继续编译!');
322
- } else {
323
- console.log('\n❌ 部分检查失败,请修复后再编译。');
324
- }
325
-
326
- console.log('═'.repeat(70) + '\n');
327
-
328
- return {
329
- success: allSuccess,
330
- results
331
- };
332
- }
333
-
334
- /**
87
+ */async function runPreBuildChecks(projectRoot,options={}){const{only=[],skip=[],verbose=false,showDetails=true,failFast=false}=options;const results=new Map;let allSuccess=true;console.log("\n"+"\u2550".repeat(70));console.log("\uD83D\uDD0D \u7F16\u8BD1\u524D\u68C0\u67E5");console.log("\u2550".repeat(70));// 确定要执行的检查器
88
+ let checkersToRun=Array.from(checkers.entries()).filter(([id,checker])=>{// 如果指定了 only,只运行指定的
89
+ if(only.length>0&&!only.includes(id))return false;// 跳过 skip 列表中的
90
+ if(skip.includes(id))return false;// 只运行启用的
91
+ return checker.enabled});if(checkersToRun.length===0){console.log("\n\u26A0\uFE0F \u6CA1\u6709\u542F\u7528\u7684\u68C0\u67E5\u5668");console.log("\u2550".repeat(70)+"\n");return{success:true,results}}if(verbose){console.log(`\n📋 将执行 ${checkersToRun.length} 个检查器:`);checkersToRun.forEach(([id,checker])=>{console.log(` - ${checker.name} (${id})`)});console.log("")}// 执行检查器
92
+ for(const[id,checker]of checkersToRun){try{console.log(`\n▶️ 执行检查: ${checker.name}`);console.log("-".repeat(70));const result=await Promise.resolve(checker.validator(projectRoot,options));results.set(id,result);console.log(result.message);// 详细输出(针对埋点验证)
93
+ if(showDetails&&id==="tracking"&&result.data){printValidationResult(result.data,showDetails)}if(!result.success){allSuccess=false;if(failFast){console.log("\n\u26A0\uFE0F failFast \u6A21\u5F0F\uFF1A\u68C0\u6D4B\u5230\u5931\u8D25\uFF0C\u7EC8\u6B62\u540E\u7EED\u68C0\u67E5");break}}}catch(error){console.error(`\n❌ 检查器 "${checker.name}" 执行失败:`,error.message);results.set(id,{success:false,message:`执行出错: ${error.message}`,error});allSuccess=false;if(failFast)break}}// 总结
94
+ console.log("\n"+"\u2550".repeat(70));console.log("\uD83D\uDCCA \u68C0\u67E5\u603B\u7ED3");console.log("\u2550".repeat(70));const successCount=Array.from(results.values()).filter(r=>r.success).length;const totalCount=results.size;console.log(`\n通过: ${successCount}/${totalCount}`);if(allSuccess){console.log("\n\u2705 \u6240\u6709\u68C0\u67E5\u901A\u8FC7\uFF0C\u53EF\u4EE5\u7EE7\u7EED\u7F16\u8BD1\uFF01")}else{console.log("\n\u274C \u90E8\u5206\u68C0\u67E5\u5931\u8D25\uFF0C\u8BF7\u4FEE\u590D\u540E\u518D\u7F16\u8BD1\u3002")}console.log("\u2550".repeat(70)+"\n");return{success:allSuccess,results}}/**
335
95
  * 单独运行埋点验证(快捷方法)
336
96
  * @param {string} projectRoot - 项目根目录
337
97
  * @param {Object} [options] - 选项
338
98
  * @returns {Promise<CheckResult>}
339
- */
340
- async function runTrackingCheck(projectRoot, options = {}) {
341
- const checker = checkers.get('tracking');
342
- if (!checker) {
343
- throw new Error('埋点检查器未注册');
344
- }
345
-
346
- return await Promise.resolve(checker.validator(projectRoot, options));
347
- }
348
-
349
- // ============================================================
99
+ */async function runTrackingCheck(projectRoot,options={}){const checker=checkers.get("tracking");if(!checker){throw new Error("\u57CB\u70B9\u68C0\u67E5\u5668\u672A\u6CE8\u518C")}return await Promise.resolve(checker.validator(projectRoot,options))}// ============================================================
350
100
  // 导出
351
101
  // ============================================================
352
-
353
- module.exports = {
354
- // 主要函数
355
- runPreBuildChecks,
356
- runTrackingCheck,
357
-
358
- // 检查器管理
359
- registerChecker,
360
- toggleChecker,
361
- listCheckers,
362
-
363
- // 内部访问(供高级用户)
364
- checkers
365
- };
102
+ module.exports={// 主要函数
103
+ runPreBuildChecks,runTrackingCheck,// 检查器管理
104
+ registerChecker,toggleChecker,listCheckers,// 内部访问(供高级用户)
105
+ checkers};