-
Notifications
You must be signed in to change notification settings - Fork 818
Open
Labels
Description
前置阅读 | Pre-reading
Puer的版本 | Puer Version
1.0.9
UE的版本 | UE Version
5.7.1
发生在哪个平台 | Platform
Editor(win)
错误信息 | Error Message
Error: can not find @protobufjs/aspromise in D:/Projects/CoreGame/node_modules/protobufjs/src/util
问题重现 | Bug reproduce
CoreGame 是一个UE5.7.1的项目,集成了PureTS在Plugins目录下,JsEnv.Build.cs配置(使用NodeJs backend):
private SupportedV8Versions UseV8Version =
#if UE_4_25_OR_LATER
SupportedV8Versions.V9_4_146_24;
#else
SupportedV8Versions.VDeprecated;
#endif
private bool UseNodejs = true;
private bool Node16 = true;
private bool UseQuickjs = false;
private bool QjsNamespaceSuffix = false;
private bool WithFFI = false;
private bool ForceStaticLibInEditor = false;
private bool ThreadSafe = false;
private bool FTextAsString = true;
private bool bEditorSuffix = true;
// v8 9.4+
private bool SingleThreaded = false;
public static bool WithSourceControl = false;
public bool WithByteCode = false;
private bool WithWebsocket = false;系统node/npm版本:
$ node --version
v22.21.1
$ npm --version
10.9.4
因为项目需要,需要使用protobufjs库,在项目根目录(CoreGame)的node_modules下能够发现protobufjs及相关依赖正常安装,使用protobufjs的方式如下(使用Mixin方式加载):
import { toDelegate } from 'puerts';
import * as UE from 'ue'
import { load } from "protobufjs"; // <---------------------------------- 应该是这里对应的JavaScript解析node_modules出错
interface GM_NscmSessionTest_C extends UE.Game.TestMaps.GM_NscmSessionTest.GM_NscmSessionTest_C {}
class GM_NscmSessionTest_C {
NscmSession: UE.NscmSession
ReceiveBeginPlay() {
console.log(`****************** GM_NscmSessionTest_C.ReceiveBeginPlay: from GM_NscmSessionTest_C.ts`);
this.Print("****************** GM_NscmSessionTest_C.ReceiveBeginPlay: from GM_NscmSessionTest_C.ts");
let NscmSessionSubsystem = UE.SubsystemBlueprintLibrary.GetGameInstanceSubsystem(this.GetWorld(), UE.NscmSessionSubsystem.StaticClass()) as UE.NscmSessionSubsystem
this.NscmSession = NscmSessionSubsystem.CreateNscmSession("127.0.0.1", 8888)
function OnMessage(session: UE.NscmSession, msg: ArrayBuffer) {
let u8a1 = new Uint8Array(msg);
// todo: this should be a protobuf message, so use protobufjs to unmarshal it
}
this.NscmSession.SetOnMessageDelegate(toDelegate(this, OnMessage))
load("Proto/HeartBeat.proto", function (err, root) { // <============== this should trigger protobufjs library resolution, and thus the error
if (err)
throw err;
// Lookup types (no package name in your proto)
const HeartBeatRequest = root.lookupType("HeartBeatRequest");
const HeartBeatResponse = root.lookupType("HeartBeatResponse");
// ----------------------------
// Encode HeartBeatRequest
// ----------------------------
const requestPayload = {
key: "conn-12345",
time: Date.now() // int64
};
// Optional but recommended
const reqErr = HeartBeatRequest.verify(requestPayload);
if (reqErr)
throw Error(reqErr);
const requestMessage = HeartBeatRequest.create(requestPayload);
console.log("requestMessage =", requestMessage);
const requestBuffer = HeartBeatRequest.encode(requestMessage).finish();
console.log("requestBuffer =", Array.prototype.toString.call(requestBuffer));
// ----------------------------
// Decode HeartBeatRequest
// ----------------------------
const decodedRequest = HeartBeatRequest.decode(requestBuffer);
console.log("decodedRequest =", decodedRequest);
// Convert to plain object (important for int64)
const requestObject = HeartBeatRequest.toObject(decodedRequest, {
longs: String,
defaults: true
});
console.log("requestObject =", requestObject);
// ----------------------------
// Encode HeartBeatResponse
// ----------------------------
const responsePayload = {
key: requestObject.key,
time: Date.now()
};
const responseMessage = HeartBeatResponse.create(responsePayload);
const responseBuffer = HeartBeatResponse.encode(responseMessage).finish();
// ----------------------------
// Decode HeartBeatResponse
// ----------------------------
const decodedResponse = HeartBeatResponse.decode(responseBuffer);
const responseObject = HeartBeatResponse.toObject(decodedResponse, {
longs: String,
defaults: true
});
console.log("responseObject =", responseObject);
});
}
ReceiveTick() {
console.log("ReceiveOnTick ...")
}
ReceiveEndPlay() {
this.NscmSession.Shutdown()
}
}
export { GM_NscmSessionTest_C }几个问题吧:
node_modules的位置:currently it's under the project root directory (CoreGame), 但是实际运行的时候(either under PIE or packaged game),我猜测node_modulessomehow 应该在CoreGame/Content/JavaScript目录下面,然而文档里面我并没有找到当使用NodeJs backend的时候,有什么额外的步骤来将项目根目录下的node_modules目录引入到CoreGame/Content/JavaScript目录下面?或者有什么其他的设置可以让实际生成的JavaScript代码来找到protobufjs库和相关依赖?- PuerTS内部使用NodeJs应该是Node16?但是我的系统NodeJs的版本是22(如上面所示),不同的Node版本安装的protobufjs包是否可以在不同的NodeJs版本之间使用?
- 目前我对整体TypeScript/JavaScript生态还不是很熟,但是我比较好奇,为什么最终生成的在CoreGame/Content/JavaScript目录下的代码还是找到了根目录下面的node_modules目录?是在哪里配置了吗?
- 因为我的报错信息还是在PIE模式下运行的时候出现的,那么如果在打包的时候,可能会更需要protobufjs在正确的位置才能在最终运行时正确加载使用,那这个其实和第一个问题是强相关的:使用nodejs后端的时候需要如何保证node_modules能够在packaged game模式下能够被正确找到?
谢谢解答!
Reactions are currently unavailable