0

我有一个自定义 API(目前是封闭源代码),用纯 C 构建。这个 API 是通信协议的客户端(想想基于网络的数据库查询)。我已经成功地用于node-gyp编译 C 代码包装器,以便 NAPI 插件addon.node可以通过调用 C 在 JavaScript 中运行。我还编写了一个.d.ts文件,以便该插件可以在 TypeScript 中工作。我对这两个用例都没有问题;即,执行 atsc index.ts && nodejs index.js将顺利编译和运行导入/所需的插件,并且我的 C API 的客户端操作顺利进行。我已经把这个插件变成了一个私有的 npm 包,并且一直在小型 TypeScript 项目中使用它,将它安装为node_modules依赖项,没有任何问题。

当我尝试运行需要使用此插件的 React Web 应用程序时,我的问题就出现了。我需要 React,因为我的数据查询将用于 GUI 类型的 Web 小程序(查询它们的数据,并实时更新 GUI 视图)。我使用 启动我的 React 应用程序react-scripts start,就像通​​过 webpack/create-react-app 创建的任何 React 项目一样。我不知道除了使用react-scripts-family 命令之外,是否还有其他方法可以启动 ReactJS/ReactTS 项目。如果你知道另一种选择,我会试试的。

我的错误正是:

  • 在 TypeScript 方面:Module not found: Can't resolve '@my-company/my_package/addon' in '/path/to/typescript/srcdirectory'当我尝试为正确的路径导入/需要插件时出现错误。是的,我绝对确定我的路径是正确的(在package.json“路径”和调用源中);在同一依赖目录中的其他(正常.ts)文件可以从相同的.tsx.ts源中找到并使用相同的路径(和它们自己的文件名)导入。addonaddon.node请注意,.ts使用tsc. 在处理 TypeScript 转换时,它是addon.node由 that 生成的node-gyp,根本无法识别。react-scripts start

  • 在 JavaScript 方面:我还尝试首先使用 为我的 TS 源生成相应的 JS 文件tsc,并“要求”我的插件;然后启动react-scripts。对于生成的 JS 中的路径var api = require("@my-company/my_package/addon");,我得到相同的“未找到模块”错误。因为var api = require("@my-company/my_package/addon.node");,插件被识别,但是,当我到达api.MyFunction()任何函数的任何行时,JS 失败,带有TypeError: api.MyFunction is not a function.

我在 SO 上找到了以下问题,这似乎与我的有关:如何在 React 中使用本机 node.js 插件;但它没有得到答复,并且可能不会出于与我完全相同的原因而发生。

我的问题是:用 编译 NAPI 插件node-gyp、使用特定结构为 npm 打包并从 React JS/TS 项目导入它以便导入工作的适当方法是什么?是否应该验证插件或 React 项目中的某些特定约束,package.json以便能够顺利工作?我不确定很多人是否有过这种用例的经验(从原始 C 到 ReactTS);但是肯定会有一些 NAPI 插件很有名,可以在一些 React 项目中使用:即使是指向它的链接也可能对我有用。

您提供的任何链接、想法或建议将不胜感激。感谢您的时间。

编辑:经过大量的实验和文档阅读,我现在确信问题源于 webpack,并且需要使用externalsinwebpack.config.js来解决我如何以某种方式导入插件。两者的语法是什么webpack.config.js,应该如何在我的文件中导入这个“外部”库.tsx?使用特定的 Webpack 配置时,我的 package.json 有什么特别之处吗?

4

1 回答 1

1

所以我设法解决了我的问题。事实证明,这个问题比我想象的更根本。我通过以下链接找到了答案,并通过询问 Reactiflux discord 了解了解决方案。由于以下问题并没有真正解释可用的解决方案,我想我会在这里发布它们。

如何在 React、ES6、Electron 应用上使用原生节点模块?

无法使用 webpack 加载 Node 原生插件

基本上,本机节点插件只能从节点服务器启动,而不能直接从浏览器启动。出于安全考虑,浏览器永远不会从节点插件本身运行代码。即,node-gyp/napi 不是一些“C 到 JS”的转译器。如果您想要那种东西,请查找emscripten

此问题的仅节点解决方案是将前端逻辑与后端逻辑分开。我的意思是一方面有一个小型节点服务器(express例如服务)来处理需要由插件完成的事情;另一方面,在另一个项目中拥有一个 React 前端客户端,该客户端连接到该服务器以获取前端所需的任何数据(例如,通过让服务器将 JSON 传递给客户端)。这允许浏览器以浏览器本身不运行任何插件代码的方式使用插件操作的结果。从第一个链接中可以看出,对于 Electron 应用程序要做一些类似的划分,使用ipcRendererremote代替应用程序express的前端和后端部分之间的通信。

于 2020-12-30T14:15:00.130 回答