@playcraft/devkit 1.0.16 → 1.0.17

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 (45) hide show
  1. package/README.md +259 -0
  2. package/cli/bin/playable-scripts.js +44 -1
  3. package/cli/commands/build.js +122 -17
  4. package/cli/commands/builds.js +13 -2
  5. package/cli/commands/dev.js +7 -1
  6. package/cli/commands/pack.js +308 -39
  7. package/cli/commands/vite-dev.js +7 -1
  8. package/core/batch-build.js +1091 -124
  9. package/core/cos-uploader.js +264 -20
  10. package/core/index.js +58 -4
  11. package/core/loaders/gltf-loader.js +74 -28
  12. package/core/options.js +310 -15
  13. package/core/plugins/AdikteevInjectorPlugin.js +26 -4
  14. package/core/plugins/BigoAdsInjectorPlugin.js +21 -4
  15. package/core/plugins/DAPIInjectorPlugin.js +25 -2
  16. package/core/plugins/DebuggerInjectionPlugin.js +31 -3
  17. package/core/plugins/ExitAPIInjectorPlugin.js +57 -3
  18. package/core/plugins/FflateCompressionPlugin.js +225 -37
  19. package/core/plugins/LiftoffInjectorPlugin.js +26 -4
  20. package/core/plugins/MRAIDInjectorPlugin.js +24 -2
  21. package/core/plugins/MintegralInjectorPlugin.js +25 -2
  22. package/core/plugins/PangleInjectorPlugin.js +24 -2
  23. package/core/plugins/SnapchatInjectorPlugin.js +26 -4
  24. package/core/plugins/TikTokInjectorPlugin.js +24 -2
  25. package/core/plugins/UnityInjectorPlugin.js +37 -8
  26. package/core/plugins/ZipPlugin.js +138 -19
  27. package/core/utils/buildDefines.js +29 -2
  28. package/core/utils/buildTemplateString.js +40 -5
  29. package/core/utils/date.js +16 -1
  30. package/core/utils/generateAdikteevHtmlWebpackPluginConfig.js +42 -7
  31. package/core/utils/generateBigabidHtmlWebpackPluginConfig.js +30 -3
  32. package/core/utils/generateInMobiHtmlWebpackPluginConfig.js +43 -7
  33. package/core/utils/injectSDKPlugins.js +58 -11
  34. package/core/utils/logOptions.js +37 -4
  35. package/core/utils/mergeOptions.js +19 -2
  36. package/core/utils/parseArgvOptions.js +110 -5
  37. package/core/utils/resolveChannelFold2Zip.js +15 -3
  38. package/core/utils/validateThemeData.js +220 -25
  39. package/core/validators/pre-build-checker.js +201 -21
  40. package/core/validators/tracking-validator.js +358 -40
  41. package/core/vite.dev.js +181 -15
  42. package/core/webpack.build.js +446 -52
  43. package/core/webpack.common.js +177 -11
  44. package/core/webpack.dev.js +82 -5
  45. package/package.json +3 -2
@@ -1,6 +1,9 @@
1
- "use strict";const{validateTracking,printValidationResult}=require("./tracking-validator.js");// ============================================================
1
+ const { validateTracking, printValidationResult } = require('./tracking-validator.js');
2
+
3
+ // ============================================================
2
4
  // 检查器注册表
3
5
  // ============================================================
6
+
4
7
  /**
5
8
  * 检查器定义
6
9
  * @typedef {Object} Checker
@@ -8,21 +11,51 @@
8
11
  * @property {string} description - 检查器描述
9
12
  * @property {boolean} enabled - 是否启用
10
13
  * @property {(projectRoot: string, options: any) => Promise<CheckResult>|CheckResult} validator - 验证函数
11
- *//**
14
+ */
15
+
16
+ /**
12
17
  * 检查结果
13
18
  * @typedef {Object} CheckResult
14
19
  * @property {boolean} success - 是否通过
15
20
  * @property {string} message - 结果消息
16
21
  * @property {any} [data] - 额外数据
17
- *//**
22
+ */
23
+
24
+ /**
18
25
  * 所有注册的检查器
19
26
  * @type {Map<string, Checker>}
20
- */const checkers=new Map;// ============================================================
27
+ */
28
+ const checkers = new Map();
29
+
30
+ // ============================================================
21
31
  // 内置检查器
