UNPKG

@honor-minigame/cli

Version:

honor minigame pack cli

106 lines (95 loc) 3.91 kB
import fs from 'fs-extra' import path from 'path' import { fileURLToPath } from 'url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) // CLI 自身 common 目录(修复文件源) const COMMON_DIR = path.join(__dirname, '../common') // cocos2.x 运行时崩溃修复文件(运行时 monkey-patch,不改引擎文件): // image-load-fix.js —— 修复 internal://files/ 协议头图片加载 ERROR 4930(黑屏卡死) // renderflow-fix.js —— 修复 RenderFlow _assembler 空引用崩溃 const COCOS2X_FIX_FILES = ['image-load-fix.js', 'renderflow-fix.js'] // boot.js 注入锚点:require('adapter/index.js'); 行 // 兼容行首缩进、单/双引号、可选分号、行尾注释及 \r\n 换行 const ADAPTER_INDEX_REQUIRE = /([ \t]*require\(\s*['"]adapter\/index\.js['"]\s*\)\s*;?[^\n]*\r?\n)/ /** * 判断是否为 cocos2.x 游戏 * 与 utils/engineType.js 中 cocos2.x 判断一致:src/cocos2d-runtime.js 存在即 cocos2.x * (cocos3.x 使用 src/settings.json 的 CocosEngine 字段,不会有 cocos2d-runtime.js) * @param {string} rootPath 项目根目录 * @returns {boolean} */ function isCocos2x(rootPath) { return fs.existsSync(path.join(rootPath, 'src', 'cocos2d-runtime.js')) } /** * 定位项目中的 adapter 目录(包含 index.js 的那个) * boot.js 中 require('adapter/index.js') 的解析位置,优先 src/adapter,回退项目根 adapter * @param {string} rootPath 项目根目录 * @returns {string|null} */ function resolveAdapterDir(rootPath) { const candidates = [ path.join(rootPath, 'src', 'adapter'), path.join(rootPath, 'adapter') ] for (const dir of candidates) { if (fs.existsSync(path.join(dir, 'index.js'))) { return dir } } return null } /** * cocos2.x 运行时崩溃适配注入 * * 触发条件:cocos2.x 游戏(src/cocos2d-runtime.js 存在)且 src/boot.js 存在。 * 做两件事: * 1. 将 common/image-load-fix.js、common/renderflow-fix.js 复制到 adapter/ 下; * 2. 在 boot.js 的 require('adapter/index.js'); 下方追加这两个文件的 require。 * * 两个修复文件内部均已用 cc.game.once(EVENT_GAME_INITED, apply) 兜底, * 即便在 cocos2d-runtime.js 之前被 require,引擎初始化后仍会补 patch,故放在 * require('adapter/index.js') 下方是安全的。 * * @param {string} rootPath 项目根目录 */ export function injectCocos2xRuntimeFix(rootPath) { if (!isCocos2x(rootPath)) { return } const bootJsPath = path.join(rootPath, 'src', 'boot.js') if (!fs.existsSync(bootJsPath)) { return } const adapterDir = resolveAdapterDir(rootPath) if (!adapterDir) { console.warn('### HONOR PACK ### 未找到 adapter/index.js,跳过 cocos2.x 运行时修复注入') return } // 1. 复制修复文件到 adapter 目录 COCOS2X_FIX_FILES.forEach((file) => { const src = path.join(COMMON_DIR, file) const dest = path.join(adapterDir, file) fs.copySync(src, dest) }) // 2. 在 boot.js 的 require('adapter/index.js'); 下方注入两个 require let bootContent = fs.readFileSync(bootJsPath, 'utf8') // 防重复:已注入则跳过 if (bootContent.indexOf("require('adapter/image-load-fix.js')") > -1) { return } if (!ADAPTER_INDEX_REQUIRE.test(bootContent)) { console.warn("### HONOR PACK ### boot.js 中未找到 require('adapter/index.js') 锚点,跳过注入") return } bootContent = bootContent.replace(ADAPTER_INDEX_REQUIRE, (match) => { // 继承锚点行的缩进,保持 boot.js 风格一致 const indent = (match.match(/^[ \t]*/) || [''])[0] const injectLines = `${indent}require('adapter/image-load-fix.js');\n` + `${indent}require('adapter/renderflow-fix.js');\n` return match + injectLines }) fs.writeFileSync(bootJsPath, bootContent, 'utf8') }