const fs = require('fs');
const pathUtils = require('path');
const { parse } = require('@babel/parser');
const { default: traverse } = require('@babel/traverse');
const { default: generate } = require('@babel/generator');
// ==========================================
// 1. 配置路径
// ==========================================
const filePath = 'D:\游戏\cocos\wechatgame_\assets\main\index.js';
const directoryPath = pathUtils.join(pathUtils.dirname(filePath), 'out');
if (!fs.existsSync(directoryPath)) {
fs.mkdirSync(directoryPath, { recursive: true });
}
// ==========================================
// 2. 内置 Cocos Creator UUID 解压工具
// ==========================================
const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const BASE64_VALUES = new Array(123);
for (let i = 0; i < BASE64_CHARS.length; i++) {
BASE64_VALUES[BASE64_CHARS.charCodeAt(i)] = i;
}
const HexChars = '0123456789abcdef'.split('');
function decompressUuid(uuid) {
if (!uuid || uuid.length !== 22) {
return uuid;
}
let res = [];
let i = 0;
let j = 0;
while (i < 22) {
let b1 = BASE64_VALUES[uuid.charCodeAt(i++)];
let b2 = BASE64_VALUES[uuid.charCodeAt(i++)];
let b3 = BASE64_VALUES[uuid.charCodeAt(i++)];
let b4 = BASE64_VALUES[uuid.charCodeAt(i++)];
let d1 = (b1 << 2) | (b2 >> 4);
let d2 = ((b2 & 15) << 4) | (b3 >> 2);
let d3 = ((b3 & 3) << 6) | b4;
res[j++] = HexChars[d1 >> 4]; res[j++] = HexChars[d1 & 15];
res[j++] = HexChars[d2 >> 4]; res[j++] = HexChars[d2 & 15];
res[j++] = HexChars[d3 >> 4]; res[j++] = HexChars[d3 & 15];
}
let str = res.join('');
return str.slice(0, 8) + '-' + str.slice(8, 12) + '-' + str.slice(12, 16) + '-' + str.slice(16, 20) + '-' + str.slice(20, 32);
}
// ==========================================
// 3. 核心处理逻辑 (完美修复版)
// ==========================================
function separateFunctionsInFile(filePath) {
const fileContent = fs.readFileSync(filePath, 'utf8');
const ast = parse(fileContent, { sourceType: 'module' });
// 1. 最外层全局遍历
traverse(ast, {
ObjectProperty(path) {
const { node } = path;
if (
node.value.type === 'ArrayExpression' &&
node.value.elements.length > 0 &&
node.value.elements[0].type === 'FunctionExpression'
) {
let funcName = '';
if (node.key.type === 'Identifier') funcName = node.key.name;
else if (node.key.type === 'StringLiteral') funcName = node.key.value;
if (funcName) {
const funcNode = node.value.elements[0];
let extractedUuid = null;
const param1 = funcNode.params[0] ? funcNode.params[0].name : 'require';
// 2. 对当前这个对象节点进行局部向下扫描,完美规避独立 traverse 报错,也不会误跳过
path.traverse({
CallExpression(innerPath) {
const innerNode = innerPath.node;
// 提取 UUID 并移除 cc._RF.push
if (
innerNode.callee.type === 'MemberExpression' &&
innerNode.callee.object.type === 'MemberExpression' &&
innerNode.callee.object.object.name === 'cc' &&
innerNode.callee.object.property.name === '_RF'
) {
if (innerNode.arguments.length >= 2 && innerNode.arguments[1].type === 'StringLiteral') {
extractedUuid = innerNode.arguments[1].value; // 抓取到了 UUID
}
if (innerPath.parentPath.isExpressionStatement()) {
innerPath.parentPath.remove();
} else {
innerPath.remove();
}
return;
}
// 修改 require 路径
if (
innerNode.callee.type === 'Identifier' &&
innerNode.callee.name === param1 &&
innerNode.arguments.length === 1 &&
innerNode.arguments[0].type === 'StringLiteral'
) {
const requirePath = innerNode.arguments[0].value;
innerNode.arguments[0].value = pathUtils.basename(requirePath);
}
},
// 处理特殊字符串
StringLiteral(innerPath) {
const innerNode = innerPath.node;
if (innerNode.extra && innerNode.extra.raw && innerNode.extra.raw.includes('\\u')) {
let value = innerNode.value;
if (value.includes('\r') || value.includes('\n')) {
value = value.replace(/\r/g, '\\r').replace(/\n/g, '\\n');
}
innerNode.extra.raw = `"${value}"`;
}
}
});
// 3. 将修改好的函数导出
exportFunctionCode(funcNode, funcName, extractedUuid);
}
}
}
});
}
/**
- 导出 JS 和 Meta
*/
function exportFunctionCode(funcNode, funcName, extractedUuid) {
const funcParams = funcNode.params.map((param) => param.name);
const paramAssignments = funcParams
.map((param, index) => {
const assignment = index === 0 ? 'require' : index === 1 ? 'module' : 'exports';
return var ${param} = ${assignment};;
})
.join('\n');
const bodyCode = funcNode.body.body.map((node) => generate(node).code).join('\n');
const modifiedCode = ${paramAssignments}\n${bodyCode};
const outJsPath = pathUtils.join(directoryPath, ${funcName}.js);
fs.writeFileSync(outJsPath, modifiedCode, 'utf8');
// 如果抓到了 UUID,就生成 Meta
if (extractedUuid) {
saveMeta(funcName, extractedUuid);
}
}
/**
- 生成 Meta 文件实体
*/
function saveMeta(funcName, uuidValue) {
const deuuid = decompressUuid(uuidValue);
const jsonData = {
ver: '1.1.0',
uuid: deuuid,
importer: 'javascript',
isPlugin: false,
loadPluginInWeb: true,
loadPluginInNative: true,
loadPluginInEditor: false,
subMetas: {},
};
const jsonString = JSON.stringify(jsonData, null, 2);
const outMetaPath = pathUtils.join(directoryPath, ${funcName}.js.meta);
fs.writeFileSync(outMetaPath, jsonString, 'utf8');
}
// ==========================================
// 4. 执行
// ==========================================
separateFunctionsInFile(filePath);
console.log('✨ 导出成功!:', directoryPath);`
const fs = require('fs');
const pathUtils = require('path');
const { parse } = require('@babel/parser');
const { default: traverse } = require('@babel/traverse');
const { default: generate } = require('@babel/generator');
// ==========================================
// 1. 配置路径
// ==========================================
const filePath = 'D:\游戏\cocos\wechatgame_\assets\main\index.js';
const directoryPath = pathUtils.join(pathUtils.dirname(filePath), 'out');
if (!fs.existsSync(directoryPath)) {
fs.mkdirSync(directoryPath, { recursive: true });
}
// ==========================================
// 2. 内置 Cocos Creator UUID 解压工具
// ==========================================
const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const BASE64_VALUES = new Array(123);
for (let i = 0; i < BASE64_CHARS.length; i++) {
BASE64_VALUES[BASE64_CHARS.charCodeAt(i)] = i;
}
const HexChars = '0123456789abcdef'.split('');
function decompressUuid(uuid) {
if (!uuid || uuid.length !== 22) {
return uuid;
}
let res = [];
let i = 0;
let j = 0;
while (i < 22) {
let b1 = BASE64_VALUES[uuid.charCodeAt(i++)];
let b2 = BASE64_VALUES[uuid.charCodeAt(i++)];
let b3 = BASE64_VALUES[uuid.charCodeAt(i++)];
let b4 = BASE64_VALUES[uuid.charCodeAt(i++)];
}
let str = res.join('');
return str.slice(0, 8) + '-' + str.slice(8, 12) + '-' + str.slice(12, 16) + '-' + str.slice(16, 20) + '-' + str.slice(20, 32);
}
// ==========================================
// 3. 核心处理逻辑 (完美修复版)
// ==========================================
function separateFunctionsInFile(filePath) {
const fileContent = fs.readFileSync(filePath, 'utf8');
const ast = parse(fileContent, { sourceType: 'module' });
// 1. 最外层全局遍历
traverse(ast, {
ObjectProperty(path) {
const { node } = path;
if (
node.value.type === 'ArrayExpression' &&
node.value.elements.length > 0 &&
node.value.elements[0].type === 'FunctionExpression'
) {
let funcName = '';
if (node.key.type === 'Identifier') funcName = node.key.name;
else if (node.key.type === 'StringLiteral') funcName = node.key.value;
});
}
/**
*/
function exportFunctionCode(funcNode, funcName, extractedUuid) {
const funcParams = funcNode.params.map((param) => param.name);
const paramAssignments = funcParams
.map((param, index) => {
const assignment = index === 0 ? 'require' : index === 1 ? 'module' : 'exports';
return
var ${param} = ${assignment};;})
.join('\n');
const bodyCode = funcNode.body.body.map((node) => generate(node).code).join('\n');
const modifiedCode =
${paramAssignments}\n${bodyCode};const outJsPath = pathUtils.join(directoryPath,
${funcName}.js);fs.writeFileSync(outJsPath, modifiedCode, 'utf8');
// 如果抓到了 UUID,就生成 Meta
if (extractedUuid) {
saveMeta(funcName, extractedUuid);
}
}
/**
*/
function saveMeta(funcName, uuidValue) {
const deuuid = decompressUuid(uuidValue);
const jsonData = {
ver: '1.1.0',
uuid: deuuid,
importer: 'javascript',
isPlugin: false,
loadPluginInWeb: true,
loadPluginInNative: true,
loadPluginInEditor: false,
subMetas: {},
};
const jsonString = JSON.stringify(jsonData, null, 2);
const outMetaPath = pathUtils.join(directoryPath,
${funcName}.js.meta);fs.writeFileSync(outMetaPath, jsonString, 'utf8');
}
// ==========================================
// 4. 执行
// ==========================================
separateFunctionsInFile(filePath);
console.log('✨ 导出成功!:', directoryPath);`