22
32
  // ============================================================
33
+
23
34
  /**
24
35
  * 埋点验证检查器
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}}});// 预留:未来可添加更多检查器
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
+ // 预留:未来可添加更多检查器
26
59
  // checkers.set('assets', {
27
60
  // name: '资源检查',
28
61
  // description: '验证项目资源文件的完整性和规范性',
@@ -32,6 +65,7 @@
32
65
  // return { success: true, message: '资源检查通过' };
33
66
  // }
34
67
  // });
68
+
35
69
  // checkers.set('config', {
36
70
  // name: '配置检查',
37
71
  // description: '验证项目配置文件的正确性',
@@ -41,23 +75,54 @@
41
75
  // return { success: true, message: '配置检查通过' };
42
76
  // }
43
77
  // });
78
+
44
79
  // ============================================================
45
80
  // 检查器管理
46
81
  // ============================================================
82
+
47
83
  /**
48
84
  * 注册自定义检查器
49
85
  * @param {string} id - 检查器 ID
50
86
  * @param {Checker} checker - 检查器配置
51
- */function registerChecker(id,checker){if(checkers.has(id)){console.warn(`[警告] 检查器 "${id}" 已存在,将被覆盖`)}checkers.set(id,checker)}/**
87
+ */
88
+ function registerChecker(id, checker) {
89
+ if (checkers.has(id)) {
90
+ console.warn(`[警告] 检查器 "${id}" 已存在,将被覆盖`);
91
+ }
92
+ checkers.set(id, checker);
93
+ }
94
+
95
+ /**
52
96
  * 启用/禁用检查器
53
97
  * @param {string} id - 检查器 ID
54
98
  * @param {boolean} enabled - 是否启用
55
- */function toggleChecker(id,enabled){const checker=checkers.get(id);if(checker){checker.enabled=enabled}else{console.warn(`[警告] 未找到检查器: ${id}`)}}/**
99
+ */
100
+ function toggleChecker(id, enabled) {
101
+ const checker = checkers.get(id);
102
+ if (checker) {
103
+ checker.enabled = enabled;
104
+ } else {
105
+ console.warn(`[警告] 未找到检查器: ${id}`);
106
+ }
107
+ }
108
+
109
+ /**
56
110
  * 获取所有检查器列表
57
111
  * @returns {Array<{id: string, name: string, description: string, enabled: boolean}>}
58
- */function listCheckers(){return Array.from(checkers.entries()).map(([id,checker])=>({id,name:checker.name,description:checker.description,enabled:checker.enabled}))}// ============================================================
112
+ */
113
+ function listCheckers() {
114
+ return Array.from(checkers.entries()).map(([id, checker]) => ({
115
+ id,
116
+ name: checker.name,
117
+ description: checker.description,
118
+ enabled: checker.enabled
119
+ }));
120
+ }
121
+
122
+ // ============================================================
59
123
  // 执行检查
60
124
  // ============================================================
