@playcraft/devkit 1.0.15-beta.1 → 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 -10
  44. package/core/webpack.dev.js +82 -5
  45. package/package.json +3 -2
package/core/vite.dev.js CHANGED
@@ -1,25 +1,191 @@
1
- "use strict";const path=require("path");const fs=require("fs");const{options}=require("./options.js");const{mergeOptions}=require("./utils/mergeOptions.js");const{buildDefines}=require("./utils/buildDefines.js");const{logOptions}=require("./utils/logOptions.js");/**
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+ const { options } = require('./options.js');
6
+ const { mergeOptions } = require('./utils/mergeOptions.js');
7
+ const { buildDefines } = require('./utils/buildDefines.js');
8
+ const { logOptions } = require('./utils/logOptions.js');
9
+
10
+ /**
2
11
  * 创建 Vite 开发配置
3
12
  * @param {Partial<import('./index').CLIOptions>} [customOptions] - 自定义选项,会与默认选项合并
4
13
  * @param {Record<string, any>} [customDefines] - 额外的 define 常量
5
14
  * @param {import('vite').UserConfig} [viteCustomConfig] - 自定义 Vite 配置,会与默认配置合并
6
15
  * @returns {import('vite').UserConfig} 最终的 Vite 开发配置
7
- */function makeViteDevConfig(customOptions,customDefines,viteCustomConfig){const devOptions=mergeOptions(options,customOptions);logOptions(devOptions);customDefines=customDefines||{};viteCustomConfig=viteCustomConfig||{};// 构建 define 常量(复用 webpack 的 buildDefines 逻辑)
8
- const defines={...buildDefines(),...devOptions.defines,__DEV__:JSON.stringify(devOptions["dev"]===undefined?true:devOptions["dev"]),...customDefines};// 解析 tsconfig/jsconfig 路径别名
9
- const tsConfigPath=path.resolve(devOptions.tsConfig||"tsconfig.json");const jsConfigPath=path.resolve(devOptions.jsConfig||"jsconfig.json");let aliasConfig={};// 尝试从 tsconfig/jsconfig 中读取 paths 配置
10
- let configFilePath=null;if(fs.existsSync(tsConfigPath)){configFilePath=tsConfigPath}else if(fs.existsSync(jsConfigPath)){configFilePath=jsConfigPath}if(configFilePath){try{var _config$compilerOptio;const JSON5=require("json5");const configContent=fs.readFileSync(configFilePath,"utf-8");const config=JSON5.parse(configContent);const paths=((_config$compilerOptio=config.compilerOptions)===null||_config$compilerOptio===void 0?void 0:_config$compilerOptio.paths)||{};for(const[alias,targets]of Object.entries(paths)){var _targets$;// 将 tsconfig paths 格式 "foo/*" -> ["src/foo/*"] 转换为 vite alias
11
- const cleanAlias=alias.replace("/*","");const cleanTarget=((_targets$=targets[0])===null||_targets$===void 0?void 0:_targets$.replace("/*",""))||"";if(cleanAlias&&cleanTarget){aliasConfig[cleanAlias]=path.resolve(cleanTarget)}}}catch(err){console.log("\x1B[33m\u26A0\uFE0F \u8BFB\u53D6\u8DEF\u5F84\u914D\u7F6E\u5931\u8D25: "+err.message+"\x1B[0m")}}// 默认别名
12
- aliasConfig={assets:path.resolve("assets"),"@":path.resolve("src"),...aliasConfig};// JSON5 插件
13
- function json5Plugin(){return{name:"vite-plugin-json5",transform(code,id){if(id.endsWith(".json5")){const JSON5=require("json5");const raw=fs.readFileSync(id,"utf-8");const parsed=JSON5.parse(raw);return{code:`export default ${JSON.stringify(parsed)};`,map:null}}}}}// 资源内联插件(模拟 webpack 的 asset/inline 行为)
14
- function assetInlinePlugin(){return{name:"vite-plugin-asset-inline",enforce:"pre",transform(code,id){// .atlas 文件 -> base64 data URL
15
- if(id.endsWith(".atlas")){const content=fs.readFileSync(id);const base64=content.toString("base64");return{code:`export default "data:text/atlas;base64,${base64}";`,map:null}}// .fnt 文件 -> base64 data URL
16
- if(id.endsWith(".fnt")){const content=fs.readFileSync(id);const base64=content.toString("base64");return{code:`export default "data:text/plain;base64,${base64}";`,map:null}}// .xml 文件 -> 原始文本
17
- if(id.endsWith(".xml")){const raw=fs.readFileSync(id,"utf-8");return{code:`export default ${JSON.stringify(raw)};`,map:null}}}}}/** @type {import('vite').UserConfig} */const viteConfig={root:".",resolve:{alias:aliasConfig},plugins:[json5Plugin(),assetInlinePlugin()],define:defines,server:{port:devOptions["port"]||3000,open:devOptions["open"]||false},build:{outDir:devOptions["outDir"]||"dist",sourcemap:true}};// 合并自定义配置
18
- if(viteCustomConfig){// 简单合并:自定义配置中的字段会覆盖默认配置
19
- const{plugins:customPlugins,define:customDefine,resolve:customResolve,server:customServer,build:customBuild,...rest}=viteCustomConfig;if(customPlugins){viteConfig.plugins=[...viteConfig.plugins,...customPlugins]}if(customDefine){viteConfig.define={...viteConfig.define,...customDefine}}if(customResolve){viteConfig.resolve={...viteConfig.resolve,...customResolve,alias:{...viteConfig.resolve.alias,...(customResolve.alias||{})}}}if(customServer){viteConfig.server={...viteConfig.server,...customServer}}if(customBuild){viteConfig.build={...viteConfig.build,...customBuild}}Object.assign(viteConfig,rest)}return viteConfig}/**
16
+ */
17
+ function makeViteDevConfig(customOptions, customDefines, viteCustomConfig) {
18
+ const devOptions = mergeOptions(options, customOptions);
19
+ logOptions(devOptions);
20
+ customDefines = customDefines || {};
21
+ viteCustomConfig = viteCustomConfig || {};
22
+
23
+ // 构建 define 常量(复用 webpack buildDefines 逻辑)
24
+ const defines = {
25
+ ...buildDefines(),
26
+ ...devOptions.defines,
27
+ __DEV__: JSON.stringify(devOptions['dev'] === undefined ? true : devOptions['dev']),
28
+ ...customDefines,
29
+ };
30
+
31
+ // 解析 tsconfig/jsconfig 路径别名
32
+ const tsConfigPath = path.resolve(devOptions.tsConfig || 'tsconfig.json');
33
+ const jsConfigPath = path.resolve(devOptions.jsConfig || 'jsconfig.json');
34
+ let aliasConfig = {};
35
+
36
+ // 尝试从 tsconfig/jsconfig 中读取 paths 配置
37
+ let configFilePath = null;
38
+ if (fs.existsSync(tsConfigPath)) {
39
+ configFilePath = tsConfigPath;
40
+ } else if (fs.existsSync(jsConfigPath)) {
41
+ configFilePath = jsConfigPath;
42
+ }
43
+
44
+ if (configFilePath) {
45
+ try {
46
+ const JSON5 = require('json5');
47
+ const configContent = fs.readFileSync(configFilePath, 'utf-8');
48
+ const config = JSON5.parse(configContent);
49
+ const paths = config.compilerOptions?.paths || {};
50
+ for (const [alias, targets] of Object.entries(paths)) {
51
+ // 将 tsconfig paths 格式 "foo/*" -> ["src/foo/*"] 转换为 vite alias
52
+ const cleanAlias = alias.replace('/*', '');
53
+ const cleanTarget = targets[0]?.replace('/*', '') || '';
54
+ if (cleanAlias && cleanTarget) {
55
+ aliasConfig[cleanAlias] = path.resolve(cleanTarget);
56
+ }
57
+ }
58
+ } catch (err) {
59
+ console.log('\x1b[33m⚠️ 读取路径配置失败: ' + err.message + '\x1b[0m');
60
+ }
61
+ }
62
+
63
+ // 默认别名
64
+ aliasConfig = {
65
+ assets: path.resolve('assets'),
66
+ '@': path.resolve('src'),
67
+ ...aliasConfig,
68
+ };
69
+
70
+ // JSON5 插件
71
+ function json5Plugin() {
72
+ return {
73
+ name: 'vite-plugin-json5',
74
+ transform(code, id) {
75
+ if (id.endsWith('.json5')) {
76
+ const JSON5 = require('json5');
77
+ const raw = fs.readFileSync(id, 'utf-8');
78
+ const parsed = JSON5.parse(raw);
79
+ return {
80
+ code: `export default ${JSON.stringify(parsed)};`,
81
+ map: null,
82
+ };
83
+ }
84
+ },
85
+ };
86
+ }
87
+
88
+ // 资源内联插件(模拟 webpack 的 asset/inline 行为)
89
+ function assetInlinePlugin() {
90
+ return {
91
+ name: 'vite-plugin-asset-inline',
92
+ enforce: 'pre',
93
+ transform(code, id) {
94
+ // .atlas 文件 -> base64 data URL
95
+ if (id.endsWith('.atlas')) {
96
+ const content = fs.readFileSync(id);
97
+ const base64 = content.toString('base64');
98
+ return {
99
+ code: `export default "data:text/atlas;base64,${base64}";`,
100
+ map: null,
101
+ };
102
+ }
103
+ // .fnt 文件 -> base64 data URL
104
+ if (id.endsWith('.fnt')) {
105
+ const content = fs.readFileSync(id);
106
+ const base64 = content.toString('base64');
107
+ return {
108
+ code: `export default "data:text/plain;base64,${base64}";`,
109
+ map: null,
110
+ };
111
+ }
112
+ // .xml 文件 -> 原始文本
113
+ if (id.endsWith('.xml')) {
114
+ const raw = fs.readFileSync(id, 'utf-8');
115
+ return {
116
+ code: `export default ${JSON.stringify(raw)};`,
117
+ map: null,
118
+ };
119
+ }
120
+ },
121
+ };
122
+ }
123
+
124
+ /** @type {import('vite').UserConfig} */
125
+ const viteConfig = {
126
+ root: '.',
127
+ resolve: {
128
+ alias: aliasConfig,
129
+ },
130
+ plugins: [json5Plugin(), assetInlinePlugin()],
131
+ define: defines,
132
+ server: {
133
+ port: devOptions['port'] || 3000,
134
+ open: devOptions['open'] || false,
135
+ },
136
+ build: {
137
+ outDir: devOptions['outDir'] || 'dist',
138
+ sourcemap: true,
139
+ },
140
+ };
141
+
142
+ // 合并自定义配置
143
+ if (viteCustomConfig) {
144
+ // 简单合并:自定义配置中的字段会覆盖默认配置
145
+ const { plugins: customPlugins, define: customDefine, resolve: customResolve, server: customServer, build: customBuild, ...rest } = viteCustomConfig;
146
+
147
+ if (customPlugins) {
148
+ viteConfig.plugins = [...viteConfig.plugins, ...customPlugins];
149
+ }
150
+ if (customDefine) {
151
+ viteConfig.define = { ...viteConfig.define, ...customDefine };
152
+ }
153
+ if (customResolve) {
154
+ viteConfig.resolve = {
155
+ ...viteConfig.resolve,
156
+ ...customResolve,
157
+ alias: { ...viteConfig.resolve.alias, ...(customResolve.alias || {}) },
158
+ };
159
+ }
160
+ if (customServer) {
161
+ viteConfig.server = { ...viteConfig.server, ...customServer };
162
+ }
163
+ if (customBuild) {
164
+ viteConfig.build = { ...viteConfig.build, ...customBuild };
165
+ }
166
+ Object.assign(viteConfig, rest);
167
+ }
168
+
169
+ return viteConfig;
170
+ }
171
+
172
+ /**
20
173
  * 启动 Vite 开发服务器
21
174
  * @param {import('vite').UserConfig} [viteConfig] - Vite 配置,不传则自动创建
22
175
  * @param {Partial<import('./index').CLIOptions>} [customOptions] - 自定义选项
23
176
  * @param {Record<string, any>} [customDefines] - 额外的 define 常量
24
177
  * @param {import('vite').UserConfig} [viteCustomConfig] - 自定义 Vite 配置
25
- */async function runViteDev(viteConfig,customOptions,customDefines,viteCustomConfig){if(!viteConfig){viteConfig=makeViteDevConfig(customOptions,customDefines,viteCustomConfig)}const{createServer}=require("vite");const server=await createServer(viteConfig);await server.listen();server.printUrls()}exports.makeViteDevConfig=makeViteDevConfig;exports.runViteDev=runViteDev;
178
+ */
179
+ async function runViteDev(viteConfig, customOptions, customDefines, viteCustomConfig) {
180
+ if (!viteConfig) {
181
+ viteConfig = makeViteDevConfig(customOptions, customDefines, viteCustomConfig);
182
+ }
183
+
184
+ const { createServer } = require('vite');
185
+ const server = await createServer(viteConfig);
186
+ await server.listen();
187
+ server.printUrls();
188
+ }
189
+
190
+ exports.makeViteDevConfig = makeViteDevConfig;
191
+ exports.runViteDev = runViteDev;