久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

在帶有 Webpack 的 Electron 渲染器中使用 Node.js 插件

Using Node.js addons in Electron#39;s renderer with Webpack(在帶有 Webpack 的 Electron 渲染器中使用 Node.js 插件)
本文介紹了在帶有 Webpack 的 Electron 渲染器中使用 Node.js 插件的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

我有以下渲染器:

import SerialPort from "serialport";

new SerialPort("/dev/tty-usbserial1", { baudRate: 57600 });

它由 Webpack 構(gòu)建,具有以下配置(為簡潔起見):

It's built by Webpack, with the following config (trimmed for brevity):

const config = {
  entry: { renderer: ["./src/renderer"] }
  output: {
    path: `${__dirname}/dist`,
    filename: "[name].js",
  },
  target: "electron-renderer",
  node: false, // Disables __dirname mocking and such
};

它由開發(fā)服務(wù)器提供服務(wù),與 index.html 一起,并由主進(jìn)程作為網(wǎng)頁加載(這是開發(fā)過程中熱模塊更換所需要的).

It's served by a development server, along with an index.html, and is loaded by the main process as a web page (this is needed for hot module replacement during development).

主進(jìn)程由 Webpack 構(gòu)建并發(fā)送到 dist.Webpack 插件還會生成以下 dist/package.json:

The main process is built by Webpack and emitted to dist too. A Webpack plugin also generates the following dist/package.json:

{
  "name": "my-app",
  "main": "main.js"
}

當(dāng)我運(yùn)行 electron dist 時,渲染器進(jìn)程崩潰并出現(xiàn)以下錯誤:

When I run electron dist, the renderer process crashes with the following error:

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)

我該如何解決這個問題?

How do I fix this?

推薦答案

問題

第一個問題是 node-bindingsnode-serialport 依賴于解析其 Node.js 插件的路徑,在 Electron 中根本不起作用.有一個 未決問題 ,我認(rèn)為相關(guān)的 PR 不是甚至是一個完整的修復(fù),因?yàn)槲乙呀?jīng)進(jìn)行了一些調(diào)試,并且似乎 fileName 在整個 getFileName 中仍然是 undefined.

Problem

The first problem is that node-bindings, which node-serialport relies on to resolve the path to its Node.js addon, simply doesn't work in Electron. There's an open issue for this, and I don't think the associated PR is even a complete fix, since I've done some debugging, and it appears that fileName remains undefined throughout the whole getFileName.

第二個問題:即使它以某種方式在某處找到了 serialport.node,在打包應(yīng)用程序以進(jìn)行分發(fā)后它也無法工作,因?yàn)椴寮旧聿辉?dist 中 目錄,Webpack 不能把它和主 JS 文件捆綁在一起.

The second problem: even if it somehow found a serialport.node somewhere, it wouldn't work after packaging the application for distribution, since the addon itself isn't in the dist directory, and Webpack can't just bundle it together with the main JS file.

可以嘗試使用 node-loader,給定一個正確工作的 node-bindings,但這也無濟(jì)于事,因?yàn)?node-bindings 使用精細(xì)的啟發(fā)式方法,Webpack 根本無法從中推斷,當(dāng)試圖了解其 require 可能需要哪些文件.Webpack 可以做的唯一安全的事情是包含整個項(xiàng)目,以防萬一",顯然這是絕對不行的,所以 node-loader 只是不復(fù)制任何東西.

One could attempt to solve this with node-loader, given a correctly working node-bindings, but that wouldn't help either, since node-bindings uses elaborate heuristics, which Webpack simply can't extrapolate from, when trying to understand what files could be required by its require. The only safe thing Webpack could do is include the whole project, "just in case", and that's a certain no-go, obviously, so node-loader just doesn't copy anything.

所以,我們需要手動替換node-bindings并復(fù)制serialport.node.

So, we need to replace node-bindings and copy serialport.node manually.

首先,我們必須抓取插件并將其放入dist.這需要在 main 的 Webpack 構(gòu)建中完成,因?yàn)殇秩酒髯鳛榫W(wǎng)頁提供,可能來自內(nèi)存中的文件系統(tǒng)(因此 *.node 文件可能不會發(fā)送到磁盤,而 Electron永遠(yuǎn)不會看到它).方法如下:

First, we must grab the addon and put it in dist. This needs to be done in main's Webpack build, since the renderer is served as web page, potentially from an in-memory file system (so the *.node file may not be emitted to disk, and Electron will never see it). Here's how:

import CopyWebpackPlugin from "copy-webpack-plugin";

const config = {
  // ...
  plugins: [
    new CopyWebpackPlugin([
      "node_modules/serialport/build/Release/serialport.node",
    ]),
  ],
  // ...
};

不幸的是,硬編碼,但如果發(fā)生變化,很容易修復(fù).

Hardcoded, unfortunately, but easy to fix if something changes.

其次,我們必須用我們自己的 shim 替換 node-bindingssrc/bindings.js:

