Ole*_*evs 5 javascript node.js node-serialport webpack electron
我有以下渲染器:
import SerialPort from "serialport";
new SerialPort("/dev/tty-usbserial1", { baudRate: 57600 });
Run Code Online (Sandbox Code Playgroud)
它由 Webpack 构建,具有以下配置(为简洁起见进行了修剪):
const config = {
entry: { renderer: ["./src/renderer"] }
output: {
path: `${__dirname}/dist`,
filename: "[name].js",
},
target: "electron-renderer",
node: false, // Disables __dirname mocking and such
};
Run Code Online (Sandbox Code Playgroud)
它由开发服务器以及 , 提供服务index.html,并由主进程作为网页加载(这是开发期间热模块替换所需要的)。
主进程由 Webpack 构建并发出dist。Webpack 插件还会生成以下内容dist/package.json:
{
"name": "my-app",
"main": "main.js"
}
Run Code Online (Sandbox Code Playgroud)
当我运行时electron dist,渲染器进程崩溃并出现以下错误:
Uncaught TypeError: Path must be a string. Received undefined
at assertPath (path.js:28)
at dirname (path.js:1364)
at Function.getRoot (bindings.js?dfc1:151)
at bindings (bindings.js?dfc1:60)
at eval (linux.js?d488:2)
at Object../node_modules/serialport/lib/bindings/linux.js (renderer.js:12686)
at __webpack_require__ (renderer.js:712)
at fn (renderer.js:95)
at eval (auto-detect.js?3cc7:16)
at Object../node_modules/serialport/lib/bindings/auto-detect.js (renderer.js:12638)
Run Code Online (Sandbox Code Playgroud)
我该如何解决?
Ole*_*evs 13
第一个问题是node-bindings,它node-serialport依赖于解析其 Node.js 插件的路径,在 Electron 中根本不起作用。有一个悬而未决的问题对于这一点,我不认为相关的公关甚至是一个完整的修复,因为我已经做了一些调试,并且看起来fileName遗迹undefined遍布全getFileName。
第二个问题:即使它以某种方式找到了serialport.node某个地方,在打包分发应用程序后也不起作用,因为插件本身不在dist目录中,Webpack 不能将它与主 JS 文件捆绑在一起。
如果node-loader工作正常,可以尝试使用 解决此问题node-bindings,但这没有帮助,因为node-bindings应用复杂的启发式,其中的WebPack根本无法从外推,试图了解哪些文件可以通过它来在需要时require。Webpack 可以做的唯一安全的事情就是包含整个项目,“以防万一”,显然这node-loader是绝对不行的,所以不要复制任何东西。
所以,我们需要更换 node-bindingsserialport.node手动和复制。
首先,我们必须获取插件并将其放入dist. 这需要在 main 的 Webpack 构建中完成,因为渲染器用作网页,可能来自内存文件系统(因此*.node文件可能不会发送到磁盘,并且 Electron 永远不会看到它)。就是这样:
import CopyWebpackPlugin from "copy-webpack-plugin";
const config = {
// ...
plugins: [
new CopyWebpackPlugin([
"node_modules/serialport/build/Release/serialport.node",
]),
],
// ...
};
Run Code Online (Sandbox Code Playgroud)
不幸的是,硬编码,但如果发生变化,很容易修复。
其次,我们必须node-bindings用我们自己的垫片代替src/bindings.js:
module.exports = x =>
__non_webpack_require__(
`${require("electron").remote.app.getAppPath()}/${x}`
);
Run Code Online (Sandbox Code Playgroud)
__non_webpack_require__是不言自明的(是的,require如果没有一些技巧,它是由 Webpack 处理的,那么简单require("electron").remote.app.getAppPath()是行不通的),并且这是必要的,因为__dirname实际上并没有解决人们所期望的 - 绝对路径dist- 而是某个目录深埋在 Electron 内部。
这是在渲染器的 Webpack 配置中完成替换的方式:
import { NormalModuleReplacementPlugin } from "webpack";
const config = {
// ...
plugins: [
new NormalModuleReplacementPlugin(
/^bindings$/,
`${__dirname}/src/bindings`
),
],
// ...
};
Run Code Online (Sandbox Code Playgroud)
就是这样!完成上述操作后,某个服务器(或任何您的方法)正在为index.html+renderer.js提供服务,dist看起来像这样:
dist/
main.js
package.json
serialport.node
Run Code Online (Sandbox Code Playgroud)
electron dist 应该“正常工作”。
可能逃脱添加node-serialport作为一个依赖所产生的dist/package.json,只是npm i在那里nstalling它,和标记serialport为的WebPack外部,而是那种感觉更脏(包版本不匹配,等等)。
另一种方法是将所有内容都声明为外部对象,并为您electron-packager复制node_modulesto的整个生产部分dist,但这基本上是一大堆兆字节。
| 归档时间: |
|
| 查看次数: |
3240 次 |
| 最近记录: |