-
Notifications
You must be signed in to change notification settings - Fork 38
Description
Disclaimer: I am not a JS expert and used Claude liberally to troubleshoot and explain things to me.
I am using this library to generate WASM + JS bindings that can run in Node.js (payjoin/rust-payjoin#1190). I've got it mostly working by just setting target: nodejs in the ubrn.config.yaml. However, there was an issue with module imports resulting in the error below when executing the generated code:
❯ npm run test
> [email protected] test
> node test.js
file:///Users/spacebear/Projects/rust-payjoin/payjoin-ffi/javascript/dist/generated/bitcoin.js:7
import { AbstractFfiConverterByteArray, FfiConverterArray, FfiConverterArrayBuffer, FfiConverterBool, FfiConverterFloat64, FfiConverterInt32, FfiConverterObject, FfiConverterUInt32, FfiConverterUInt64, FfiConverterUInt8, UniffiAbstractObject, UniffiError, UniffiInternalError, UniffiRustCaller, destructorGuardSymbol, pointerLiteralSymbol, uniffiCreateFfiConverterString, uniffiCreateRecord, uniffiTypeNameSymbol, } from "uniffi-bindgen-react-native";
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: The requested module 'uniffi-bindgen-react-native' does not provide an export named 'AbstractFfiConverterByteArray'
at #_instantiate (node:internal/modules/esm/module_job:254:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:369:5)
at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:691:26)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)
Node.js v24.11.0
This seems to be caused by a conflict between package.json which specifies "type": "module", and tsconfig.json which sets "module": "commonjs". The package declares itself as ESM but compiles to CommonJS.
I found a note in the TS documentation which states:
Node.js’s rules for module format detection and interoperability make it incorrect to specify module as esnext or commonjs for projects that run in Node.js, even if all files emitted by tsc are ESM or CJS, respectively. The only correct module settings for projects that intend to run in Node.js are node16 and nodenext. While the emitted JavaScript for an all-ESM Node.js project might look identical between compilations using esnext and nodenext, the type checking can differ. See the reference section on nodenext for more details.
I was able to get around this issue with a fork that changes the tsconfig module value to nodenext and updates the imports accordingly, but it would be nice to upstream a fix into the next official release. I'm not sure whether my solution is compatible with other JS settings e.g. React Native and web, as I only validated it in Node, but will open a draft PR for consideration.