Load Multiple JS Modules

Is there a way to load multiple JS modules? I see in the documentation that in configuration, you can set a js_entrypoint but it only takes 1 string as an argument. I don’t see where else I can do it.

what i want to do is conditionally register an RPC function based on an environment variable, for example via nkruntime context env.build === "production", but it errors out i think due to this: [Feature] Allow rpc registration with indirect function references · Issue #549 · heroiclabs/nakama · GitHub. so i thought about loading multiple JS modules instead but not sure how to achieve this

Hello @dragonlobster,

the server expects a single bundled JS file, if you want to lay out your code in modules, you’ll need to use some bundling tool or build system (e.g.: rollup or the TS compiler) to transpile and build a single ES5 compliant JS file as output to be read by Nakama.

Due to some limitations in how we need to internally map the JS function calls in Nakama to be able to reuse them across the JS VM pooling system, the functions need to be named and defined at the top level scope. I believe you should be able to conditionally register functions, depending on how you’re doing it. If you’re running into an error please provide a small reproducible example and we’ll try to help.

@sesposito Thanks for the response. I have 2 rpc functions like this:

const rpcAny: nkruntime.RpcFunction = (
    _context: nkruntime.Context,
    logger: nkruntime.Logger,
    _nk: nkruntime.Nakama,
    _payload: string
): void => {
    logger.info("hello world any")
}
const rpcNonProd: nkruntime.RpcFunction = (
    _context: nkruntime.Context,
    logger: nkruntime.Logger,
    _nk: nkruntime.Nakama,
    _payload: string
): void => {
    logger.info("hello world nonprod")
}

So i try to conditionally load rpcNonProd based on nkruntime.Context env flag that i set myself. So I run nakama with flag --runtime.env "build=nonprod". The following code however doesn’t work.

const InitModule: nkruntime.InitModule = (
    ctx: nkruntime.Context,
    logger: nkruntime.Logger,
    _nk: nkruntime.Nakama,
    initializer: nkruntime.Initializer
) => {
    initializer.registerMatch(...)

    initializer.registerRpc("rpcAny", rpcAny)

    if (ctx.env.build !== "prod") {
        initializer.registerRpc("rpcNonProd", rpcNonProd)
    }
}

It results in:

{"level":"error","ts":"2023-05-09T14:38:58.717Z","caller":"server/runtime_javascript.go:1654","msg":"Failed to eval JavaScript modules.","error":"GoError: js rpcNonProd functi
on key could not be extracted: not found\n\tat github.com/heroiclabs/nakama/v3/server.(*RuntimeJavascriptInitModule).registerRpc.func1 (native)\n\tat InitModule (index.js:611:43
(40))\n\tat native\n"}

@dragonlobster I’ve double checked, unfortunately this is a current limitation, I think there’s some improvements that we can make for the next release, but for now the function registration itself has to be at the top level.

What you could do to achieve a similar result is move the function registration at the top level inside InitModule and do the env check within rpcNonProd and return early or throw an error based on the environment to guard it from being executed.

@sesposito thanks - i suspected so. will give checking environment inside rpc function a try