UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

414 lines (360 loc) 23.6 kB
"use strict";var _typeof = require("@babel/runtime-corejs2/helpers/typeof");var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");var _WeakMap = require("@babel/runtime-corejs2/core-js/weak-map");var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");_Object$defineProperty(exports, "__esModule", { value: true });exports.release = exports.build = void 0;var _create = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/create"));var _parseFloat2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-float"));var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));var _path = _interopRequireDefault(require("path")); var _index = require("../cli-shared-utils/index.js"); var _http = _interopRequireDefault(require("http")); var _process = require("./config/process.js"); var paths = _interopRequireWildcard(require("./lib/paths.js")); var _manifest = require("./lib/manifest.js"); var _constanst = require("./lib/constanst.js"); var _subpackage = require("./lib/subpackage.js"); var _zipPack = _interopRequireDefault(require("./lib/zipPack.js")); var _fsUtils = require("../cli-shared-utils/lib/fsUtils"); var _index2 = _interopRequireDefault(require("./webpack/lib/index.js"));function _getRequireWildcardCache(e) {if ("function" != typeof _WeakMap) return null;var r = new _WeakMap(),t = new _WeakMap();return (_getRequireWildcardCache = function _getRequireWildcardCache(e) {return e ? t : r;})(e);}function _interopRequireWildcard(e, r) {if (!r && e && e.__esModule) return e;if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e };var t = _getRequireWildcardCache(r);if (t && t.has(e)) return t.get(e);var n = { __proto__: null },a = _Object$defineProperty && _Object$getOwnPropertyDescriptor;for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) {var i = a ? _Object$getOwnPropertyDescriptor(e, u) : null;i && (i.get || i.set) ? _Object$defineProperty(n, u, i) : n[u] = e[u];}return n["default"] = e, t && t.set(e, n), n;}function ownKeys(e, r) {var t = _Object$keys(e);if (_Object$getOwnPropertySymbols) {var o = _Object$getOwnPropertySymbols(e);r && (o = o.filter(function (r) {return _Object$getOwnPropertyDescriptor(e, r).enumerable;})), t.push.apply(t, o);}return t;}function _objectSpread(e) {for (var r = 1; r < arguments.length; r++) {var t = null != arguments[r] ? arguments[r] : {};r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {(0, _defineProperty2["default"])(e, r, t[r]);}) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {_Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r));});}return e;} /** * 将webpack源码引入进来解决动态编译问题,修改lib\ContextModule.js * 1、__webpack_require__.webpackContext = webpackContext,将webpackContext赋值给__webpack_require__ * 2、修改webpackEmptyContext,if (__webpack_require__.webpackContext.resolve(req)),若存在已编译的路径,则直接运行 **/ /** * 发布构建 * * @param {Object} args - 构建参数 * @returns {Promise<Object>} 构建结果 */var release = exports.release = /*#__PURE__*/function () {var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(args) {return _regenerator["default"].wrap(function _callee$(_context) {while (1) switch (_context.prev = _context.next) {case 0:return _context.abrupt("return", build(_objectSpread(_objectSpread({}, args), {}, { isRelease: true, buildType: 'release' }) ));case 1:case "end":return _context.stop();}}, _callee);}));return function release(_x) {return _ref.apply(this, arguments);};}(); /** * 构建项目包 * * @param {Object} options - 构建选项 * @param {boolean} [options.isRelease=false] - 是否为发布版本 * @param {boolean} [options.inject=true] - 是否注入依赖 * @param {string} [options.buildType] - 构建类型 * @param {function} [options.complete=() => {}] - 构建完成后的回调函数 * @param {boolean} [options.amd=true] - 是否使用AMD模块 * @param {boolean} [options.rpk=false] - 是否使用RPK打包 * @returns {Promise<void>} 无返回值 */ var build = exports.build = /*#__PURE__*/function () {var _ref3 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(_ref2) {var _ref2$isRelease, isRelease, _ref2$inject, inject, buildType, _ref2$complete, complete, _ref2$amd, amd, _ref2$rpk, rpk, manifest, subpackages, _toConfigs, entry, externals, isMain, packageName, rpkStartTime, singleCompiler, _singleDone, doneNext;return _regenerator["default"].wrap(function _callee2$(_context2) {while (1) switch (_context2.prev = _context2.next) {case 0:_ref2$isRelease = _ref2.isRelease, isRelease = _ref2$isRelease === void 0 ? false : _ref2$isRelease, _ref2$inject = _ref2.inject, inject = _ref2$inject === void 0 ? true : _ref2$inject, buildType = _ref2.buildType, _ref2$complete = _ref2.complete, complete = _ref2$complete === void 0 ? function () {} : _ref2$complete, _ref2$amd = _ref2.amd, amd = _ref2$amd === void 0 ? true : _ref2$amd, _ref2$rpk = _ref2.rpk, rpk = _ref2$rpk === void 0 ? false : _ref2$rpk; // 校验manifest (0, _manifest.check)(); // 校验通过后,可以清空编译目录 _index.fs.removeSync(paths.BUILD); _index.fs.removeSync(paths.DIST); // TODO 开发需要看temp里面的包,方便测试,上线后去掉 _index.fs.removeSync(paths.TEMP); // 读取manifest配置 manifest = (0, _manifest.get)(); // 添加manifest配置 buildType if (buildType) { (0, _manifest.add)('buildType', buildType); } else { (0, _manifest.add)('buildType', 'dev'); } // 过滤出合法的分包配置 subpackages = (0, _subpackage.filter)(manifest.subpackages); // 将分包配置转化为对应的webpack的打包入口 // 将分包配置转化为对应的externals用于打出兼容的原整包 _toConfigs = (0, _subpackage.toConfigs)(subpackages), entry = _toConfigs.entry, externals = _toConfigs.externals, isMain = _toConfigs.isMain; // 对分包名称判断 不能为main if (!isMain) {_context2.next = 12;break;} (0, _index.error)('请检查分包的配置,分包名称不能为main,请修改分包名称');return _context2.abrupt("return");case 12: // 取出包名 packageName = manifest["package"] || 'Bundle'; rpkStartTime = new Date().valueOf(); // 如果配置了rpk,则直接将src目录copy到build目录并压缩 if (!rpk) {_context2.next = 17;break;} rpkZip(isRelease, packageName, subpackages, manifest, buildType, rpkStartTime, complete);return _context2.abrupt("return");case 17: // 先打原整包 singleCompiler = (0, _index2["default"])((0, _process.singleConfig)(entry, isRelease, externals, inject, amd)); /** * 编译原整包的完成处理函数 * @param {Object} err * @param {Object} stats */ _singleDone = function singleDone(err, stats) { if ((0, _process.checkError)(err, stats)) return; // 如果存在未使用的模块,则将所有未使用的模块作为入口重新webpack打包 if (paths.unUsedFiles.length !== 0) { (0, _index.info)("paths.unUsedFiles \u5B58\u5728\u672A\u5F15\u5165\u7684\u6587\u4EF6\u91CD\u65B0\u6253\u5305\uFF0Cmodule: ".concat(paths.unUsedFiles)); var _entry = (0, _create["default"])(null); paths.unUsedFiles.forEach(function (unUsedFile) { var filePath = _path["default"].resolve(paths.BUILD, unUsedFile); if (_index.fs.existsSync(filePath)) { var parsedPath = _path["default"].parse(unUsedFile); var entryKey = _path["default"].join(parsedPath.dir, parsedPath.name); _entry[entryKey] = filePath; } }); paths.unUsedFiles = []; var compiler = (0, _index2["default"])((0, _process.base)(isRelease, _entry, amd)); compiler.run(_singleDone); return; } var compileStartTime = new Date().valueOf(); var promise = (0, _zipPack["default"])(isRelease, packageName, true, subpackages, manifest, buildType, compileStartTime); promise.then(function (resolve) { doneNext(); }); }; // 等待原整包打包完成再继续编译 doneNext = function doneNext() { (0, _index.info)("".concat(_constanst.LOG_TITLE, "\u539F\u6574\u5305\u6253\u5305\u5B8C\u6210\uFF01 \u8017\u65F6: ").concat((new Date().valueOf() - rpkStartTime) / 1000, "s")); // 原整包打包完成后,判断是否存在分包配置,如果有就编译分包,如果没有,拷贝原整包作为最终的输出包 if (subpackages.length) { // 原整包打包完成后,开始打分包 (0, _index.info)("".concat(_constanst.LOG_TITLE, "\u5F00\u59CB\u7F16\u8BD1\u5206\u5305...")); (0, _index2["default"])((0, _process.multiConfig)(entry, isRelease, packageName, externals, subpackages, manifest, buildType, amd), function (err, stats) { if ((0, _process.checkError)(err, stats)) return; (0, _index.info)("".concat(_constanst.LOG_TITLE, "\u603B\u5305\u6253\u5305\u5B8C\u6210\uFF01 \u603B\u8017\u65F6: ").concat((new Date().valueOf() - rpkStartTime) / 1000, "s")); _final(packageName, complete, rpkStartTime); }); } else { // 不分包不带插件包的 才走这个逻辑 // 不分包的带插件包的打包已经在webpack插件里面做了 var temp = _path["default"].join(paths.TEMP, "".concat(packageName).concat(_constanst.RPK)); var dist = _path["default"].join(paths.DIST, "".concat(packageName).concat(isRelease ? _constanst.RPK_SIGNED : _constanst.RPK)); _index.fs.copy(temp, dist).then(function () { _final(packageName, complete, rpkStartTime); })["catch"](function (err) { (0, _index.error)(err); }); } }; (0, _index.info)("".concat(_constanst.LOG_TITLE, "\u5F00\u59CB\u7F16\u8BD1\u539F\u6574\u5305...")); singleCompiler.run(_singleDone);case 22:case "end":return _context2.stop();}}, _callee2);}));return function build(_x2) {return _ref3.apply(this, arguments);};}(); // 全部结束后的处理函数 var _final = function _final(packageName, complete, rpkStartTime) { complete(); (0, _index.done)("".concat(_constanst.LOG_TITLE, "\u3010\u7EDF\u4E00rpk\u3011\u538B\u7F29\u5305\u5DF2\u751F\u6210:").concat(paths.DIST, " ").concat((new Date().valueOf() - rpkStartTime) / 1000, "s")); // 打印包体信息 logRpk(packageName); // 通知引擎自动更新包 notify(); }; function logRpk(packageName) { // 打印包体信息 try { (0, _index.done)("\u3010\u7EDF\u4E00rpk\u3011\u6253\u5305\u5B8C\u6210\uFF0C\u5305\u4F53\u4FE1\u606F\u5982\u4E0B\uFF1A\n"); var files = _index.fs.readdirSync(paths.TEMP); var subAllSize = 0; var subSize = 0; var mainSize = 0; var fileInfoArray = files.map(function (file) { if (file.endsWith('.rpk')) { var filePath = _path["default"].resolve(paths.TEMP, file); var stats = _index.fs.statSync(filePath); var size = Number(stats.size / 1024 / 1024).toFixed(3); size = size > 1 ? Number(size).toFixed(1) : size; var fileName = file.split('.rpk')[0]; // 包体名称 var name = fileName === 'main' ? '主包' : "\u5206\u5305/".concat(fileName); name = fileName === packageName ? '原整包' : name; name = fileName === 'cocos-library' || fileName === 'laya-library' || fileName === 'egret-library' ? "\u63D2\u4EF6\u5305" : name; // 分包size加到一起 if (name.startsWith('分包')) { subAllSize += (0, _parseFloat2["default"])(size); subSize++; } if (name === '主包') { mainSize = size; } return { name: name, file: file, size: "".concat(size, " MB") }; } }).filter(function (fileInfo) {return fileInfo !== undefined;}); if (fileInfoArray.length === 1) { var _files = _index.fs.readdirSync(paths.DIST); fileInfoArray = _files.map(function (file) { if (file.endsWith('.rpk')) { var fileName = file.split('.rpk')[0]; if (fileName.includes(packageName)) { var filePath = _path["default"].resolve(paths.DIST, file); var stats = _index.fs.statSync(filePath); var size = Number(stats.size / 1024 / 1024).toFixed(3); size = size > 1 ? Number(size).toFixed(1) : size; return { name: 'dist/整包', file: file, size: "".concat(size, " MB") }; } } }).filter(function (fileInfo) {return fileInfo !== undefined;}); } else { var _files2 = _index.fs.readdirSync(paths.DIST); var fileDistArray = _files2.map(function (file) { if (file.endsWith('.rpk')) { var fileName = file.split('.rpk')[0]; if (fileName.includes(packageName)) { var filePath = _path["default"].resolve(paths.DIST, file); var stats = _index.fs.statSync(filePath); var size = Number(stats.size / 1024 / 1024).toFixed(3); size = size > 1 ? Number(size).toFixed(1) : size; return { name: 'dist/整包', file: file, size: "".concat(size, " MB") }; } } }).filter(function (fileInfo) {return fileInfo !== undefined;}); if (subAllSize !== 0) { fileInfoArray.push({ name: '所有分包', file: "".concat(subSize, "\u4E2A"), size: "".concat(Number(subAllSize).toFixed(3), " MB") }); } var sortOrder = new _map["default"]([ ['原整包', 1], ['主包', 2], ['插件包', 3], ['所有分包', 4]] ); fileInfoArray.sort(function (a, b) { if (sortOrder.get(a.name) && sortOrder.get(b.name)) { return sortOrder.get(a.name) - sortOrder.get(b.name); } if (sortOrder.get(a.name)) { return -1; } if (sortOrder.get(b.name)) { return 1; } var sizeA = (0, _parseFloat2["default"])(a.size.split('MB')[0]); var sizeB = (0, _parseFloat2["default"])(b.size.split('MB')[0]); // 先按文件大小排序 if (sizeA !== sizeB) { return sizeB - sizeA; } else { return b.file.localeCompare(a.file); } }); fileInfoArray = fileDistArray.concat(fileInfoArray); } console.log(fileInfoArray.map(function (obj) {return (0, _values["default"])(obj);})); if (fileInfoArray.length === 1) { console.info("\n### \u5F00\u5E73\u4F1A\u6821\u9A8C\u5355\u4E2A\u6574\u5305\u5927\u5C0F\uFF1A".concat(fileInfoArray[0].size)); } else if (mainSize !== 0 && subAllSize !== 0) { console.info("\n### \u5F00\u5E73\u53EA\u4F1A\u6821\u9A8C \u4E3B\u5305main.rpk\u5927\u5C0F\uFF1A".concat(mainSize, " MB, \u6240\u6709\u5206\u5305\u5927\u5C0F\uFF1A").concat(Number(subAllSize).toFixed(3), " MB")); } console.log('\n'); } catch (err) { } } function notify() { try { (0, _index.info)("### App Server ### \u53D1\u9001\u66F4\u65B0\u901A\u77E5\u8BF7\u6C42"); var json = _index.fs.readJsonSync(_path["default"].resolve(_index.projectPath, 'client.json')); console.log(json); // 给游戏前台发送更新通知 var gameRequrl = "http://".concat(json.client, ":49517/update"); var reqGame = _http["default"].request({ host: json.client, port: 49517, path: '/update', timeout: 2000 }, function (res) { (0, _index.info)("### App Server ### \u7ED9\u5F15\u64CE\u53D1\u9001\u66F4\u65B0\u901A\u77E5\u8BF7\u6C42: ".concat(gameRequrl, " \u6210\u529F")); }).on('error', function () { (0, _index.info)("### App Server ### \u7ED9\u5F15\u64CE\u53D1\u9001\u66F4\u65B0\u901A\u77E5\u8BF7\u6C42: ".concat(gameRequrl, " \u5931\u8D25")); // 给调试器发送 var requrl = "http://".concat(json.client, ":39517/update"); var req = _http["default"].request({ host: json.client, port: 39517, path: '/update', timeout: 2000 }, function (res) { (0, _index.info)("### App Server ### \u53D1\u9001\u81EA\u52A8\u66F4\u65B0\u8C03\u8BD5\u5668\u5668\u8BF7\u6C42: ".concat(requrl, " \u6210\u529F")); }).on('error', function () { // error(`### App Server ### 发送自动更新调试器请求: ${requrl} 失败: ${err.message}`) }).on('timeout', function () {// error(`### App Server ### 发送自动更新调试器请求: ${requrl} 超时: 3000ms`) req.abort(); }); req.end(); }).on('timeout', function () { (0, _index.info)("### App Server ### \u7ED9\u5F15\u64CE\u53D1\u9001\u66F4\u65B0\u901A\u77E5\u8BF7\u6C42: ".concat(gameRequrl, " \u8D85\u65F6: 3000ms")); reqGame.abort(); }); reqGame.end(); } catch (error) { (0, _index.info)("### App Server ### \u6CA1\u627E\u5230client\u4FE1\u606F"); } } /** * 不使用webpack直接压缩打包联盟RPK文件 * * @param {boolean} isRelease - 是否为发布版本 * @param {string} packageName - 包的名称 * @param {Array} subpackages - 分包配置 * @param {Object} manifest - 包的清单文件 * @param {string} buildType - 构建类型 * @param {number} rpkStartTime - RPK打包开始时间 * @param {function} complete - 打包完成后的回调函数 * @returns {Promise} 返回一个Promise,表示打包过程的状态 */ var rpkZip = function rpkZip(isRelease, packageName, subpackages, manifest, buildType, rpkStartTime, complete) { // copy src目录下文件到build目录 _fsUtils.fsExt.overwrite(paths.SRC, paths.BUILD); // 联盟包体处理 // 联盟适配转换代码 var needTransferAlliance = true; var vivoAllianceAdapterJS = 'vivo_alliance_adapter'; var gameContent = _index.fs.readFileSync(_path["default"].resolve(paths.BUILD, './game.js'), { encoding: 'utf-8' }); if (gameContent.includes(vivoAllianceAdapterJS)) { needTransferAlliance = false; (0, _index.info)('game.js 包含联盟 vivo_alliance_adapter.js 转换代码,不进行二次转换...'); } if (needTransferAlliance) { (0, _index.info)('开始写入联盟转换代码...'); // 生成 main.js文件,引入 game.js,作为适配联盟api的入口 if (_index.fs.existsSync(_path["default"].resolve(paths.BUILD, './main.js'))) { (0, _index.info)('main.js为入口文件,不允许作为业务文件引入进来,如果游戏有报错,请修改文件名,重新打包'); var content = _index.fs.readFileSync(_path["default"].resolve(paths.BUILD, './main.js'), { encoding: 'utf-8' }); // 判断build是否包含适配文件 var allianceJs = _path["default"].resolve(paths.BUILD, './vivo_alliance_adapter.js'); if (!_index.fs.existsSync(allianceJs)) { var _allianceJs = _path["default"].join(__dirname, './plugins/alliance_adapter/vivo_alliance_adapter.js'); _index.fs.copyFileSync(_allianceJs, _path["default"].resolve(paths.BUILD, './vivo_alliance_adapter.js')); } // 判断main.js是否已引入适配js if (!content.includes(vivoAllianceAdapterJS)) { // 重新写入vivo_alliance_adapter var allianceAdapterContent = 'require(\'vivo_alliance_adapter.js\');\n'; _index.fs.outputFileSync(_path["default"].resolve(paths.BUILD, './main.js'), allianceAdapterContent + content, 'utf8'); } } else { var _allianceJs2 = _path["default"].join(__dirname, './plugins/alliance_adapter/vivo_alliance_adapter.js'); _index.fs.copyFileSync(_allianceJs2, _path["default"].resolve(paths.BUILD, './vivo_alliance_adapter.js')); _index.fs.outputFileSync(_path["default"].resolve(paths.BUILD, './main.js'), 'require(\'vivo_alliance_adapter.js\');\nrequire("game.js");', 'utf8'); } } else { // 生成 main.js文件,引入 game.js,作为适配联盟api的入口 if (_index.fs.existsSync(_path["default"].resolve(paths.BUILD, './main.js'))) { (0, _index.info)('main.js为入口文件,不允许作为业务文件引入进来,如果游戏有报错,请修改文件名,重新打包'); // throw new Error() } else { _index.fs.outputFileSync(_path["default"].resolve(paths.BUILD, './main.js'), 'require("game.js");', 'utf8'); } } // 打包原整包 var compileStartTime = new Date().valueOf(); var promise = (0, _zipPack["default"])(isRelease, packageName, true, subpackages, manifest, buildType, compileStartTime); promise.then(function (resolve) { doneNext(); }); // 等待原整包打包完成再继续编译 var doneNext = function doneNext() { (0, _index.info)("".concat(_constanst.LOG_TITLE, "\u539F\u6574\u5305\u6253\u5305\u5B8C\u6210\uFF01 \u8017\u65F6: ").concat((new Date().valueOf() - rpkStartTime) / 1000, "s")); // 原整包打包完成后,判断是否存在分包配置,如果有就编译分包,如果没有,拷贝原整包作为最终的输出包 if (subpackages.length) { // 原整包打包完成后,开始打分包 (0, _index.info)("".concat(_constanst.LOG_TITLE, "\u5F00\u59CB\u7F16\u8BD1\u5206\u5305...")); var _compileStartTime = new Date().valueOf(); var _promise = (0, _zipPack["default"])(isRelease, packageName, false, subpackages, manifest, buildType, _compileStartTime); _promise.then(function (resolve) { _final(packageName, complete, rpkStartTime); }); } else { var temp = _path["default"].join(paths.TEMP, "".concat(packageName).concat(_constanst.RPK)); var dist = _path["default"].join(paths.DIST, "".concat(packageName).concat(isRelease ? _constanst.RPK_SIGNED : _constanst.RPK)); _index.fs.copy(temp, dist).then(function () { _final(packageName, complete, rpkStartTime); })["catch"](function (err) { (0, _index.error)(err); }); } }; };