Second, we must substitute node-bindings with our own shim, src/bindings.js:

module.exports = x =>
  __non_webpack_require__(
    `${require("electron").remote.app.getAppPath()}/${x}`
  );

__non_webpack_require__ 是不言自明的(是的,普通的 require 不起作用,沒有一些技巧,因?yàn)樗?Webpack 處理),并且 require("electron").remote.app.getAppPath() 是必要的,因?yàn)?__dirname 實(shí)際上并沒有解決人們所期望的 - dist 的絕對路徑- 而是放到 Electron 深處的某個目錄.

__non_webpack_require__ is self-explanatory (yes, plain require won't work, without some trickery, as it's handled by Webpack), and the require("electron").remote.app.getAppPath() is necessary because __dirname doesn't actually resolve to what one would expect - an absolute path to dist - but rather to some directory buried deep inside Electron.

在渲染器的 Webpack 配置中,替換是這樣完成的:

And here's how the replacement is done, in renderer's Webpack config:

import { NormalModuleReplacementPlugin } from "webpack";

const config = {
  // ...
  plugins: [
    new NormalModuleReplacementPlugin(
      /^bindings$/,
      `${__dirname}/src/bindings`
    ),
  ],
  // ...
};

就是這樣!一旦完成上述操作,并且 index.html + renderer.js 正在由某個服務(wù)器(或任何您的方法)提供服務(wù),并且 dist看起來像這樣:

And that's it! Once the above is done, and index.html + renderer.js are being served by some server (or whatever your approach is), and the dist looks something like this:

dist/
  main.js
  package.json
  serialport.node

electron dist 應(yīng)該正常工作".

node-serialport 作為對生成的 dist/package.json 的依賴項(xiàng)添加并且只需 npm installing 可能會成功在那里,并將 serialport 標(biāo)記為 Webpack 中的外部,但這感覺更臟(包版本不匹配等).

Could potentially get away with adding node-serialport as a dependency to the generated dist/package.json and just npm installing it in there, and marking serialport as an external in Webpack, but that feels even dirtier (package version mismatches, etc.).

另一種方法是將所有內(nèi)容聲明為外部,并讓 electron-packager 只需將 node_modules 的整個生產(chǎn)部分復(fù)制到 dist 即可你,但那是一大堆兆字節(jié),基本上什么都沒有.

Another way is to just declare everything as externals, and have electron-packager just copy the whole production part of node_modules to dist for you, but that's a whole lot of megabytes for basically nothing.

這篇關(guān)于在帶有 Webpack 的 Electron 渲染器中使用 Node.js 插件的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

How to fix BrowserWindow is not a constructor error when creating child window in Electron renderer process(在 Electron 渲染器進(jìn)程中創(chuàng)建子窗口時如何修復(fù) BrowserWindow 不是構(gòu)造函數(shù)錯誤) - IT屋-程序員軟件開發(fā)技術(shù)
mainWindow.loadURL(quot;https://localhost:3000/quot;) show white screen on Electron app(mainWindow.loadURL(https://localhost:3000/) 在 Electron 應(yīng)用程序上顯示白屏)
Electron webContents executeJavaScript : Cannot execute script on second on loadURL(Electron webContents executeJavaScript:無法在第二個 loadURL 上執(zhí)行腳本)
how to use electron browser window inside components in angular-cli?(如何在angular-cli的組件內(nèi)使用電子瀏覽器窗口?)
ElectronJS - sharing redux store between windows?(ElectronJS - 在 Windows 之間共享 redux 存儲?)
How to access camera/webcamera inside electron app?(如何在電子應(yīng)用程序中訪問相機(jī)/網(wǎng)絡(luò)攝像頭?)
主站蜘蛛池模板: 亚洲精品国产电影 | 亚欧洲精品在线视频免费观看 | 国产日日操 | 亚洲精品二区 | 黑人一级片视频 | 精品久久久久久亚洲精品 | 日韩中文一区二区三区 | 久久av资源网 | 国产精品日韩一区 | 综合一区二区三区 | 日韩美女在线看免费观看 | 国内自拍真实伦在线观看 | 天天澡天天狠天天天做 | 一本色道精品久久一区二区三区 | 在线不卡一区 | 国产不卡一区在线观看 | www.天天操 | 日韩中文字幕在线观看视频 | 日本一区二区高清视频 | 亚洲国产精品久久人人爱 | 日本在线免费观看 | 在线黄色网 | 日韩久久久久久久久久久 | 欧美一区二区三区大片 | 韩国久久 | 黄在线免费观看 | 日韩成人av在线播放 | 九九热精品视频 | 亚洲热在线视频 | 国产一区二区免费 | 亚洲色图图片 | 精品福利在线 | 成人亚洲| 成人午夜网 | 日韩精品一区二区三区第95 | 精品久久久久国产 | 黄色片在线免费看 | 99精品视频免费在线观看 | 久久国产婷婷国产香蕉 | 无人区国产成人久久三区 | 欧美阿v|