从 Webpack ReactJS/ReactTS 项目导入/需要 NAPI 插件 [英] Importing/requiring an NAPI addon from a Webpack ReactJS/ReactTS project

查看:118
本文介绍了从 Webpack ReactJS/ReactTS 项目导入/需要 NAPI 插件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

当我尝试运行需要使用此插件的 React Web 应用程序时,我的问题就出现了.我需要 React,因为我的数据查询将用于 GUI 类型的 Web 小程序(查询它们的数据,并实时更新 GUI 视图).我使用 react-scripts start 启动我的 React 应用程序,就像通​​过 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 源代码.另请注意,非 React .tsaddon 而不是 addon.node)> 文件,使用 tsc 编译.addon.nodenode-gyp 生成,在 react-scripts start 处理 TypeScript 转译时根本无法识别.>

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

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

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

我们将非常感谢您提供的任何链接、想法或建议.非常.感谢您抽出宝贵时间.

经过大量实验和文档阅读后,我现在确信问题源于 webpack,需要在 webpack.config.jsexternals> 以某种方式解决我如何导入插件的问题.webpack.config.js 的语法是什么,这个外部"应该如何?lib 被导入到我的 .tsx 文件中?使用特定的 Webpack 配置时,我的 package.json 有什么特别之处吗?

解决方案

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

如何使用 Native NodeReact、ES6、Electron 应用上的模块?

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

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

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

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 in package.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, with addon and not addon.node) is recognized just fine by a non-React .ts file, compiled with tsc. It is the addon.node, generated by node-gyp that is simply not recognized when react-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 launching react-scripts. For the path var api = require("@my-company/my_package/addon"); in the generated JS, I get the same "Module not found" error. For 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.

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 ?

解决方案

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. 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?

Cannot load Node native addons with webpack

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. 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 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.

这篇关于从 Webpack ReactJS/ReactTS 项目导入/需要 NAPI 插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