nodejs / node-gyp

Node.js native addon build tool
MIT License
9.91k stars 1.79k forks source link

Building a React-compatible addon module #2282

Closed Fulguritude closed 3 years ago

Fulguritude commented 3 years ago

$> npm -v 6.14.9


* **Platform**: <!-- `uname -a` (UNIX), or `systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type"` (Windows) -->

$> uname -a Linux pop-os 5.8.0-7630-generic #32~1606339263~20.10~61c3910-Ubuntu SMP Thu Nov 26 00:10:35 UTC x86_64 x86_64 x86_64 GNU/Linux

(pop-os is an ubuntu/debian-based build)

* **Compiler**: <!-- `cc -v` (UNIX) or `msbuild /version & cl` (Windows) -->

$> cc -v COLLECT_GCC=cc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.2.0-13ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-JvwpWM/gcc-10-10.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-JvwpWM/gcc-10-10.2.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.2.0 (Ubuntu 10.2.0-13ubuntu1)


(NB: in the Makefile generated by node-gyp, you have `CC.host ?= gcc`)

* **Module**: <!-- what you tried to build/install -->

A proprietary (for now closed source) module, based on a raw C API. **My problem is that I can't manage to import the module generated by node-gyp from a ReactTS file; and this is the only context in which importing the module does not work. The module otherwise works fine.**

Of note: the `module.node` executable works fine as an import with both normal JS, and normal TS (given a corresponding `module.d.ts` file). The issue arises when importing it from a `.tsx` file. No matter what I try, I get:

`Module not found: Can't resolve 'path/to/module' in 'path/to/src'`

Note that this is of course not an error in the filepath, or filename, or package.json "paths" field (I quadruple-checked), as the same path to this module works fine for non-React projects, and other imports from the same package folder work fine in the React project. **This seems to be an incompatibility specific to the pairing of an NAPI addon and React.**

**Is there some specific node-gyp compiler option, or tsconfig.json option, or package.json option, that one should specify specify to allow for a `.node` files to be correctly imported from a `.tsx` file ? Do you have any idea from where this issue may arise ?**

Thank you very much for your help. If any extra information can be of help (that I am legally able to disclose), please don't hesitate to ask. If you think there is another repository on which this issue might be more relevant, please let me know as well.
Fulguritude commented 3 years ago

So I figured out what the issue was. It is simply that native node addons can only be launched from a node server, and not directly from the browser. The browser will NEVER run the code from the node addon itself, for security purposes. Ie, node-gyp isn't a simple "C to JS" transpiler. If you want something of that kind, look up emscripten.

A node-only solution to this problem is simply to separate the front-end logic from the back-end logic. By this I mean having on one hand a small node server (serving with express for example) that handles the things that need to be done by the addon; and on the other hand, having a React front-end client in another project that connects to this server to get whatever data it needs for the front-end (say, by having the server communicate a JSON to the client). This allows the browser to consume the results of the addon's operations in a way where the browser itself doesn't run any addon code.