Importing/requiring 来自 Webpack ReactJS/ReactTS 项目的 NAPI 插件
Importing/requiring an NAPI addon from a Webpack ReactJS/ReactTS project
我有一个自定义的 API(暂时关闭源代码),它是用纯 C 语言构建的。这个 API 是通信协议的客户端(想想基于网络的数据库查询)。我已成功使用 node-gyp
编译 C 代码包装器,以便 NAPI 插件 addon.node
可以通过调用 C 在 JavaScript 中运行。我还写了一个 .d.ts
文件,这样这个插件就可以在 TypeScript 中运行。我对这两个用例都没有问题;即,执行 tsc index.ts && nodejs index.js
将编译 运行 imported/required 插件,而我的 C API 的客户端操作会顺利进行。我已将此插件制作成私有 npm 包,并通过将其作为 node_modules
依赖项安装在小型 TypeScript 项目中使用,没有任何问题。
当我尝试 运行 需要使用此插件的 React 网络应用程序时,我的问题就来了。我需要 React,因为我的数据查询将用于 GUI 类型的 Web 小程序(实时查询数据并更新 GUI 视图)。我使用 react-scripts start
启动我的 React 应用程序,就像使用 webpack/create-react-app 创建的任何 React 项目一样。我不知道除了使用 react-scripts
-family 命令之外,是否还有其他启动 ReactJS/ReactTS 项目的方法。如果你知道替代方案,我会试试的。
我的错误完全是:
在 TypeScript 方面:当我尝试 import/require 插件时出现 Module not found: Can't resolve '@my-company/my_package/addon' in '/path/to/typescript/srcdirectory'
错误,以获得正确的路径。是的,我绝对确定我的路径是正确的(在 package.json
“路径”和调用源中);找到同一依赖目录中的其他(正常 .ts
)文件,并使用来自同一 .tsx
或 .ts
源的相同路径(和它们自己的文件名)正常导入。另请注意,使用 tsc
编译的非 React .ts
文件可以很好地识别此相同的路径+文件名(即 addon
而不是 addon.node
)。由 node-gyp
生成的 addon.node
在 react-scripts start
处理 TypeScript 转换时根本无法识别。
在 JavaScript 方面:我也尝试先用 tsc
为我的 TS 源生成相应的 JS 文件,然后“需要”我的插件;然后启动 react-scripts
。对于生成的 JS 中的路径 var api = require("@my-company/my_package/addon");
,我得到相同的“找不到模块”错误。对于 var api = require("@my-company/my_package/addon.node");
,插件被识别,但是,当我到达带有 api.MyFunction()
的任何行时,对于任何函数,带有 TypeError: api.MyFunction is not a function
.
的任何行,JS 都会失败
我在SO上发现了下面的问题,这似乎与我有关:How to use a native node.js addon in React;但由于与我完全相同的原因,它没有得到答复并且可能不会发生。
我的问题是:使用 node-gyp
编译 NAPI 插件的合适方法是什么,将其打包为 npm 的特定结构,然后从React JS/TS 项目以便导入工作?是否应该验证插件的 package.json
或 React 项目的一些特定约束,以便它可以顺利工作? 我不确定很多人有这样的经验用例(从原始 C 到 ReactTS);但肯定会有一些 NAPI 插件,它非常有名,可以在某些 React 项目中使用:即使是 link 也可能对我有用。
您提供的任何 link 意见、想法或建议都将 非常 感激。谢谢你的时间。
编辑:经过大量实验和阅读文档,我现在确信问题出在 webpack 上,需要在 webpack.config.js
中使用 externals
来解决我的导入方式插件以某种方式。 webpack.config.js
的语法是什么?如何将这个“外部”库导入到我的 .tsx
文件中?使用特定的 Webpack 配置时,我的 package.json 有什么特别之处吗?
所以我设法解决了我的问题。事实证明这个问题比我想象的更根本。我通过以下 links 弄清楚了,并通过在 Reactiflux discord 上询问来了解解决方案。由于以下问题并没有真正解释可用的解决方案,我想我会 post 在这里。
How to use Native Node Modules on a React, ES6, Electron App?
基本上,原生节点插件只能从节点服务器启动,不能直接从浏览器启动。出于安全目的,浏览器永远不会 运行 来自节点插件本身的代码。也就是说,node-gyp/napi 不是某种“C 到 JS”的转译器。如果你想要那种东西,请查找 emscripten
.
这个问题的一个纯节点解决方案就是简单地将前端逻辑与后端逻辑分开。我的意思是,一方面有一个小型节点服务器(例如与 express
一起服务)来处理插件需要完成的事情;另一方面,在另一个连接到该服务器的项目中有一个 React 前端客户端,以获取前端所需的任何数据(例如,让服务器与客户端通信 JSON) .这允许浏览器以浏览器本身永远不会 运行 任何插件代码的方式使用插件操作的结果。从第一个 link 中可以看出,Electron 应用程序将进行一些类似的划分,使用 ipcRenderer
或 remote
而不是 express
在前端之间进行通信端和应用程序的后端部分。
我有一个自定义的 API(暂时关闭源代码),它是用纯 C 语言构建的。这个 API 是通信协议的客户端(想想基于网络的数据库查询)。我已成功使用 node-gyp
编译 C 代码包装器,以便 NAPI 插件 addon.node
可以通过调用 C 在 JavaScript 中运行。我还写了一个 .d.ts
文件,这样这个插件就可以在 TypeScript 中运行。我对这两个用例都没有问题;即,执行 tsc index.ts && nodejs index.js
将编译 运行 imported/required 插件,而我的 C API 的客户端操作会顺利进行。我已将此插件制作成私有 npm 包,并通过将其作为 node_modules
依赖项安装在小型 TypeScript 项目中使用,没有任何问题。
当我尝试 运行 需要使用此插件的 React 网络应用程序时,我的问题就来了。我需要 React,因为我的数据查询将用于 GUI 类型的 Web 小程序(实时查询数据并更新 GUI 视图)。我使用 react-scripts start
启动我的 React 应用程序,就像使用 webpack/create-react-app 创建的任何 React 项目一样。我不知道除了使用 react-scripts
-family 命令之外,是否还有其他启动 ReactJS/ReactTS 项目的方法。如果你知道替代方案,我会试试的。
我的错误完全是:
在 TypeScript 方面:当我尝试 import/require 插件时出现
Module not found: Can't resolve '@my-company/my_package/addon' in '/path/to/typescript/srcdirectory'
错误,以获得正确的路径。是的,我绝对确定我的路径是正确的(在package.json
“路径”和调用源中);找到同一依赖目录中的其他(正常.ts
)文件,并使用来自同一.tsx
或.ts
源的相同路径(和它们自己的文件名)正常导入。另请注意,使用tsc
编译的非 React.ts
文件可以很好地识别此相同的路径+文件名(即addon
而不是addon.node
)。由node-gyp
生成的addon.node
在react-scripts start
处理 TypeScript 转换时根本无法识别。在 JavaScript 方面:我也尝试先用
的任何行,JS 都会失败tsc
为我的 TS 源生成相应的 JS 文件,然后“需要”我的插件;然后启动react-scripts
。对于生成的 JS 中的路径var api = require("@my-company/my_package/addon");
,我得到相同的“找不到模块”错误。对于var api = require("@my-company/my_package/addon.node");
,插件被识别,但是,当我到达带有api.MyFunction()
的任何行时,对于任何函数,带有TypeError: api.MyFunction is not a function
.
我在SO上发现了下面的问题,这似乎与我有关:How to use a native node.js addon in React;但由于与我完全相同的原因,它没有得到答复并且可能不会发生。
我的问题是:使用 node-gyp
编译 NAPI 插件的合适方法是什么,将其打包为 npm 的特定结构,然后从React JS/TS 项目以便导入工作?是否应该验证插件的 package.json
或 React 项目的一些特定约束,以便它可以顺利工作? 我不确定很多人有这样的经验用例(从原始 C 到 ReactTS);但肯定会有一些 NAPI 插件,它非常有名,可以在某些 React 项目中使用:即使是 link 也可能对我有用。
您提供的任何 link 意见、想法或建议都将 非常 感激。谢谢你的时间。
编辑:经过大量实验和阅读文档,我现在确信问题出在 webpack 上,需要在 webpack.config.js
中使用 externals
来解决我的导入方式插件以某种方式。 webpack.config.js
的语法是什么?如何将这个“外部”库导入到我的 .tsx
文件中?使用特定的 Webpack 配置时,我的 package.json 有什么特别之处吗?
所以我设法解决了我的问题。事实证明这个问题比我想象的更根本。我通过以下 links 弄清楚了,并通过在 Reactiflux discord 上询问来了解解决方案。由于以下问题并没有真正解释可用的解决方案,我想我会 post 在这里。
How to use Native Node Modules on a React, ES6, Electron App?
基本上,原生节点插件只能从节点服务器启动,不能直接从浏览器启动。出于安全目的,浏览器永远不会 运行 来自节点插件本身的代码。也就是说,node-gyp/napi 不是某种“C 到 JS”的转译器。如果你想要那种东西,请查找 emscripten
.
这个问题的一个纯节点解决方案就是简单地将前端逻辑与后端逻辑分开。我的意思是,一方面有一个小型节点服务器(例如与 express
一起服务)来处理插件需要完成的事情;另一方面,在另一个连接到该服务器的项目中有一个 React 前端客户端,以获取前端所需的任何数据(例如,让服务器与客户端通信 JSON) .这允许浏览器以浏览器本身永远不会 运行 任何插件代码的方式使用插件操作的结果。从第一个 link 中可以看出,Electron 应用程序将进行一些类似的划分,使用 ipcRenderer
或 remote
而不是 express
在前端之间进行通信端和应用程序的后端部分。