125
+
61
126
  /**
62
127
  * 执行所有已启用的检查器
63
128
  * @param {string} projectRoot - 项目根目录
@@ -68,22 +133,137 @@
68
133
  * @param {boolean} [options.showDetails] - 显示详细报告
69
134
  * @param {boolean} [options.failFast] - 遇到错误立即停止
70
135
  * @returns {Promise<{success: boolean, results: Map<string, CheckResult>}>}
71
- */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));// 确定要执行的检查器
72
- let checkersToRun=Array.from(checkers.entries()).filter(([id,checker])=>{// 如果指定了 only,只运行指定的
73
- if(only.length>0&&!only.includes(id))return false;// 跳过 skip 列表中的
74
- if(skip.includes(id))return false;// 只运行启用的
75
- 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("")}// 执行检查器
76
- 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);// 详细输出(针对埋点验证)
77
- 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}}// 总结
78
- 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}}/**
136
+ */
137
+ async function runPreBuildChecks(projectRoot, options = {}) {
138
+ const {
139
+ only = [],
140
+ skip = [],
141
+ verbose = false,
142
+ showDetails = true,
143
+ failFast = false
144
+ } = options;
145
+
146
+ const results = new Map();
147
+ let allSuccess = true;
148
+
149
+ console.log('\n' + '═'.repeat(70));
150
+ console.log('🔍 编译前检查');
151
+ console.log('═'.repeat(70));
152
+
153
+ // 确定要执行的检查器
154
+ let checkersToRun = Array.from(checkers.entries()).filter(([id, checker]) => {
155
+ // 如果指定了 only,只运行指定的
156
+ if (only.length > 0 && !only.includes(id)) return false;
157
+ // 跳过 skip 列表中的
158
+ if (skip.includes(id)) return false;
159
+ // 只运行启用的
160
+ return checker.enabled;
161
+ });
162
+
163
+ if (checkersToRun.length === 0) {
164
+ console.log('\n⚠️ 没有启用的检查器');
165
+ console.log('═'.repeat(70) + '\n');
166
+ return { success: true, results };
167
+ }
168
+
169
+ if (verbose) {
170
+ console.log(`\n📋 将执行 ${checkersToRun.length} 个检查器:`);
171
+ checkersToRun.forEach(([id, checker]) => {
172
+ console.log(` - ${checker.name} (${id})`);
173
+ });
174
+ console.log('');
175
+ }
176
+
177
+ // 执行检查器
178
+ for (const [id, checker] of checkersToRun) {
179
+ try {
180
+ console.log(`\n▶️ 执行检查: ${checker.name}`);
181
+ console.log('-'.repeat(70));
182
+
183
+ const result = await Promise.resolve(checker.validator(projectRoot, options));
184
+ results.set(id, result);
185
+
186
+ console.log(result.message);
187
+
188
+ // 详细输出(针对埋点验证)
189
+ if (showDetails && id === 'tracking' && result.data) {
190
+ printValidationResult(result.data, showDetails);
191
+ }
192
+
193
+ if (!result.success) {
194
+ allSuccess = false;
195
+ if (failFast) {
196
+ console.log('\n⚠️ failFast 模式:检测到失败,终止后续检查');
197
+ break;
198
+ }
199
+ }
200
+
201
+ } catch (error) {
202
+ console.error(`\n❌ 检查器 "${checker.name}" 执行失败:`, error.message);
203
+ results.set(id, {
204
+ success: false,
205
+ message: `执行出错: ${error.message}`,
206
+ error
207
+ });
208
+ allSuccess = false;
209
+
210
+ if (failFast) break;
211
+ }
212
+ }
213
+
214
+ // 总结
215
+ console.log('\n' + '═'.repeat(70));
216
+ console.log('📊 检查总结');
217
+ console.log('═'.repeat(70));
218
+
219
+ const successCount = Array.from(results.values()).filter(r => r.success).length;
220
+ const totalCount = results.size;
221
+
222
+ console.log(`\n通过: ${successCount}/${totalCount}`);
223
+
224
+ if (allSuccess) {
225
+ console.log('\n✅ 所有检查通过,可以继续编译!');
226
+ } else {
227
+ console.log('\n❌ 部分检查失败,请修复后再编译。');
228
+ }
229
+
230
+ console.log('═'.repeat(70) + '\n');
231
+
232
+ return {
233
+ success: allSuccess,
234
+ results
235
+ };
236
+ }
237
+
238
+ /**
79
239
  * 单独运行埋点验证(快捷方法)
80
240
  * @param {string} projectRoot - 项目根目录
81
241
  * @param {Object} [options] - 选项
82
242
  * @returns {Promise<CheckResult>}
83
- */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))}// ============================================================
243
+ */
244
+ async function runTrackingCheck(projectRoot, options = {}) {
245
+ const checker = checkers.get('tracking');
246
+ if (!checker) {
247
+ throw new Error('埋点检查器未注册');
248
+ }
249
+
250
+ return await Promise.resolve(checker.validator(projectRoot, options));
251
+ }
252
+
253
+ // ============================================================
84
254
  // 导出
85
255
  // ============================================================
86
- module.exports={// 主要函数
87
- runPreBuildChecks,runTrackingCheck,// 检查器管理
88
- registerChecker,toggleChecker,listCheckers,// 内部访问(供高级用户)
89
- checkers};
256
+
257
+ module.exports = {
258
+ // 主要函数
259
+ runPreBuildChecks,
260
+ runTrackingCheck,
261
+
262
+ // 检查器管理
263
+ registerChecker,
264
+ toggleChecker,
265
+ listCheckers,
266
+
267
+ // 内部访问(供高级用户)
268
+ checkers
269
+ };