JisolGame/JisolGameCocos/.protobufjs.js
DESKTOP-5RP3AKU\Jisol c519fae9a4 提交新手引导
2023-11-13 02:37:29 +08:00

187 lines
5.6 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.

const path = require("path");
const child_process = require("child_process");
const fs = require("fs");
/**
* @typedef {Object} proto_list
* @property {string | undefined} namespace_s 命名空间
* @property {string[]} proto_ss 协议文件(生成为脚本的协议文件)
* @property {string} ts_output_path_s ts 输出路径(带脚本名)
* @property {string} dts_output_path_s d.ts 输出路径(带脚本名)
* @property {string[] | undefined} pbjs_parameters_ss pbjs 生成时参数(可用于裁剪代码, 命令行`npx pbjs`查看具体参数)
*/
module.exports = {
/**
* 协议列表
* @type {proto_list[]}
*/
proto_list: [],
/**
自动构建开关
- true: 递归监听 dir_path_ss 内的文件添加/删除/修改,并触发构建指令
- false需要手动点击 `protobuf/构建` 才会触发构建菜单
*/
automatic_build_b: false,
/** 自动构建延迟(秒),防止短时间内频繁触发构建 */
automatic_build_delay_s_n: 2,
/**
* 构建函数
* @param {proto_list} config_ proto 配置
* @returns {boolean} 成功状态
*/
async build_f(config_) {
// 生成消息头
child_process.execSync("npx ts-node ./protobuf/main.ts", {
"cwd": "./tool"
})
/** ts 输出路径 */
let ts_output_path_s = config_.ts_output_path_s[0] !== "." ? config_.ts_output_path_s : path.join(__dirname, config_.ts_output_path_s);
/** js 输出路径 */
let js_output_path_s = path.join(path.dirname(ts_output_path_s), path.basename(ts_output_path_s, path.extname(ts_output_path_s)) + ".js");
/** 声明文件路径 */
let dts_path_s = config_.dts_output_path_s[0] !== "." ? config_.dts_output_path_s : path.join(__dirname, config_.dts_output_path_s);
// 确保文件夹存在
{
if (!fs.existsSync(path.dirname(ts_output_path_s))) {
fs.mkdirSync(path.dirname(ts_output_path_s));
}
if (!fs.existsSync(path.dirname(dts_path_s))) {
fs.mkdirSync(path.dirname(dts_path_s));
}
}
let result = await Promise.resolve()
// 生成 js 文件
.then(() => {
return new Promise((resolve_f, reject_t) => {
// 使用 es6 的生成类型
child_process.exec(
`npx pbjs -t static-module -w es6 -l eslint-disable --es6 --keep-case ${!config_.pbjs_parameters_ss ? "" : config_.pbjs_parameters_ss.join(" ")
} ${!config_.namespace_s ? "" : `--root ${config_.namespace_s}`} -o ${js_output_path_s} ${config_.proto_ss.join(" ")}`,
{
cwd: __dirname,
},
(error, stdout, stderr) => {
if (stderr) {
reject_t(stderr);
return;
}
resolve_f();
}
);
});
})
// 生成 d.ts 文件
.then(() => {
// 生成 d.ts
return new Promise((resolve_f, reject_t) => {
child_process.exec(
`npx pbts -m ${config_.namespace_s ? `--root ${config_.namespace_s}` : ""} -o ${dts_path_s} ${js_output_path_s}`,
{
cwd: __dirname,
},
(error, stdout, stderr) => {
if (stderr) {
reject_t(stderr);
return;
}
resolve_f();
}
);
});
})
// js 后处理
.then(() => {
let file_s = fs.readFileSync(js_output_path_s, "utf-8");
file_s = file_s
// 替换 import
.replace('import * as $protobuf from "protobufjs/minimal";', 'import $protobuf from "protobufjs/minimal.js";')
// 替换 root
.replace(/const \$root = ([^]+?);/, "const $root = {};");
// 存在命名空间
if (config_.namespace_s) {
file_s = file_s.replace(/export const /g, "const ");
}
// 更新协议文件
fs.writeFileSync(js_output_path_s, file_s);
})
// d.ts 文件后处理
.then(() => {
let file_s = fs.readFileSync(dts_path_s, "utf-8");
if (config_.namespace_s) {
file_s = `export namespace ${config_.namespace_s} {\n${file_s}\n}`;
}
// 添加类型声明
file_s = `import type { Long } from "protobufjs";\n` + file_s;
// 后处理
file_s = file_s.replace(/\$protobuf/g, "protobuf");
// 更新协议文件
fs.writeFileSync(dts_path_s, file_s);
})
// 将 js 协议脚本转换为 ts
.then(() => {
let js_file_s = fs.readFileSync(js_output_path_s, "utf-8");
/** ts 文件路径 */
let ts_script_path_s = path.join(
path.dirname(ts_output_path_s),
path.basename(ts_output_path_s, path.extname(ts_output_path_s)) + ".ts"
);
/** d.ts 相对路径 */
let dts_relative_path_s = path.relative(path.dirname(ts_output_path_s), path.dirname(dts_path_s)).replace(/\\/g, "/");
/** d.ts 导入路径 */
let dts_import_path_s = (dts_relative_path_s || "./") + path.basename(dts_path_s, ".ts");
// 后处理
js_file_s = js_file_s
// 对象类型const $root: typeof import("./test.d").pb
.replace(
"const $root = ",
`const $root: typeof import("${dts_import_path_s}")${config_.namespace_s ? `.${config_.namespace_s}` : ""} = `
)
// 修复对象类型错误
.replace(
/export const ([^ ]+?) = ([^ ]+?) =/g,
function (...args_as) {
return `export const ${args_as[1]}: typeof ${args_as[2]} = ${args_as[2]} =`;
}
);
if (config_.namespace_s) {
js_file_s = js_file_s
// module.exports
.replace(
"export { $root as default }",
`export ${config_.namespace_s ? `const ${config_.namespace_s} = ` : ""}{ ...$root }`);
}
fs.writeFileSync(js_output_path_s, "// @ts-nocheck\n" + js_file_s);
fs.renameSync(js_output_path_s, ts_script_path_s);
})
// 捕获错误
.catch((error) => {
console.error("生成错误:", error);
return false;
})
// 任务完成
.then((v) => {
return v ?? true;
});
return result;
},
};