Files
18xchat/Tools/Proto/build-proto.js
T
2025-08-14 00:16:34 +08:00

104 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Tools/Proto/build-proto.js
const { execSync } = require('child_process');
const fs = require('fs-extra');
const path = require('path');
const SRC = path.join(__dirname, '..', '..', 'Proto'); // 源 proto 文件目录
const OUT_DIR = path.join(__dirname, '..', '..', 'assets', 'Scripts', 'proto');
const OUT_JS = path.join(OUT_DIR, 'proto.pb.js');
const OUT_DTS = path.join(OUT_DIR, 'proto.pb.d.ts');
const NAMESPACE = 'proto';
/** 递归收集所有 .proto 文件 */
function walk(dir) {
const files = [];
for (const name of fs.readdirSync(dir)) {
const p = path.join(dir, name);
const stat = fs.statSync(p);
if (stat.isDirectory()) files.push(...walk(p));
else if (name.endsWith('.proto')) files.push(p);
}
return files;
}
/** 清空输出目录 */
function clearOutput() {
fs.emptyDirSync(OUT_DIR);
console.log(`已清空目录: ${OUT_DIR}`);
}
/** 给 CJS 文件添加 default 导出 */
function addDefaultExport(jsFile) {
let code = fs.readFileSync(jsFile, 'utf8');
if (/module\.exports\s*=/.test(code) && !/module\.exports\.default\s*=/.test(code)) {
code += `\nmodule.exports.default = module.exports;`;
fs.writeFileSync(jsFile, code, 'utf8');
console.log(`已为 ${path.basename(jsFile)} 添加 default 导出`);
}
}
/** 包装 d.ts 文件,修复 $protobuf & public 报错 */
function wrapDTS(filePath) {
let original = fs.readFileSync(filePath, 'utf8');
// 1. 提取顶层 import(避免包进 namespace
const importLines = [];
original = original.replace(/^(import\s+.*?;)\s*$/gm, (_, imp) => {
importLines.push(imp);
return '';
});
// 2. 去掉 public 修饰符
original = original.replace(/^\s*public\s+/gm, '');
// 3. 包装 namespace
const wrapped = `${importLines.join('\n')}\n\ndeclare namespace ${NAMESPACE} {\n${original}\n}\nexport default ${NAMESPACE};\n`;
fs.writeFileSync(filePath, wrapped, 'utf8');
console.log(`已包装文件: ${filePath}`);
}
/** 主构建流程 */
function build() {
clearOutput();
const allProtoFiles = walk(SRC);
if (allProtoFiles.length === 0) {
console.error('没有找到任何 .proto 文件!');
process.exit(1);
}
fs.mkdirpSync(OUT_DIR);
// 1) 生成 JSCJS 格式,方便加 default
execSync([
'pbjs',
'-t static-module',
'-w commonjs', // 用 commonjs 避免 ESM 重复 default
'--dependency protobufjs/minimal.js',
`-o "${OUT_JS}"`,
`-p "${SRC}"`,
...allProtoFiles.map(f => `"${f}"`)
].join(' '), { stdio: 'inherit' });
// 2) 添加 default 导出
addDefaultExport(OUT_JS);
// 3) 生成 d.ts
execSync([
'pbts',
'--main',
`-o "${OUT_DTS}"`,
`"${OUT_JS}"`
].join(' '), { stdio: 'inherit' });
// 4) wrap d.ts
wrapDTS(OUT_DTS);
console.log(`\nProto 生成完成!
JS 文件: ${OUT_JS}
TS 文件: ${OUT_DTS}
共处理 ${allProtoFiles.length} 个 .proto 文件`);
}
build();