publish_wxgame.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // v1.8.9
  2. const ideModuleDir = global.ideModuleDir;
  3. const workSpaceDir = global.workSpaceDir;
  4. //引用插件模块
  5. const gulp = require(ideModuleDir + "gulp");
  6. const fs = require("fs");
  7. const path = require("path");
  8. const del = require(ideModuleDir + "del");
  9. const revCollector = require(ideModuleDir + 'gulp-rev-collector');
  10. const { getEngineVersion, getFileMd5, canUsePluginEngine } = require("./pub_utils");
  11. const provider = "wx70d8aa25ec591f7a";
  12. const minPluginVersion = "2.0.1";
  13. let fullRemoteEngineList = ["laya.core.js", "laya.filter.js", "laya.ani.js", "laya.tiledmap.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.webgl.js", "laya.filter.js", "laya.d3Plugin.js"];
  14. let copyLibsTask = ["copyPlatformLibsJsFile"];
  15. let versiontask = ["version2"];
  16. let
  17. config,
  18. releaseDir;
  19. let isOpendataProj;
  20. let versionCon; // 版本管理version.json
  21. let commandSuffix,
  22. layarepublicPath;
  23. gulp.task("preCreate_WX", copyLibsTask, function() {
  24. releaseDir = global.releaseDir;
  25. config = global.config;
  26. commandSuffix = global.commandSuffix;
  27. layarepublicPath = global.layarepublicPath;
  28. if (config.useMinJsLibs) {
  29. fullRemoteEngineList = fullRemoteEngineList.map((item, index) => {
  30. return item.replace(".js", ".min.js");
  31. })
  32. }
  33. // 是否是开放域项目
  34. let projInfoPath = path.join(workSpaceDir, path.basename(workSpaceDir) + ".laya");
  35. let isExist = fs.existsSync(projInfoPath);
  36. if (isExist) {
  37. try {
  38. let projInfo = fs.readFileSync(projInfoPath, "utf8");
  39. projInfo = projInfo && JSON.parse(projInfo);
  40. isOpendataProj = projInfo.layaProType === 12;
  41. } catch (e) {}
  42. }
  43. });
  44. gulp.task("copyPlatformFile_WX", ["preCreate_WX"], function() {
  45. let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "wxfiles");
  46. // 开放域项目
  47. if (isOpendataProj) {
  48. let platformDir = path.join(adapterPath, "weapp-adapter.js");
  49. let stream = gulp.src(platformDir);
  50. return stream.pipe(gulp.dest(releaseDir));
  51. }
  52. // 如果新建项目时已经点击了"微信/百度小游戏bin目录快速调试",不再拷贝
  53. let hasPlatform =
  54. fs.existsSync(path.join(workSpaceDir, "bin", "game.js")) &&
  55. fs.existsSync(path.join(workSpaceDir, "bin", "game.json")) &&
  56. fs.existsSync(path.join(workSpaceDir, "bin", "project.config.json"));
  57. let hasPublishPlatform =
  58. fs.existsSync(path.join(releaseDir, "game.js")) &&
  59. fs.existsSync(path.join(releaseDir, "game.json")) &&
  60. fs.existsSync(path.join(releaseDir, "project.config.json"));
  61. let copyLibsList;
  62. if (hasPlatform || hasPublishPlatform) {
  63. copyLibsList = [`${adapterPath}/weapp-adapter.js`];
  64. } else {
  65. copyLibsList = [`${adapterPath}/*.*`];
  66. }
  67. var stream = gulp.src(copyLibsList);
  68. return stream.pipe(gulp.dest(releaseDir));
  69. });
  70. // 适配微信wasm
  71. gulp.task("fitwasm_WX", ["copyPlatformFile_WX"], function() {
  72. let
  73. phy3dWasmJs = path.join(releaseDir, "libs", "laya.physics3D.wasm.js"),
  74. phy3dWasmMinJs = path.join(releaseDir, "libs", "min", "laya.physics3D.wasm.min.js");
  75. let isPhy3dWasmJsExist = fs.existsSync(phy3dWasmJs);
  76. let isPhy3dWasmMinJsExist = fs.existsSync(phy3dWasmMinJs);
  77. if (!isPhy3dWasmJsExist && !isPhy3dWasmMinJsExist) {
  78. return;
  79. }
  80. let phy3dWasmName = isPhy3dWasmJsExist ? phy3dWasmJs : phy3dWasmMinJs;
  81. con = fs.readFileSync(phy3dWasmName, "utf8");
  82. con = con.replace(/WebAssembly/mg, "WXWebAssembly");
  83. con = con.replace(/(fetch\(("[\w./]+")\)\.then[(\w)\s=>]+\{\n?\s*[(\.\w)\s=>]+\{)(\n?\s*WXWebAssembly\.instantiate\()(\w+,)/mg, "/** $1 */$3/** $4 */$2,");
  84. con = con.replace(/(\}\);?\n?\s*\}\);?\n?)(\s*\}\);?\n?\s*\};)/mg, "/** $1 */$2");
  85. fs.writeFileSync(phy3dWasmName, con, "utf8");
  86. })
  87. // 开放域的情况下,合并game.js和index.js,并删除game.js
  88. gulp.task("openData_WX", versiontask, function (cb) {
  89. if (config.openDataZone) {
  90. let versionCon;
  91. if (config.version) {
  92. let versionPath = releaseDir + "/version.json";
  93. versionCon = fs.readFileSync(versionPath, "utf8");
  94. versionCon = JSON.parse(versionCon);
  95. }
  96. let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
  97. let indexPath = path.join(releaseDir, indexJsStr);
  98. let indexjs = readFile(indexPath);
  99. let gamejs = readFile(releaseDir + "/game.js");
  100. if (gamejs && indexjs) {
  101. gamejs = gamejs.replace(`require("index.js")`, indexjs);
  102. fs.writeFileSync(indexPath, gamejs, 'utf-8');
  103. }
  104. if (isOpendataProj) {
  105. // 开放域项目,将game.js删掉,发布最小包
  106. del(`${releaseDir}/game.js`, { force: true }).then(paths => {
  107. cb();
  108. });
  109. } else {
  110. cb();
  111. }
  112. } else {
  113. cb();
  114. }
  115. });
  116. function readFile(path) {
  117. if (fs.existsSync(path)) {
  118. return fs.readFileSync(path, "utf-8");
  119. }
  120. return null;
  121. }
  122. gulp.task("modifyMinJs_WX", ["openData_WX"], function() {
  123. if (config.openDataZone) {
  124. return;
  125. }
  126. // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题
  127. if (config.keepPlatformFile) {
  128. let fileJsPath = path.join(releaseDir, "game.js");
  129. let content = fs.readFileSync(fileJsPath, "utf-8");
  130. content = content.replace(/min\/laya(-[\w\d]+)?\.wxmini\.min\.js/gm, "laya.wxmini.js");
  131. fs.writeFileSync(fileJsPath, content, 'utf-8');
  132. }
  133. if (!config.useMinJsLibs) {
  134. return;
  135. }
  136. let fileJsPath = path.join(releaseDir, "game.js");
  137. let content = fs.readFileSync(fileJsPath, "utf-8");
  138. content = content.replace(/(min\/)?laya(-[\w\d]+)?\.wxmini(\.min)?\.js/gm, "min/laya.wxmini.min.js");
  139. fs.writeFileSync(fileJsPath, content, 'utf-8');
  140. });
  141. gulp.task("version_WX", ["modifyMinJs_WX"], function() {
  142. if (config.openDataZone) {
  143. return;
  144. }
  145. // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
  146. if (config.keepPlatformFile) {
  147. let fileJsPath = path.join(releaseDir, "game.js");
  148. let content = fs.readFileSync(fileJsPath, "utf-8");
  149. content = content.replace(/laya(-[\w\d]+)?\.wxmini/gm, "laya.wxmini");
  150. content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
  151. fs.writeFileSync(fileJsPath, content, 'utf-8');
  152. }
  153. if (config.version) {
  154. let versionPath = releaseDir + "/version.json";
  155. let gameJSPath = releaseDir + "/game.js";
  156. let srcList = [versionPath, gameJSPath];
  157. return gulp.src(srcList)
  158. .pipe(revCollector())
  159. .pipe(gulp.dest(releaseDir));
  160. }
  161. });
  162. gulp.task("optimizeOpen_WX", ["version_WX"], function(cb) {
  163. let wxOptimize = config.wxOptimize;
  164. if (!wxOptimize || !wxOptimize.useOptimizeOpen) { // 没有使用微信引擎插件,还是像以前一样发布
  165. return cb();
  166. }
  167. // 首屏加载优化(秒开),修改game.json
  168. let filePath = path.join(releaseDir, "game.json");
  169. if (!fs.existsSync(filePath)) {
  170. return cb();
  171. }
  172. let fileContent = fs.readFileSync(filePath, "utf8");
  173. let fileConObj = JSON.parse(fileContent);
  174. if (wxOptimize.preloadRes) {
  175. fileConObj.preloadResources = wxOptimize.preloadResList;
  176. } else {
  177. delete fileConObj.preloadResources;
  178. }
  179. if (wxOptimize.preloadSubpack) {
  180. fileConObj.preloadSubpackages = wxOptimize.preloadSubpackList;
  181. } else {
  182. delete fileConObj.preloadSubpackages;
  183. }
  184. fs.writeFileSync(filePath, JSON.stringify(fileConObj, null, 4), "utf8");
  185. return cb();
  186. });
  187. gulp.task("pluginEngin_WX", ["optimizeOpen_WX"], function(cb) {
  188. if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布
  189. let gameJsonPath = path.join(releaseDir, "game.json");
  190. if (!fs.existsSync(gameJsonPath)) {
  191. return cb();
  192. }
  193. let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
  194. let conJson = JSON.parse(gameJsonContent);
  195. if (conJson.plugins) {
  196. delete conJson.plugins;
  197. gameJsonContent = JSON.stringify(conJson, null, 4);
  198. fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
  199. let gameJsPath = path.join(releaseDir, "game.js");
  200. let gameJscontent = fs.readFileSync(gameJsPath, "utf8");
  201. gameJscontent = gameJscontent.replace(/requirePlugin\("[\w\/\.]+"\)(;|,)?\n?/mg, "");
  202. fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
  203. }
  204. return cb();
  205. }
  206. if (config.version) {
  207. let versionPath = releaseDir + "/version.json";
  208. versionCon = fs.readFileSync(versionPath, "utf8");
  209. versionCon = JSON.parse(versionCon);
  210. }
  211. let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
  212. // 获取version等信息
  213. let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js");
  214. let isHasCoreLib = fs.existsSync(coreLibPath);
  215. let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib;
  216. let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib;
  217. let EngineVersion = getEngineVersion();
  218. if (!EngineVersion) {
  219. throw new Error(`读取引擎版本号失败,请于服务提供商联系!`);
  220. }
  221. if (!EngineVersion || EngineVersion.includes("beta") || !canUsePluginEngine(EngineVersion, minPluginVersion)) {
  222. throw new Error(`该版本引擎无法使用引擎插件功能(engineVersion: ${EngineVersion})`);
  223. }
  224. console.log(`通过版本号检查: ${EngineVersion}`);
  225. // 使用引擎插件
  226. let localUseEngineList = [];
  227. let copyEnginePathList;
  228. new Promise(function(resolve, reject) {
  229. console.log(`修改game.js和game.json`);
  230. // 1) 修改game.js和game.json
  231. // 修改game.js
  232. let gameJsPath = path.join(releaseDir, "game.js");
  233. let platformJs = config.useMinJsLibs ? `require("./libs/min/laya.wxmini.min.js");` : `require("./libs/laya.wxmini.js");`;
  234. let gameJscontent = `require("weapp-adapter.js");\n${platformJs}\nrequirePlugin("layaPlugin");\nwindow.loadLib = require;\nrequire("./${indexJsStr}");`;
  235. fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
  236. // 修改game.json,使其支持引擎插件
  237. let gameJsonPath = path.join(releaseDir, "game.json");
  238. let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
  239. let conJson = JSON.parse(gameJsonContent);
  240. conJson.plugins = {
  241. "layaPlugin": {
  242. "version": EngineVersion,
  243. "provider": provider,
  244. "path": "laya-libs"
  245. }
  246. }
  247. gameJsonContent = JSON.stringify(conJson, null, 4);
  248. fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
  249. resolve();
  250. }).then(function() {
  251. return new Promise(function(resolve, reject) {
  252. console.log(`确定用到的插件引擎`);
  253. // 2) 确定用到了那些插件引擎,并将插件引擎从index.js的引用中去掉
  254. let indexJsPath = path.join(releaseDir, indexJsStr);
  255. let indexJsCon = fs.readFileSync(indexJsPath, "utf8");
  256. let item, fullRequireItem;
  257. for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) {
  258. item = fullRemoteEngineList[i];
  259. fullRequireItem = config.useMinJsLibs ? `loadLib("libs/min/${item}")` : `loadLib("libs/${item}")`;
  260. if (indexJsCon.includes(fullRequireItem)) {
  261. let _item = item.replace(".min.js", ".js"), _minItem = item;
  262. localUseEngineList.push(_item);
  263. indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
  264. // 如果引用了压缩的类库,将其重命名为未压缩的类库,并拷贝到libs中
  265. if (config.useMinJsLibs) {
  266. let oldMinlibPath = path.join(releaseDir, "libs", "min", _minItem);
  267. let newMinlibPath = path.join(releaseDir, "libs", "min", _item);
  268. let newlibPath = path.join(releaseDir, "libs", _item);
  269. fs.renameSync(oldMinlibPath, newMinlibPath);
  270. // fs.copyFileSync(newlibPath, newMinlibPath);
  271. let con = fs.readFileSync(newMinlibPath, "utf8");
  272. fs.writeFileSync(newlibPath, con, "utf8");
  273. fs.unlinkSync(newMinlibPath);
  274. }
  275. }
  276. }
  277. if (isOldAsProj || isNewTsProj) { // 如果as||ts_new语言,开发者将laya.js也写入index.js中了,将其删掉
  278. fullRequireItem = `loadLib("laya.js")`;
  279. if (indexJsCon.includes(fullRequireItem)) {
  280. indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
  281. }
  282. }
  283. fs.writeFileSync(indexJsPath, indexJsCon, "utf8");
  284. // ts/js再次修改game.js,仅引用使用到的类库
  285. // as||ts_new因为本地只有laya.js,无法仅引用使用到的类库
  286. if (!isOldAsProj && !isNewTsProj) {
  287. let pluginCon = "";
  288. localUseEngineList.forEach(function(item) {
  289. pluginCon += `requirePlugin("layaPlugin/${item}");\n`;
  290. });
  291. let gameJsPath = path.join(releaseDir, "game.js");
  292. let gameJsCon = fs.readFileSync(gameJsPath, "utf8");
  293. gameJsCon = gameJsCon.replace(`requirePlugin("layaPlugin");`, pluginCon);
  294. fs.writeFileSync(gameJsPath, gameJsCon, "utf8");
  295. }
  296. resolve();
  297. });
  298. }).then(function() {
  299. return new Promise(function(resolve, reject) {
  300. console.log(`将本地的引擎插件移动到laya-libs中`);
  301. // 3) 将本地的引擎插件移动到laya-libs中
  302. let libsPath = /** config.useMinJsLibs ? `${releaseDir}/libs/min` : */`${releaseDir}/libs`;
  303. copyEnginePathList = [`${libsPath}/{${localUseEngineList.join(",")}}`];
  304. if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
  305. copyEnginePathList = [`${releaseDir}/laya.js`];
  306. }
  307. gulp.src(copyEnginePathList).pipe(gulp.dest(`${releaseDir}/laya-libs`));
  308. setTimeout(resolve, 500);
  309. });
  310. }).then(function() {
  311. return new Promise(function(resolve, reject) {
  312. console.log(`将libs中的本地引擎插件删掉`);
  313. // 4) 将libs中的本地引擎插件删掉
  314. del(copyEnginePathList, { force: true }).then(resolve);
  315. });
  316. }).then(function() {
  317. return new Promise(async function(resolve, reject) {
  318. console.log(`完善引擎插件目录`);
  319. // 5) 引擎插件目录laya-libs中还需要新建几个文件,使该目录能够使用
  320. if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
  321. localUseEngineList.push("laya.js");
  322. }
  323. let
  324. layalibsPath = path.join(releaseDir, "laya-libs"),
  325. engineIndex = path.join(layalibsPath, "index.js"),
  326. engineplugin = path.join(layalibsPath, "plugin.json"),
  327. enginesignature = path.join(layalibsPath, "signature.json");
  328. // index.js
  329. if (!fs.existsSync(layalibsPath)) {
  330. throw new Error("引擎插件目录创建失败,请与服务提供商联系!");
  331. }
  332. let indexCon = "";
  333. localUseEngineList.forEach(function(item) {
  334. indexCon += `require("./${item}");\n`;
  335. });
  336. fs.writeFileSync(engineIndex, indexCon, "utf8");
  337. // plugin.json
  338. let pluginCon = {"main": "index.js"};
  339. fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8");
  340. // signature.json,目前平台方将其作为保留用途,不会做插件的md5校验;IDE仍将生成md5
  341. let signatureCon = {
  342. "provider": provider,
  343. "signature": []
  344. };
  345. localUseEngineList.unshift("index.js");
  346. let fileName, md5Str;
  347. for (let i = 0, len = localUseEngineList.length; i < len; i++) {
  348. fileName = localUseEngineList[i];
  349. let md5Str = await getFileMd5(path.join(releaseDir, "laya-libs", fileName));
  350. signatureCon.signature.push({
  351. "path": fileName,
  352. "md5": md5Str
  353. });
  354. }
  355. fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8");
  356. resolve();
  357. });
  358. })
  359. .then(function() {
  360. cb();
  361. }).catch(function(e) {
  362. throw e;
  363. })
  364. });
  365. gulp.task("buildWXProj", ["pluginEngin_WX"], function() {
  366. console.log("all tasks completed");
  367. });