使用 Electron 应用程序打包 Keytar

Posted

技术标签:

【中文标题】使用 Electron 应用程序打包 Keytar【英文标题】:Packaging Keytar with an Electron app 【发布时间】:2017-08-31 05:41:49 【问题描述】:

我正在使用 electron-builder (16.6.2) 打包我的电子应用程序,其中包括 keytar (3.0.2) 作为产品依赖项。

package.json 文件包括:

"scripts": 
    "postinstall": "install-app-deps",
    "compile:dev": "webpack-dev-server --hot --host 0.0.0.0 --config=./webpack.dev.config.js",
    "compile": "webpack --config webpack.build.config.js",
    "dist": "yarn compile && build"
,
"build": 
    "appId": "com.myproject",
    "asar": true,
    "files": [
      "bin",
      "node_modules",
      "main.js"
    ]

当我在同一系统上运行 .app 时,它运行良好。当我尝试在不同的系统上运行它(或删除我的 node_modules)时,它找不到 keytar.node。构建 keytar 时,它包含我系统的该映像的完全限定路径。我在控制台中收到以下错误:

Uncaught Error: Cannot open /Users/Kevin/Work/myproject/node_modules/keytar/build/Release/keytar.node
Error: dlopen(/Users/Kevin/Work/myproject/node_modules/keytar/build/Release/keytar.node, 
1): image not found

我一定是在构建过程中遗漏了一个步骤。

【问题讨论】:

【参考方案1】:

事实证明,我在渲染器进程中使用了 keytar。我将 keytar 移到主进程中(不通过 Webpack / Babel),并由电子生成器正确打包。

main.js

ipcMain.on('get-password', (event, user) => 
    event.returnValue = keytar.getPassword('ServiceName', user);
);

ipcMain.on('set-password', (event, user, pass) => 
    event.returnValue = keytar.replacePassword('ServiceName', user, pass);
);

然后我可以从渲染器进程调用

const password = ipcRenderer.sendSync('get-password', user);

ipcRenderer.sendSync('set-password', user, pass);

【讨论】:

我重构了我的应用程序,只在主线程中调用 keytar,使用来自渲染器线程的 IPC。但是,由于使用 webpack 转译所有代码,我的应用程序运行良好,直到我与 keytar 交互,然后我遇到:TypeError: keytar.findPassword is not a function,请参阅this Github issue。【参考方案2】:

更新: 我发现(根据 OP)转译我的主线程代码(使用 keytar)导致调用 keytar 函数返回 TypeError: keytar.findPassword is not a function

我必须从我的 webpack 配置中删除主线程代码入口点,这样 babel 才不会触及它。我将我的主线程源代码包含在我的应用程序中,未捆绑/未转译,它运行良好。

以下信息仍然代表在您的 webpack 构建中包含二进制资产。


如果您必须转译需要二进制文件的代码,您可以将 file-loader 添加到您的 webpack 配置中。

安装

npm i -D file-loaderyarn add -D file-loader

webpack 配置(包括.dat 文件)

...,
module: 
  rules: [
    ...
  , 
    test: /\.dat$/,
    use: 
      loader: "file-loader"
    
  ]
,
...

如果要保留文件名,可以将name 选项传递给加载程序:

use: 
  loader: "file-loader",
  options: 
    name: "[name].[ext]"
  

有关file-loader Github repo的更多信息。

【讨论】:

【参考方案3】:
window.require("electron").remote.require("keytar")

由于您正在处理渲染器进程并希望使用系统或主进程中的本机 api。

【讨论】:

以上是关于使用 Electron 应用程序打包 Keytar的主要内容,如果未能解决你的问题,请参考以下文章

使用electron进行原生应用的打包

electron教程: 使用electron-builder或electron-packager将项目打包为可执行桌面程序(.exe)

使用electron进行原生应用的打包---主进程与渲染进程之间的通信

将现有vue项目基于electron打包成桌面应用程序

Electron 应用部署

使用electron-packager electron-builder electron-updater 打包vue项目,支持在线更新