I have a custom API (closed source for now), built in pure C. This API is the client side of a communication protocol (think network-based database queries). I have successfully used node-gyp
to compile the C code wrappers so that the NAPI addon addon.node
can function in JavaScript by calling the C. I have also written a .d.ts
file, so that this addon can work from TypeScript. I have no issue with both of these use cases; ie, doing a tsc index.ts && nodejs index.js
will compile and run the imported/required addon without a hitch, and the client-side operations of my C API happen without a hitch. I have made this addon into a private npm package, and have been using it in small TypeScript projects by installing it as a node_modules
dependency without any issue.
My issue arrives when I try to run a React web app which needs to use this addon. I need React because my data-querying is to be used for GUI-type web applets (that query their data, and update the GUI view, in real-time). I launch my React app with react-scripts start
, like is done with any React project created via webpack/create-react-app. I do not know if there is some other way of launching a ReactJS/ReactTS project than with a react-scripts
-family command. If you know an alternative, I will try it.
My bug exactly:
On the TypeScript side of things: I get a
Module not found: Can't resolve '@my-company/my_package/addon' in '/path/to/typescript/srcdirectory'
error when I try to import/require the addon, for the right path. Yes, I am absolutely certain my path is correct (both inpackage.json
"paths", and the calling source); other (normal.ts
) files in the same dependency directory are found and imported just fine with the same path (and their own filename) from the same.tsx
or.ts
source. Also note that this same path+filename (ie, withaddon
and notaddon.node
) is recognized just fine by a non-React.ts
file, compiled withtsc
. It is theaddon.node
, generated bynode-gyp
that is simply not recognized whenreact-scripts start
handles the TypeScript transpilation.On the JavaScript side of things: I also tried first generating the corresponding JS file for my TS source with
tsc
, and "requiring" my addon; then launchingreact-scripts
. For the pathvar api = require("@my-company/my_package/addon");
in the generated JS, I get the same "Module not found" error. Forvar api = require("@my-company/my_package/addon.node");
, the addon IS recognized, however, the JS fails when I get to any line withapi.MyFunction()
for any function, withTypeError: api.MyFunction is not a function
.
I have found the following question on SO, which seems to be related to mine: How to use a native node.js addon in React ; but it is unanswered and might not happen for exactly the same reasons as mine.
My question is: what is the appropriate way to compile an NAPI addon with node-gyp
, packaging it with a certain structure for npm, and importing it from a React JS/TS project so that the imports work ? Should some specific constraints in either the package.json
for the addon, or the one for the React project, be verified so that this can work smoothly? I'm not sure many people have experience with such a use case (going all the way from raw C to ReactTS); but there's bound to be some NAPI addon that's famous enough to be used in some React project: even a link to that might be useful to me.
Any links, ideas, or advice you provide will be greatly appreciated. Thank you for your time.
Edit: After much experimentation and documentation reading, I am now confident that the issue stems from webpack, and need to use externals
in webpack.config.js
to resolve how I import the addon in some way. What is the syntax for both the webpack.config.js
, and how should this "external" lib be imported in my .tsx
files ? Is there anything special to do with my package.json when using a specific Webpack config ?