【问题标题】: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 }

【问题讨论】:

    标签: webpack electron create-react-app electron-builder


    【解决方案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}`);
    });
    

    两件事:

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

    2. 您不需要启用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 运行此程序时,您可以看到两件事:

    1. 在主进程的输出中看到一个卷饼
    2. 在渲染器进程的 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

    【讨论】:

      猜你喜欢
      • 2011-08-01
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2013-05-07
      相关资源
      最近更新 更多