如何在编译时设置电子变量?

Posted

技术标签:

【中文标题】如何在编译时设置电子变量?【英文标题】:How do I set an Electron variable at compile time? 【发布时间】:2021-04-24 04:29:13 【问题描述】:

我正在使用 electron-builder 打包一个 React 应用程序。我的应用使用 create-react-app 样板。

有没有办法可以在编译时设置变量,以便在运行时在主进程的代码中用于条件...?

我正在寻找与 C 的预处理器宏等效的东西。所以我可以这样做:

electron-builder --extraConfig BUILD_TYPE=testing

然后在我的 main.js 中:

if (extraConfig.BUILD_TYPE === 'testing') // do stuff

【问题讨论】:

【参考方案1】:

我以前做过这个,但除了你已经拥有的之外,我还在使用electron-webpack

electron ^11.2.0
electron-builder ^22.9.1
electron-webpack ^2.8.2
webpack ^4

这个想法是通过webpack.DefinePlugin 公开一个变量,您可以为您的主进程和渲染器进程执行此操作。

使用electron-webpack,您可以为两个进程提供webpack 配置:

// webpack.main.config.js
const webpack = require('webpack');
module.exports = 
  plugins: [ new webpack.DefinePlugin(__BURRITO__: true) ]
;

// webpack.renderer.config.js
const webpack = require('webpack');
module.exports = 
  plugins: [ new webpack.DefinePlugin(__TACO__: true) ]
;

这两个文件通过package.json 中的一些配置暴露给electron-webpack


  …
  "electronWebpack": 
    "main": 
      "webpackConfig": "webpack.main.config.js"
    ,
    "renderer": 
      "webpackConfig": "webpack.renderer.config.js"
    
  

然后在你的主进程中:

// src/main/index.js
const app, BrowserWindow = require('electron')

app.whenReady().then(() => 
  const mainWindow = new BrowserWindow(webPreferences: nodeIntegration: true);
  console.log(__BURRITO__ ? "?" : "?");
  mainWindow.loadURL(`http://localhost:$process.env.ELECTRON_WEBPACK_WDS_PORT`);
);

两件事:

    .loadURL 位看起来很有趣,但这只是因为我在渲染器中使用了electron-webpack 默认 html 模板。在开发期间,它通过这个本地服务器提供服务。

    您不需要启用nodeIntegration 标志。那只是因为electron-webpack 默认渲染器模板在这里和那里使用了一些require 语句。

如果您的渲染器进程包含一些脚本,它们也可以访问您的 at-compile-time 变量。这里我再次使用electron-webpack 默认模板,它自动需要src/renderer/index.js

// src/renderer/index.js
if (__TACO__) 
  document.body.innerHTML = "?"

当您通过electron-webpack dev 运行此程序时,您可以看到两件事:

    在主进程的输出中看到一个卷饼 在渲染器进程的 html 中看到一个 taco

这说明electron-webpack在编译时成功注入了两个变量。

【讨论】:

谢谢!你在使用 create-react-app ...?如果我按照上面的说明进行操作,我会收到错误 Support for the experimental syntax 'jsx' isn't currently enabled 然后是 Add @babel/preset-react (https://git.io/JfeDR) to the 'presets' section of your Babel config to enable transformation。有什么想法吗? 我不是,但我肯定在我正在处理的项目中使用 React 和 Babel,它使用了这种方法并且效果很好。不过,设置 Babel 和 React 可能是一段漫长而令人沮丧的旅程!【参考方案2】:

我会将electron-builder 命令放在 NPM 脚本中,然后预先运行另一个脚本以在 .txt 文件中设置 BUILD_TYPE

像这样:

package.json:

"scripts": 
    "distProd": "node ./setBuildType.js prod && electron-builder",
    "distDev": "node ./setBuildType.js dev && electron-builder",

然后在setBuildType.js

// process.argv[2] Contains the type.
fs.writeFile('./BUILD_TYPE.txt', process.argv[2], function (errObj) 
    if (errObj) 
        console.log(errObj);
    
);

然后从您的应用中获取BUILD_TYPE

// Always set `BUILD_TYPE` to `dev` when running from the terminal.
if (!app.isPackaged) 
    var BUILD_TYPE = fs.readFileSync('./BUILD_TYPE.txt');
 else 
    var BUILD_TYPE = 'dev';

console.log(BUILD_TYPE); // Outputs "prod" or "dev".

这将检查它是从安装程序还是从终端运行,如果它是从终端运行,那么它将始终将 BUILD_TYPE 设置为 dev

【讨论】:

以上是关于如何在编译时设置电子变量?的主要内容,如果未能解决你的问题,请参考以下文章

uBoot编译时无法设置环境变量

如何在os x下让sublime text编译c程序

预编译时的 Sass 未定义变量

gcc 编译错误:“在调用 always_inline 时内联失败”,即使在设置 cflags 环境变量后也是如此

怎样在windows下安装JAVA环境并配置环境变量,并且怎样编译和运行JAVA程序?

如何开发编译部署调用智能合约