ttmg-pack 0.0.16 → 0.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.
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ==========================================
|
|
3
3
|
* @Description: ttmg pack
|
|
4
|
-
* @Version: 0.0.
|
|
4
|
+
* @Version: 0.0.17
|
|
5
5
|
* @Author: zhanghongyang.mocha
|
|
6
|
-
* @Date: 2025-08-26 21:
|
|
6
|
+
* @Date: 2025-08-26 21:22:27
|
|
7
7
|
* ==========================================
|
|
8
8
|
*/
|
|
9
|
-
"use strict";var e=require("fs"),t=require("winston"),n=require("path");require("crypto"),require("zlib");var s=require("acorn"),o=require("glob"),i=require("magic-string");function c(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var s=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,s.get?s:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var r=c(e),a=c(n);function u(t){e.existsSync(t)||e.mkdirSync(t,{recursive:!0})}const f=new class{constructor(){this.logger=null}init(e,s=!0){this.enableLog=s,this.logger=t.createLogger({level:"info",format:t.format.combine(t.format.timestamp(),t.format.json()),transports:[new t.transports.File({filename:n.join(e,"pack.log")}),new t.transports.Console]})}info(e){this.enableLog&&this.logger.info(e)}error(e){this.enableLog&&this.logger.error(e)}warn(e){this.enableLog&&this.logger.warn(e)}debug(e){this.enableLog&&this.logger.debug(e)}log(e){this.logger.info(e)}setOutput(e){this.output=e}};function l(t){if(!e.existsSync(t))return!1;if(!e.statSync(t).isDirectory())return!1;let s=!0;const o=e.readdirSync(t);for(const i of o){const o=n.join(t,i);if(e.statSync(o).isDirectory()){l(o)||(s=!1)}else s=!1}return!!s&&(e.rmSync(t,{recursive:!0}),!0)}const m="packageConfig.json",d="project.config.json",g="game.json",p="__GAME__",y=".txt",k="_code",h="_asset",j=62914560,S=["ttmg_odr_tag_1","ttmg_odr_tag_2","ttmg_odr_tag_3"],b=31457280,_=4194304;function w(t,s=[]){let o=0;if(!e.existsSync(t))return 0;const i=e.readdirSync(t,{withFileTypes:!0});for(const c of i){const i=n.join(t,c.name);c.isDirectory()?s.includes(c.name)||(o+=w(i,s)):c.isFile()&&(o+=e.statSync(i).size)}return o}function $(t){const s=e.readdirSync(t,{withFileTypes:!0});for(const o of s){const s=n.join(t,o.name);if(o.isDirectory())$(s);else if(o.isFile()&&(s.endsWith(".js")||s.endsWith(".js.map")))try{e.unlinkSync(s)}catch(e){}}}function x(t){const s=e.readdirSync(t,{withFileTypes:!0});for(const o of s){const s=n.join(t,o.name);if(o.isDirectory())x(s);else if(o.isFile()&&!s.endsWith(".js")&&!s.endsWith(".js.map"))try{e.unlinkSync(s)}catch(e){}}}const O=["node_modules","__MACOSX"],v=[".DS_Store","Thumbs.db"];const F={__GAME__:{code_url:"https://connect.tiktok-minis.com/test/__GAME___code.txt",asset_url:"https://connect.tiktok-minis.com/test/__GAME___asset.txt",asset_md5:"8e3cc2ebd5536e9183b93fda34c1e7f4",root:"",main:"game.js"},configBundle:{root:"subpackages/configBundle",main:"subpackages/configBundle/game.js",asset_md5:"f624a1b37fb35d4dfb1975105a51ebd4",code_url:"https://connect.tiktok-minis.com/test/configBundle_code.txt",asset_url:"https://connect.tiktok-minis.com/test/configBundle_asset.txt"},gameBundle:{main:"subpackages/gameBundle/game.js",root:"subpackages/gameBundle",asset_md5:"fcc9f686bbc8d6f983263e7132598b26",code_url:"https://connect.tiktok-minis.com/test/gameBundle_code.txt",asset_url:"https://connect.tiktok-minis.com/test/gameBundle_asset.txt"},mainBundle:{main:"subpackages/mainBundle/game.js",root:"subpackages/mainBundle",asset_md5:"36b9674d48f9fbb0de6e8f48b194aebc",code_url:"https://connect.tiktok-minis.com/test/mainBundle_code.txt",asset_url:"https://connect.tiktok-minis.com/test/mainBundle_asset.txt"},resources:{root:"subpackages/resources",main:"subpackages/resources/game.js",asset_md5:"1c4608d7690750f7bd5c00663013fc70",code_url:"https://connect.tiktok-minis.com/test/resources_code.txt",asset_url:"https://connect.tiktok-minis.com/test/resources_asset.txt"},iceAndFire:{root:"subpackages/iceAndFire",main:"subpackages/iceAndFire/game.js",asset_md5:"c7fd8e8506dd59725269027a52e2cae4",code_url:"https://connect.tiktok-minis.com/test/iceAndFire_code.txt",asset_url:"https://connect.tiktok-minis.com/test/iceAndFire_asset.txt"},pushstone:{root:"subpackages/pushstone",main:"subpackages/pushstone/game.js",asset_md5:"f5061dba94ad53e1f578325a7cb26a01",code_url:"https://connect.tiktok-minis.com/test/pushstone_code.txt",asset_url:"https://connect.tiktok-minis.com/test/pushstone_asset.txt"},main:{root:"subpackages/main",main:"subpackages/main/game.js",asset_md5:"aece2f69cc168d7cefb248e8574c3371",code_url:"https://connect.tiktok-minis.com/test/main_code.txt",asset_url:"https://connect.tiktok-minis.com/test/main_asset.txt"}},M=[{id:""+1e17*Math.random(),packages:F},{id:""+1e17*Math.random(),packages:F}];function D(t,s){f.info("start check project"),function(e,t){f.info("start check project size");const{projectSizeLimit:n,isDev:s}=t,o=w(e,[]),i=Math.round(o/1048576),c=Math.round(n/1048576);if(o>n){const e=`Game size ${i}MB, must not exceed ${c}MB`;if(f.error(e),!s)throw new Error(e);console.log("[1m[33m%s[0m",e)}else f.info(`Game size ${i}MB, check successfully!`),f.info("Game size check successfully!")}(t,s),function(t){f.info("start check config");const s=n.join(t,g);if(!e.existsSync(s)){const e="can not find game.json in game source code, please check it";throw f.error(e),new Error(e)}f.info("check config successfully")}(t),function(t){f.info("start check project config");const s=n.join(t,d);if(!e.existsSync(s)){const e="can not find project.config.json in game source code, please check it";throw f.error(e),new Error(e)}f.info("check project.config.json successfully");let o;try{o=JSON.parse(e.readFileSync(s,"utf-8"))}catch(e){throw f.error("check project.config.json failed, your project.config.json is invalid json format"),e}if(!(null==o?void 0:o.appid)){const e="can not find appid in project.config.json, you should add appid(client_key) in project.config.json";throw f.error(e),new Error(e)}}(t),f.info("check project successfully")}function E(e,t){f.info("start check main package"),f.info("check game.js");const n=a.join(e,"game.js");if(!r.existsSync(n)){const e="game.js must exist in main package!";throw f.error(e),new Error(e)}f.info("check game.js successfully"),function({entryDir:e,config:t}){f.info("start check main package size");const{mainPackageSizeLimit:n,isDev:s}=t,o=w(e,["subpackages"]),i=Math.round(o/1048576),c=Math.round(n/1048576);if(o>n){const e=`Main package size ${i}MB, must not exceed ${c}MB`;if(!s)throw f.error(e),new Error(e);console.log("[1m[33m%s[0m",e)}else f.info(`Main package size ${i}MB, check successfully!`)}({entryDir:e,config:t}),f.info("check main package successfully")}function P(t,s){const{subpackageSizeLimit:o}=s||{};f.info("start check subpackages in game.json");const i=n.join(t,g),c=JSON.parse(e.readFileSync(i,"utf-8")).subpackages||[];(null==c?void 0:c.length)?c.forEach(s=>{if(!s.name||!s.root){const e="The subpackages configuration in game.json is invalid: the root or name field in one or more subpackages is empty. Please ensure that all subpackages have non-empty root and name values.";throw f.error(e),new Error(e)}const i=n.join(t,s.root);if(!e.existsSync(i)){const e=`The subpackages configuration in game.json is invalid: can not find subpackage ${s.name} entry dir, please check it`;throw f.error(e),new Error(e)}const c=s.root;if(!e.existsSync(n.join(t,c))){const e=`The subpackages configuration in game.json is invalid: can not find subpackage ${s.name} root, please check it`;throw f.error(e),new Error(e)}o&&function({entryDir:e,subPkgName:t,limit:s}){const o=n.join(e,"subpackages",t),i=w(o,[]),c=Math.round(i/1048576);if(c>s){const e=`${t} Sub package size ${c}MB, must not exceed ${s/1048576}MB`;throw f.error(e),new Error(e)}f.info(`${t} Sub package size ${c}MB, check successfully!`)}({entryDir:t,subPkgName:s.name,limit:o})}):f.info("subpackages is empty"),f.info("check subpackages in game.json successfully")}async function z({entryDir:e,config:t}){f.info("开始校验项目"),D(e,t),E(e,t),P(e,t),f.info("校验项目完成")}async function B(t,s){f.info("开始基于源代码中的 game.json 生成 packageConfig.json");const o=n.join(t,g),i=JSON.parse(e.readFileSync(o,"utf-8")),c={};c[p]={url:"",md5:"",root:"",main:"game.js",output:`${p}${y}`},function(e){if(!e||0===e.length)return[];function t(e){return String(e).replace(/^\/+|\/+$/g,"")}function s(e){return o(e)?n.join(e,"game.js"):e}function o(e){return e.endsWith("/")||!/\.[a-zA-Z0-9]+$/.test(e)}function i(e){return e.replace(/^subpackages\/([^/]+).*$/,"subpackages/$1")}return e.map(e=>{const n=t(e.name);return{main:s(e.root),root:i(e.root),name:n}})}(i.subpackages).forEach(({name:e,root:t,main:n})=>{c[e]={url:"",md5:"",root:t,main:n,output:`${e}${y}`}});const r={packages:c};return Object.keys(c).forEach(s=>{const o=n.join(t,c[s].main);if(!e.existsSync(o)){const e=`开发者源代码包中的子包 ${s} 中的 main 文件 ${c[s].main} 不存在`;throw f.error(e),new Error(e)}}),e.existsSync(s)&&e.rmSync(s,{recursive:!0}),e.mkdirSync(s),e.writeFileSync(n.join(s,m),JSON.stringify(r,null,2)),f.info("基于源代码中的 game.json 生成 packageConfig.json 成功"),r}function L(e){const t=[];return Object.values(e).forEach(e=>{Object.values(e).forEach(e=>{t.push(...e)})}),t}function A(t,s=[".js",".ts",".jsx",".tsx"],o=[]){let i=[];if(!e.existsSync(t))return i;const c=e.readdirSync(t,{withFileTypes:!0});for(const e of c){const c=n.join(t,e.name);if(e.isDirectory()){if(o.includes(e.name))continue;i=i.concat(A(c,s,[]))}else s.some(t=>e.name.endsWith(t))&&i.push(c)}return i}function T(t,i){const c=function(t){return e.readdirSync(t).filter(s=>{const o=n.join(t,s);return e.statSync(o).isDirectory()&&!["node_modules","dist","build","output"].includes(s)}).map(e=>e+"/")}(t),r=o.sync("**/*.js",{cwd:t,ignore:[]}),a=[];r.forEach(o=>{const i=n.join(t,o),r=e.readFileSync(i,"utf-8");let u;try{u=s.parse(r,{ecmaVersion:"latest",sourceType:"module"})}catch(e){return}N(u,s=>{if("CallExpression"===s.type&&"Identifier"===s.callee.type&&("require"===s.callee.name||"requireAsync"===s.callee.name)&&s.arguments.length>0&&"Literal"===s.arguments[0].type){const o=s.arguments[0].value;let r=null;if(o.startsWith("."))r=n.resolve(n.dirname(i),o);else if(o.startsWith("/"))r=n.resolve(t,"."+o);else for(const e of c)if(o.startsWith(e)){r=n.resolve(t,o);break}r&&!function(t){if(e.existsSync(t)&&e.statSync(t).isFile())return!0;const n=[".js",".ts",".jsx",".tsx"];for(const s of n)if(e.existsSync(t+s)&&e.statSync(t+s).isFile())return!0;return!1}(r)&&(r=null),a.push({file:n.relative(t,i),callee:s.callee.name,requirePath:o,resolvedPath:r?n.relative(t,r):""})}})});const u=a.map(e=>{let t="";Object.keys(i).forEach(n=>{e.resolvedPath&&e.resolvedPath.startsWith(i[n].root)&&(t=n)});let n="";return Object.keys(i).forEach(t=>{e.file.startsWith(i[t].root)&&(n=t)}),Object.assign(Object.assign({},e),{curModule:n,depModule:t})}),f=[".js",".ts",".jsx",".tsx"];return u.reduce((e,t)=>{return e[t.curModule]||(e[t.curModule]={}),t.curModule===t.depModule||t.resolvedPath&&(n=t.resolvedPath,f.some(e=>n.endsWith(e)))&&(e[t.curModule]=Object.assign(Object.assign({},e[t.curModule]),{[t.resolvedPath]:t.depModule})),e;var n},{})}function N(e,t){t(e);for(let n in e)if(e.hasOwnProperty(n)){const s=e[n];Array.isArray(s)?s.forEach(e=>e&&"string"==typeof e.type&&N(e,t)):s&&"string"==typeof s.type&&N(s,t)}}function C({gameEntry:t,gameOutput:s,pkgName:o,allDeps:c,allMaps:r,pkgConfig:a,destRoot:l}){let m=Date.now();f.info(`pack start,startTime:${m}`);const d=r[o],g={main:a.main,deps:c[o]||{},map:r[o]};u(l),e.writeFileSync(n.join(l,"moduleConfig.json"),JSON.stringify(g));for(const s in d){const c=d[s];if(!Array.isArray(c)||0===c.length)continue;const r=new i.Bundle({separator:"\n"});for(const o of c){const c=n.join(t,o);if(e.existsSync(c)&&(n.basename(c)!==s&&/\.js$/i.test(o))){const t=e.readFileSync(c,"utf-8"),n=o.replace(/\\/g,"/"),s=`define("game:${n}", ["require", "requireAsync", "module", "exports", "sandboxGlobal"], function(require, requireAsync, module, exports, sandboxGlobal){\nwith(sandboxGlobal){\n`,a="\n}\n});\n",u=new i(t,{filename:n}),f=new i(s).appendLeft(s.length,u.toString()).append(a);r.addSource({content:f,filename:n})}}const a=n.join(l,n.basename(s));e.writeFileSync(a,r.toString()+`\n//# sourceMappingURL=${s}.map`);const u=r.generateMap({hires:!0,includeContent:!0,file:s});e.writeFileSync(a+".map",u.toString()),f.info(`pack end,packName:${o}`)}}function G({pkgRoot:t,destRoot:s,packedFiles:o,gameEntry:i,gameOutput:c,skipDirs:r=[],isRoot:a=!0}){if(!e.existsSync(t))return;const f=e.readdirSync(t,{withFileTypes:!0});for(const l of f){const f=n.join(t,l.name),m=n.join(s,l.name);a&&l.isDirectory()&&r.includes(l.name)||(l.isDirectory()?G({pkgRoot:f,destRoot:m,gameOutput:c,packedFiles:o,gameEntry:i,skipDirs:r,isRoot:!1}):(u(n.dirname(m)),o.includes(n.relative(i,f))||e.copyFileSync(f,m)))}}async function q({gameEntry:t,gameOutput:s}){let o=Date.now();!function(t){!function t(s){let o;try{o=e.readdirSync(s)}catch(e){return void f.warn(`无法访问目录: ${s}, ${e.message}`)}o.forEach(o=>{const i=n.join(s,o);try{const n=e.statSync(i);n.isDirectory()?O.includes(o)?(e.rmSync(i,{recursive:!0,force:!0}),f.info(`已删除无用目录: ${i}`)):t(i):n.isFile()&&v.includes(o)&&(e.rmSync(i,{force:!0}),f.info(`已删除无用文件: ${i}`))}catch(e){f.warn(`无法处理: ${i}, ${e.message}`)}})}(t)}(t),f.info(`pack start,startTime:${o}`);const{packages:i}=await B(t,s),c=T(t,i),r=function(e,t){f.info("开始基于游戏源代码收集分包中的 JS 文件");const s={},o=Object.values(t).filter(e=>e.root&&""!==e.root).map(e=>e.root.split(n.sep)[0]).filter(Boolean),i=Array.from(new Set(o));for(const o in t){const c=t[o];let r,a;"__GAME__"===o?(a=A(e,[".js",".ts",".jsx",".tsx"],i),r=e):(r=n.join(e,c.root),a=A(r));const u=[];a.forEach(t=>{u.push(n.relative(e,t).replace(/\\/g,"/"))});const f=t[o].root;s[o]={[f?`${f}/game.pack.js`:"game.pack.js"]:u}}return f.info("基于游戏源代码收集分包中的 JS 文件完成"),s}(t,i);for(const e in r){f.info(`开始基于游戏源代码打包,包名:${e}`);let o=Date.now();const a=i[e],u=n.join(t,a.root),m=n.join(s,e,a.root);C({gameEntry:t,gameOutput:s,allDeps:c,allMaps:r,pkgName:e,pkgConfig:a,destRoot:m}),G({gameEntry:t,gameOutput:s,pkgRoot:u,destRoot:m,packedFiles:L(r),skipDirs:["subpackages"]});l(n.join(s,e)),f.info(`基于游戏源代码打包分包完成,包名:${e}`),f.info(`基于游戏源代码打包分包耗时,包名:${e},耗时:${Date.now()-o}ms`)}return f.info(`pack end,duration:${Date.now()-o}ms`),{}}exports.buildPkgs=async function(t){const{entry:s,output:o,rules:i}=t;let c=Date.now();f.init(o,!0),f.info("TTMG_PACK_VERSION: 0.0.16"),f.info(`pack start, startTime:${c}`),await z({entryDir:s,config:{projectSizeLimit:(null==i?void 0:i.projectSizeLimit)||b,mainPackageSizeLimit:(null==i?void 0:i.mainPackageSizeLimit)||_,subpackageSizeLimit:null==i?void 0:i.subpackageSizeLimit}}),await q({gameEntry:s,gameOutput:o}),await async function(t){let s=Date.now();f.info(`makeOdrPkgs start, ${s}`);const o=n.join(t,m),i=JSON.parse(e.readFileSync(o,"utf-8")),c=i.packages;for(const s in c){const o=n.join(t,s),i=n.join(t,`${s}${k}`),r=n.join(t,`${s}${h}`);u(i),u(r),e.cpSync(o,i,{recursive:!0}),e.cpSync(o,r,{recursive:!0}),x(i),$(r),c[`${s}${k}`]=Object.assign(Object.assign({},c[s]),{code_url:"",code_md5:"",output:`${s}${k}${y}`}),c[`${s}${h}`]=Object.assign(Object.assign({},c[s]),{asset_url:"",asset_md5:"",output:`${s}${h}${y}`})}e.writeFileSync(o,JSON.stringify(i,null,2)),f.info(`makeOdrPkgs end, ${Date.now()-s}ms`)}(o),f.info(`pack end:${Date.now()-c}ms`)},exports.debugPkgs=async function(t){const{entry:s,output:o,rules:i,enableLog:c=!1}=t;f.init(o,c);try{await z({entryDir:s,config:{projectSizeLimit:(null==i?void 0:i.projectSizeLimit)||b,mainPackageSizeLimit:(null==i?void 0:i.mainPackageSizeLimit)||_,isDev:!0}}),await q({gameEntry:s,gameOutput:o}),await function(t){f.info("mergePkgs start");const s=n.join(t,m);let o;try{o=JSON.parse(e.readFileSync(s,"utf-8"))}catch(e){return void f.error(`读取配置文件失败: ${s}, err: ${e.message}`)}const i=o.packages;if(i&&"object"==typeof i){for(const s of Object.keys(i)){const o=n.join(t,s);if(!e.existsSync(o)){f.warn(`package 目录不存在: ${o}`);continue}const i=e.readdirSync(o);for(const s of i){const i=n.join(o,s),c=n.join(t,s);try{const t=e.statSync(i);if(t.isFile())e.copyFileSync(i,c);else if(t.isDirectory())e.cpSync(i,c,{recursive:!0});else if(t.isSymbolicLink()){const n=e.readlinkSync(i);e.existsSync(c)&&e.rmSync(c,{force:!0}),e.symlinkSync(n,c,t.isDirectory()?"dir":"file")}f.info(`合并文件/目录: ${i} -> ${c}`)}catch(e){f.error(`处理文件失败: ${i}, err: ${e.message}`)}}try{e.rmSync(o,{recursive:!0,force:!0}),f.info(`已删除 package 目录: ${o}`)}catch(e){f.error(`删除 package 目录失败: ${o}, err: ${e.message}`)}}f.info("mergePkgs 完成")}else f.error("配置文件中 packages 字段无效, 请检查配置")}(o);const t=e.readFileSync(n.join(o,m),"utf-8");return{isSuccess:!0,packages:JSON.parse(t).packages}}catch(e){return{isSuccess:!1,errorMsg:e.message}}},exports.downloadOdrPkgs=async function(){const t=n.join(__dirname,"temp");e.existsSync(t)||e.mkdirSync(t);const s=await async function(){return M}();f.info("odr_games"),function(e,t){for(const n of e){const{id:e,packages:s}=n,o=a.join(t,e);r.existsSync(o)||r.mkdirSync(o);for(const e in s){const t=s[e],{code_url:n}=t,i=require("child_process").execSync(`curl -s "${n}"`).toString();f.info(`downloadAndSaveCodesSync code, ${n}`);const c=`${e}.txt`,u=a.join(o,c);r.writeFileSync(u,i)}}}(s,t);const o={};for(const e of s){const{id:s,packages:i}=e,c=n.join(t,s);o[s]=w(c)}const i={};S.forEach(e=>{i[e]=[]});const c={};for(const r of s){const{id:s,packages:a}=r,u=o[s];if(u>j)continue;let l=null;for(const c of S){const r=n.join(t,c);e.existsSync(r)||e.mkdirSync(r);if(i[c].reduce((e,t)=>e+o[t],0)+u<=j){const o=n.join(t,s),a=n.join(r,s);e.cpSync(o,a,{recursive:!0}),i[c].push(s),l=c;break}}if(l){c[s]={tag:l,packages:{}};for(const e in a){const t=a[e];f.info(`TTMGODRConfig[gameId].packages, ${t}, ${e}`),c[s].packages[e]={root:t.root,main:t.main,asset_md5:t.asset_md5,asset_url:t.asset_url}}}}const u=n.join(t,"TTMG_ODR_CONFIG.json");e.writeFileSync(u,JSON.stringify(c,null,2),"utf-8"),f.info(`TTMG_ODR_CONFIG.json 已生成: ${u}`)},exports.writeOdrConfig=async function(e){f.info("writeOdrPackagesConfig start");const t=a.join(e,m),n=JSON.parse(r.readFileSync(t,"utf-8")),s=n.packages,o=n.odr_packages||{};for(const e in s){if(e.endsWith(k)){const t=s[e],n=e.split(k)[0];o[n]||(o[n]={}),o[n]=Object.assign(Object.assign({},o[n]),{root:t.root,code_output:t.output,code_md5:t.md5,main:t.main}),delete s[e]}if(e.endsWith(h)){const t=e.split(h)[0],n=s[e];o[t]=Object.assign(Object.assign({},o[t]),{root:n.root,asset_output:n.output,asset_md5:n.md5}),delete s[e]}}n.odr_packages=o,r.writeFileSync(t,JSON.stringify(n,null,2)),f.info("writeOdrPackagesConfig end")};
|
|
9
|
+
"use strict";var e=require("fs"),t=require("winston"),n=require("path");require("crypto"),require("zlib");var s=require("acorn"),o=require("glob"),i=require("magic-string");function c(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var s=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,s.get?s:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var r=c(e),a=c(n);function u(t){e.existsSync(t)||e.mkdirSync(t,{recursive:!0})}const f=new class{constructor(){this.logger=null}init(e,s=!0){this.enableLog=s,this.logger=t.createLogger({level:"info",format:t.format.combine(t.format.timestamp(),t.format.json()),transports:[new t.transports.File({filename:n.join(e,"pack.log")}),new t.transports.Console]})}info(e){this.enableLog&&this.logger.info(e)}error(e){this.enableLog&&this.logger.error(e)}warn(e){this.enableLog&&this.logger.warn(e)}debug(e){this.enableLog&&this.logger.debug(e)}log(e){this.logger.info(e)}setOutput(e){this.output=e}};function l(t){if(!e.existsSync(t))return!1;if(!e.statSync(t).isDirectory())return!1;let s=!0;const o=e.readdirSync(t);for(const i of o){const o=n.join(t,i);if(e.statSync(o).isDirectory()){l(o)||(s=!1)}else s=!1}return!!s&&(e.rmSync(t,{recursive:!0}),!0)}const m="packageConfig.json",d="project.config.json",g="game.json",p="__GAME__",y=".txt",k="_code",h="_asset",j=62914560,S=["ttmg_odr_tag_1","ttmg_odr_tag_2","ttmg_odr_tag_3"],b=31457280,_=4194304;function w(t,s=[]){let o=0;if(!e.existsSync(t))return 0;const i=e.readdirSync(t,{withFileTypes:!0});for(const c of i){const i=n.join(t,c.name);c.isDirectory()?s.includes(c.name)||(o+=w(i,s)):c.isFile()&&(o+=e.statSync(i).size)}return o}function $(t){const s=e.readdirSync(t,{withFileTypes:!0});for(const o of s){const s=n.join(t,o.name);if(o.isDirectory())$(s);else if(o.isFile()&&(s.endsWith(".js")||s.endsWith(".js.map")))try{e.unlinkSync(s)}catch(e){}}}function x(t){const s=e.readdirSync(t,{withFileTypes:!0});for(const o of s){const s=n.join(t,o.name);if(o.isDirectory())x(s);else if(o.isFile()&&!s.endsWith(".js")&&!s.endsWith(".js.map"))try{e.unlinkSync(s)}catch(e){}}}const O=["node_modules","__MACOSX"],v=[".DS_Store","Thumbs.db"];const F={__GAME__:{code_url:"https://connect.tiktok-minis.com/test/__GAME___code.txt",asset_url:"https://connect.tiktok-minis.com/test/__GAME___asset.txt",asset_md5:"8e3cc2ebd5536e9183b93fda34c1e7f4",root:"",main:"game.js"},configBundle:{root:"subpackages/configBundle",main:"subpackages/configBundle/game.js",asset_md5:"f624a1b37fb35d4dfb1975105a51ebd4",code_url:"https://connect.tiktok-minis.com/test/configBundle_code.txt",asset_url:"https://connect.tiktok-minis.com/test/configBundle_asset.txt"},gameBundle:{main:"subpackages/gameBundle/game.js",root:"subpackages/gameBundle",asset_md5:"fcc9f686bbc8d6f983263e7132598b26",code_url:"https://connect.tiktok-minis.com/test/gameBundle_code.txt",asset_url:"https://connect.tiktok-minis.com/test/gameBundle_asset.txt"},mainBundle:{main:"subpackages/mainBundle/game.js",root:"subpackages/mainBundle",asset_md5:"36b9674d48f9fbb0de6e8f48b194aebc",code_url:"https://connect.tiktok-minis.com/test/mainBundle_code.txt",asset_url:"https://connect.tiktok-minis.com/test/mainBundle_asset.txt"},resources:{root:"subpackages/resources",main:"subpackages/resources/game.js",asset_md5:"1c4608d7690750f7bd5c00663013fc70",code_url:"https://connect.tiktok-minis.com/test/resources_code.txt",asset_url:"https://connect.tiktok-minis.com/test/resources_asset.txt"},iceAndFire:{root:"subpackages/iceAndFire",main:"subpackages/iceAndFire/game.js",asset_md5:"c7fd8e8506dd59725269027a52e2cae4",code_url:"https://connect.tiktok-minis.com/test/iceAndFire_code.txt",asset_url:"https://connect.tiktok-minis.com/test/iceAndFire_asset.txt"},pushstone:{root:"subpackages/pushstone",main:"subpackages/pushstone/game.js",asset_md5:"f5061dba94ad53e1f578325a7cb26a01",code_url:"https://connect.tiktok-minis.com/test/pushstone_code.txt",asset_url:"https://connect.tiktok-minis.com/test/pushstone_asset.txt"},main:{root:"subpackages/main",main:"subpackages/main/game.js",asset_md5:"aece2f69cc168d7cefb248e8574c3371",code_url:"https://connect.tiktok-minis.com/test/main_code.txt",asset_url:"https://connect.tiktok-minis.com/test/main_asset.txt"}},M=[{id:""+1e17*Math.random(),packages:F},{id:""+1e17*Math.random(),packages:F}];function D(t,s){f.info("start check project"),function(e,t){f.info("start check project size");const{projectSizeLimit:n,isDev:s}=t,o=w(e,[]),i=Math.round(o/1048576),c=Math.round(n/1048576);if(o>n){const e=`Game size ${i}MB, must not exceed ${c}MB`;if(f.error(e),!s)throw new Error(e);console.log("[1m[33m%s[0m",e)}else f.info(`Game size ${i}MB, check successfully!`),f.info("Game size check successfully!")}(t,s),function(t){f.info("start check config");const s=n.join(t,g);if(!e.existsSync(s)){const e="can not find game.json in game source code, please check it";throw f.error(e),new Error(e)}f.info("check config successfully")}(t),function(t){f.info("start check project config");const s=n.join(t,d);if(!e.existsSync(s)){const e="can not find project.config.json in game source code, please check it";throw f.error(e),new Error(e)}f.info("check project.config.json successfully");let o;try{o=JSON.parse(e.readFileSync(s,"utf-8"))}catch(e){throw f.error("check project.config.json failed, your project.config.json is invalid json format"),e}if(!(null==o?void 0:o.appid)){const e="can not find appid in project.config.json, you should add appid(client_key) in project.config.json";throw f.error(e),new Error(e)}}(t),f.info("check project successfully")}function E(e,t){f.info("start check main package"),f.info("check game.js");const n=a.join(e,"game.js");if(!r.existsSync(n)){const e="game.js must exist in main package!";throw f.error(e),new Error(e)}f.info("check game.js successfully"),function({entryDir:e,config:t}){f.info("start check main package size");const{mainPackageSizeLimit:n,isDev:s}=t,o=w(e,["subpackages"]),i=Math.round(o/1048576),c=Math.round(n/1048576);if(o>n){const e=`Main package size ${i}MB, must not exceed ${c}MB`;if(!s)throw f.error(e),new Error(e);console.log("[1m[33m%s[0m",e)}else f.info(`Main package size ${i}MB, check successfully!`)}({entryDir:e,config:t}),f.info("check main package successfully")}function P(t,s){const{subpackageSizeLimit:o}=s||{};f.info("start check subpackages in game.json");const i=n.join(t,g),c=JSON.parse(e.readFileSync(i,"utf-8")).subpackages||[];(null==c?void 0:c.length)?c.forEach(s=>{if(!s.name||!s.root){const e="The subpackages configuration in game.json is invalid: the root or name field in one or more subpackages is empty. Please ensure that all subpackages have non-empty root and name values.";throw f.error(e),new Error(e)}const i=n.join(t,s.root);if(!e.existsSync(i)){const e=`The subpackages configuration in game.json is invalid: can not find subpackage ${s.name} entry dir, please check it`;throw f.error(e),new Error(e)}const c=s.root;if(!e.existsSync(n.join(t,c))){const e=`The subpackages configuration in game.json is invalid: can not find subpackage ${s.name} root, please check it`;throw f.error(e),new Error(e)}o&&function({entryDir:e,subPkgName:t,limit:s}){const o=n.join(e,"subpackages",t),i=w(o,[]),c=Math.round(i/1048576);if(c>s){const e=`${t} Sub package size ${c}MB, must not exceed ${s/1048576}MB`;throw f.error(e),new Error(e)}f.info(`${t} Sub package size ${c}MB, check successfully!`)}({entryDir:t,subPkgName:s.name,limit:o})}):f.info("subpackages is empty"),f.info("check subpackages in game.json successfully")}async function z({entryDir:e,config:t}){f.info("开始校验项目"),D(e,t),E(e,t),P(e,t),f.info("校验项目完成")}async function B(t,s){f.info("开始基于源代码中的 game.json 生成 packageConfig.json");const o=n.join(t,g),i=JSON.parse(e.readFileSync(o,"utf-8")),c={};c[p]={url:"",md5:"",root:"",main:"game.js",output:`${p}${y}`},function(e){if(!e||0===e.length)return[];function t(e){return String(e).replace(/^\/+|\/+$/g,"")}function s(e){return o(e)?n.join(e,"game.js"):e}function o(e){return e.endsWith("/")||!/\.[a-zA-Z0-9]+$/.test(e)}function i(e){return e.replace(/^subpackages\/([^/]+).*$/,"subpackages/$1")}return e.map(e=>{const n=t(e.name);return{main:s(e.root),root:i(e.root),name:n}})}(i.subpackages).forEach(({name:e,root:t,main:n})=>{c[e]={url:"",md5:"",root:t,main:n,output:`${e}${y}`}});const r={packages:c};return Object.keys(c).forEach(s=>{const o=n.join(t,c[s].main);if(!e.existsSync(o)){const e=`开发者源代码包中的子包 ${s} 中的 main 文件 ${c[s].main} 不存在`;throw f.error(e),new Error(e)}}),e.existsSync(s)&&e.rmSync(s,{recursive:!0}),e.mkdirSync(s),e.writeFileSync(n.join(s,m),JSON.stringify(r,null,2)),f.info("基于源代码中的 game.json 生成 packageConfig.json 成功"),r}function L(e){const t=[];return Object.values(e).forEach(e=>{Object.values(e).forEach(e=>{t.push(...e)})}),t}function A(t,s=[".js",".ts",".jsx",".tsx"],o=[]){let i=[];if(!e.existsSync(t))return i;const c=e.readdirSync(t,{withFileTypes:!0});for(const e of c){const c=n.join(t,e.name);if(e.isDirectory()){if(o.includes(e.name))continue;i=i.concat(A(c,s,[]))}else s.some(t=>e.name.endsWith(t))&&i.push(c)}return i}function T(t,i){const c=function(t){return e.readdirSync(t).filter(s=>{const o=n.join(t,s);return e.statSync(o).isDirectory()&&!["node_modules","dist","build","output"].includes(s)}).map(e=>e+"/")}(t),r=o.sync("**/*.js",{cwd:t,ignore:[]}),a=[];r.forEach(o=>{const i=n.join(t,o),r=e.readFileSync(i,"utf-8");let u;try{u=s.parse(r,{ecmaVersion:"latest",sourceType:"module"})}catch(e){return}N(u,s=>{if("CallExpression"===s.type&&"Identifier"===s.callee.type&&("require"===s.callee.name||"requireAsync"===s.callee.name)&&s.arguments.length>0&&"Literal"===s.arguments[0].type){const o=s.arguments[0].value;let r=null;if(o.startsWith("."))r=n.resolve(n.dirname(i),o);else if(o.startsWith("/"))r=n.resolve(t,"."+o);else for(const e of c)if(o.startsWith(e)){r=n.resolve(t,o);break}r&&!function(t){if(e.existsSync(t)&&e.statSync(t).isFile())return!0;const n=[".js",".ts",".jsx",".tsx"];for(const s of n)if(e.existsSync(t+s)&&e.statSync(t+s).isFile())return!0;return!1}(r)&&(r=null),a.push({file:n.relative(t,i),callee:s.callee.name,requirePath:o,resolvedPath:r?n.relative(t,r):""})}})});const u=a.map(e=>{let t="";Object.keys(i).forEach(n=>{e.resolvedPath&&e.resolvedPath.startsWith(i[n].root)&&(t=n)});let n="";return Object.keys(i).forEach(t=>{e.file.startsWith(i[t].root)&&(n=t)}),Object.assign(Object.assign({},e),{curModule:n,depModule:t})}),f=[".js",".ts",".jsx",".tsx"];return u.reduce((e,t)=>{return e[t.curModule]||(e[t.curModule]={}),t.curModule===t.depModule||t.resolvedPath&&(n=t.resolvedPath,f.some(e=>n.endsWith(e)))&&(e[t.curModule]=Object.assign(Object.assign({},e[t.curModule]),{[t.resolvedPath]:t.depModule})),e;var n},{})}function N(e,t){t(e);for(let n in e)if(e.hasOwnProperty(n)){const s=e[n];Array.isArray(s)?s.forEach(e=>e&&"string"==typeof e.type&&N(e,t)):s&&"string"==typeof s.type&&N(s,t)}}function C({gameEntry:t,gameOutput:s,pkgName:o,allDeps:c,allMaps:r,pkgConfig:a,destRoot:l}){let m=Date.now();f.info(`pack start,startTime:${m}`);const d=r[o],g={main:a.main,deps:c[o]||{},map:r[o]};u(l),e.writeFileSync(n.join(l,"moduleConfig.json"),JSON.stringify(g));for(const s in d){const c=d[s];if(!Array.isArray(c)||0===c.length)continue;const r=new i.Bundle({separator:"\n"});for(const o of c){const c=n.join(t,o);if(e.existsSync(c)&&(n.basename(c)!==s&&/\.js$/i.test(o))){const t=e.readFileSync(c,"utf-8"),n=o.replace(/\\/g,"/"),s=`define("game:${n}", ["require", "requireAsync", "module", "exports", "sandboxGlobal"], function(require, requireAsync, module, exports, sandboxGlobal){\nwith(sandboxGlobal){\n`,a="\n}\n});\n",u=new i(t,{filename:n}),f=new i(s).appendLeft(s.length,u.toString()).append(a);r.addSource({content:f,filename:n})}}const a=n.join(l,n.basename(s));e.writeFileSync(a,r.toString()+`\n//# sourceMappingURL=${s}.map`);const u=r.generateMap({hires:!0,includeContent:!0,file:s});e.writeFileSync(a+".map",u.toString()),f.info(`pack end,packName:${o}`)}}function G({pkgRoot:t,destRoot:s,packedFiles:o,gameEntry:i,gameOutput:c,skipDirs:r=[],isRoot:a=!0}){if(!e.existsSync(t))return;const f=e.readdirSync(t,{withFileTypes:!0});for(const l of f){const f=n.join(t,l.name),m=n.join(s,l.name);a&&l.isDirectory()&&r.includes(l.name)||(l.isDirectory()?G({pkgRoot:f,destRoot:m,gameOutput:c,packedFiles:o,gameEntry:i,skipDirs:r,isRoot:!1}):(u(n.dirname(m)),o.includes(n.relative(i,f))||e.copyFileSync(f,m)))}}async function q({gameEntry:t,gameOutput:s}){let o=Date.now();!function(t){!function t(s){let o;try{o=e.readdirSync(s)}catch(e){return void f.warn(`无法访问目录: ${s}, ${e.message}`)}o.forEach(o=>{const i=n.join(s,o);try{const n=e.statSync(i);n.isDirectory()?O.includes(o)?(e.rmSync(i,{recursive:!0,force:!0}),f.info(`已删除无用目录: ${i}`)):t(i):n.isFile()&&v.includes(o)&&(e.rmSync(i,{force:!0}),f.info(`已删除无用文件: ${i}`))}catch(e){f.warn(`无法处理: ${i}, ${e.message}`)}})}(t)}(t),f.info(`pack start,startTime:${o}`);const{packages:i}=await B(t,s),c=T(t,i),r=function(e,t){f.info("开始基于游戏源代码收集分包中的 JS 文件");const s={},o=Object.values(t).filter(e=>e.root&&""!==e.root).map(e=>e.root.split(n.sep)[0]).filter(Boolean),i=Array.from(new Set(o));for(const o in t){const c=t[o];let r,a;"__GAME__"===o?(a=A(e,[".js",".ts",".jsx",".tsx"],i),r=e):(r=n.join(e,c.root),a=A(r));const u=[];a.forEach(t=>{u.push(n.relative(e,t).replace(/\\/g,"/"))});const f=t[o].root;s[o]={[f?`${f}/game.pack.js`:"game.pack.js"]:u}}return f.info("基于游戏源代码收集分包中的 JS 文件完成"),s}(t,i);for(const e in r){f.info(`开始基于游戏源代码打包,包名:${e}`);let o=Date.now();const a=i[e],u=n.join(t,a.root),m=n.join(s,e,a.root);C({gameEntry:t,gameOutput:s,allDeps:c,allMaps:r,pkgName:e,pkgConfig:a,destRoot:m}),G({gameEntry:t,gameOutput:s,pkgRoot:u,destRoot:m,packedFiles:L(r),skipDirs:["subpackages"]});l(n.join(s,e)),f.info(`基于游戏源代码打包分包完成,包名:${e}`),f.info(`基于游戏源代码打包分包耗时,包名:${e},耗时:${Date.now()-o}ms`)}return f.info(`pack end,duration:${Date.now()-o}ms`),{}}exports.buildPkgs=async function(t){const{entry:s,output:o,rules:i}=t;let c=Date.now();f.init(o,!0),f.info("TTMG_PACK_VERSION: 0.0.17"),f.info(`pack start, startTime:${c}`),await z({entryDir:s,config:{projectSizeLimit:(null==i?void 0:i.projectSizeLimit)||b,mainPackageSizeLimit:(null==i?void 0:i.mainPackageSizeLimit)||_,subpackageSizeLimit:null==i?void 0:i.subpackageSizeLimit}}),await q({gameEntry:s,gameOutput:o}),await async function(t){let s=Date.now();f.info(`makeOdrPkgs start, ${s}`);const o=n.join(t,m),i=JSON.parse(e.readFileSync(o,"utf-8")),c=i.packages;for(const s in c){const o=n.join(t,s),i=n.join(t,`${s}${k}`),r=n.join(t,`${s}${h}`);u(i),u(r),e.cpSync(o,i,{recursive:!0}),e.cpSync(o,r,{recursive:!0}),x(i),$(r),c[`${s}${k}`]=Object.assign(Object.assign({},c[s]),{code_url:"",code_md5:"",output:`${s}${k}${y}`}),c[`${s}${h}`]=Object.assign(Object.assign({},c[s]),{asset_url:"",asset_md5:"",output:`${s}${h}${y}`})}e.writeFileSync(o,JSON.stringify(i,null,2)),f.info(`makeOdrPkgs end, ${Date.now()-s}ms`)}(o),f.info(`pack end:${Date.now()-c}ms`)},exports.debugPkgs=async function(t){const{entry:s,output:o,rules:i,enableLog:c=!1}=t;f.init(o,c);try{await z({entryDir:s,config:{projectSizeLimit:(null==i?void 0:i.projectSizeLimit)||b,mainPackageSizeLimit:(null==i?void 0:i.mainPackageSizeLimit)||_,isDev:!0}}),await q({gameEntry:s,gameOutput:o}),await function(t){f.info("mergePkgs start");const s=n.join(t,m);let o;try{o=JSON.parse(e.readFileSync(s,"utf-8"))}catch(e){return void f.error(`读取配置文件失败: ${s}, err: ${e.message}`)}const i=o.packages;if(i&&"object"==typeof i){for(const s of Object.keys(i)){const o=n.join(t,s);if(!e.existsSync(o)){f.warn(`package 目录不存在: ${o}`);continue}const i=e.readdirSync(o);for(const s of i){const i=n.join(o,s),c=n.join(t,s);try{const t=e.statSync(i);if(t.isFile())e.copyFileSync(i,c);else if(t.isDirectory())e.cpSync(i,c,{recursive:!0});else if(t.isSymbolicLink()){const n=e.readlinkSync(i);e.existsSync(c)&&e.rmSync(c,{force:!0}),e.symlinkSync(n,c,t.isDirectory()?"dir":"file")}f.info(`合并文件/目录: ${i} -> ${c}`)}catch(e){f.error(`处理文件失败: ${i}, err: ${e.message}`)}}try{e.rmSync(o,{recursive:!0,force:!0}),f.info(`已删除 package 目录: ${o}`)}catch(e){f.error(`删除 package 目录失败: ${o}, err: ${e.message}`)}}f.info("mergePkgs 完成")}else f.error("配置文件中 packages 字段无效, 请检查配置")}(o);const t=e.readFileSync(n.join(o,m),"utf-8");return{isSuccess:!0,packages:JSON.parse(t).packages}}catch(e){return{isSuccess:!1,errorMsg:e.message}}},exports.downloadOdrPkgs=async function(){const t=n.join(__dirname,"temp");e.existsSync(t)||e.mkdirSync(t);const s=await async function(){return M}();f.info("odr_games"),function(e,t){for(const n of e){const{id:e,packages:s}=n,o=a.join(t,e);r.existsSync(o)||r.mkdirSync(o);for(const e in s){const t=s[e],{code_url:n}=t,i=require("child_process").execSync(`curl -s "${n}"`).toString();f.info(`downloadAndSaveCodesSync code, ${n}`);const c=`${e}.txt`,u=a.join(o,c);r.writeFileSync(u,i)}}}(s,t);const o={};for(const e of s){const{id:s,packages:i}=e,c=n.join(t,s);o[s]=w(c)}const i={};S.forEach(e=>{i[e]=[]});const c={};for(const r of s){const{id:s,packages:a}=r,u=o[s];if(u>j)continue;let l=null;for(const c of S){const r=n.join(t,c);e.existsSync(r)||e.mkdirSync(r);if(i[c].reduce((e,t)=>e+o[t],0)+u<=j){const o=n.join(t,s),a=n.join(r,s);e.cpSync(o,a,{recursive:!0}),i[c].push(s),l=c;break}}if(l){c[s]={tag:l,packages:{}};for(const e in a){const t=a[e];f.info(`TTMGODRConfig[gameId].packages, ${t}, ${e}`),c[s].packages[e]={root:t.root,main:t.main,asset_md5:t.asset_md5,asset_url:t.asset_url}}}}const u=n.join(t,"TTMG_ODR_CONFIG.json");e.writeFileSync(u,JSON.stringify(c,null,2),"utf-8"),f.info(`TTMG_ODR_CONFIG.json 已生成: ${u}`)},exports.writeOdrConfig=async function(e){f.info("writeOdrPackagesConfig start");const t=a.join(e,m),n=JSON.parse(r.readFileSync(t,"utf-8")),s=n.packages,o=n.odr_packages||{};for(const e in s){if(e.endsWith(k)){const t=s[e],n=e.split(k)[0];o[n]||(o[n]={}),o[n]=Object.assign(Object.assign({},o[n]),{root:t.root,code_output:t.output,code_md5:t.md5,main:t.main}),delete s[e]}if(e.endsWith(h)){const t=e.split(h)[0],n=s[e];o[t]=Object.assign(Object.assign({},o[t]),{root:n.root,asset_output:n.output,asset_md5:n.md5}),delete s[e]}}n.odr_packages=o,r.writeFileSync(t,JSON.stringify(n,null,2)),f.info("writeOdrPackagesConfig end")};
|
|
10
10
|
//# sourceMappingURL=index.js.map
|