简体   繁体   English

从 Webpack ReactJS/ReactTS 项目导入/需要 NAPI 插件

[英]Importing/requiring an NAPI addon from a Webpack ReactJS/ReactTS project

I have a custom API (closed source for now), built in pure C.我有一个定制的 API(暂时关闭源代码),内置纯 C。 This API is the client side of a communication protocol (think network-based database queries).这个 API 是通信协议的客户端(想想基于网络的数据库查询)。 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 successfully used node-gyp 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.我还编写了一个.d.ts文件,这样这个插件就可以在 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.即,执行tsc index.ts && nodejs index.js将顺利编译和运行导入/所需的插件,并且我的 C API 的客户端操作顺利进行。 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.我已将此插件制作为私有 npm package,并一直在小型 TypeScript 项目中使用它,方法是将其安装为node_modules依赖项,没有任何问题。

My issue arrives when I try to run a React web app which needs to use this addon.当我尝试运行需要使用此插件的 React web 应用程序时,我的问题就出现了。 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).我需要 React,因为我的数据查询将用于 GUI 类型的 web 小程序(实时查询其数据并更新 GUI 视图)。 I launch my React app with react-scripts start , like is done with any React project created via webpack/create-react-app.我使用react-scripts start启动我的 React 应用程序,就像通过 webpack/create-react-app 创建的任何 React 项目一样。 I do not know if there is some other way of launching a ReactJS/ReactTS project than with a react-scripts -family command.我不知道除了使用react-scripts -family 命令之外,是否还有其他方法可以启动 ReactJS/ReactTS 项目。 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.在 TypeScript 方面:当我尝试导入/需要插件时,我得到一个Module not found: Can't resolve '@my-company/my_package/addon' in '/path/to/typescript/srcdirectory'错误,为正确的道路。 Yes, I am absolutely certain my path is correct (both in package.json "paths", and the calling source);是的,我绝对确定我的路径是正确的(在package.json “路径”和调用源中); 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.相同依赖目录中的其他(普通.ts )文件可以从相同的.tsx.ts源中找到并使用相同的路径(和它们自己的文件名)很好地导入。 Also note that this same path+filename (ie, with addon and not addon.node ) is recognized just fine by a non-React .ts file, compiled with tsc .另请注意,使用tsc编译的非 React .ts文件可以很好地识别相同的路径+文件名(即,使用addon而不是addon.node )。 It is the addon.node , generated by node-gyp that is simply not recognized when react-scripts start handles the TypeScript transpilation.它是由node-gyp gyp 生成的addon.node ,当react-scripts start处理 TypeScript 转译时根本无法识别。

  • 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;在 JavaScript 方面:我还尝试首先使用tsc为我的 TS 源生成相应的 JS 文件,并“要求”我的插件; then launching react-scripts .然后启动react-scripts For the path var api = require("@my-company/my_package/addon");对于路径var api = require("@my-company/my_package/addon"); in the generated JS, I get the same "Module not found" error.在生成的 JS 中,我得到相同的“未找到模块”错误。 For var api = require("@my-company/my_package/addon.node");对于var api = require("@my-company/my_package/addon.node"); , the addon IS recognized, however, the JS fails when I get to any line with api.MyFunction() for any function, with TypeError: api.MyFunction is not a function . , the addon IS recognized, however, the JS fails when I get to any line with api.MyFunction() for any function, with TypeError: 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 ;我在 SO 上发现了以下问题,这似乎与我的有关: 如何在 React 中使用原生 node.js 插件 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?我的问题是:用node-gyp gyp 编译 NAPI 插件,用 npm 的特定结构打包它,然后从 React JS/TS 项目导入它以便导入工作的适当方法是什么? 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?是否应该验证插件的package.json或 React 项目的某些特定约束,以便能够顺利工作? I'm not sure many people have experience with such a use case (going all the way from raw C to ReactTS);我不确定很多人是否有过这种用例的经验(从原始 C 一直到 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.但是肯定会有一些著名的 NAPI 插件可以在一些 React 项目中使用:即使是指向它的链接也可能对我有用。

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.编辑:经过大量实验和文档阅读,我现在确信问题源于 webpack,并且需要在webpack.config.js中使用externals组件来解决我如何以某种方式导入插件。 What is the syntax for both the webpack.config.js , and how should this "external" lib be imported in my .tsx files? webpack.config.js的语法是什么,应该如何在我的.tsx文件中导入这个“外部”库? Is there anything special to do with my package.json when using a specific Webpack config?使用特定的 Webpack 配置时,我的 package.json 有什么特别之处吗?

So I managed to fix my issue.所以我设法解决了我的问题。 It turns out the problem was more fundamental than I thought.事实证明,这个问题比我想象的更根本。 I figured it out through the following links, and understood the solution by asking around on the Reactiflux discord.我通过以下链接找到了答案,并通过询问 Reactiflux discord 来了解解决方案。 Since the following questions didn't really explain what solutions are available, I figured I'd post them here.由于以下问题并没有真正解释可用的解决方案,我想我会在这里发布它们。

How to use Native Node Modules on a React, ES6, Electron App? 如何在 React、ES6、Electron 应用程序上使用本机节点模块?

Cannot load Node native addons with webpack 无法使用 webpack 加载 Node 本机插件

Basically, 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/napi aren't some "C to JS" transpiler.即,node-gyp/napi 不是一些“C 到 JS”的转译器。 If you want something of that kind, look up emscripten .如果您想要那种东西,请查找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;我的意思是一方面拥有一个小型节点服务器(例如使用express服务)来处理需要由插件完成的事情; 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).另一方面,在另一个项目中拥有一个 React 前端客户端,该客户端连接到该服务器以获取前端所需的任何数据(例如,通过让服务器与客户端通信 JSON)。 This allows the browser to consume the results of the addon's operations in a way where the browser itself doesn't ever run any addon code.这允许浏览器以浏览器本身不运行任何插件代码的方式使用插件操作的结果。 As can be seen in the first link, some similar division is to be done for an Electron app, using ipcRenderer or remote instead of express to communicate between the front-end and the back-end parts of the app.从第一个链接中可以看出,对于一个 Electron 应用程序要做一些类似的划分,使用ipcRendererremote而不是express来在应用程序的前端和后端部分之间进行通信。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM