electron 当contextIsolation:true时,React组件不会在电子应用程序中渲染,但当设置为false时,渲染效果良好

svgewumm  于 11个月前  发布在  Electron
关注(0)|答案(1)|浏览(129)

我目前正在尝试学习react框架,并将我的电子应用程序从标准的Electron + HTML/CSS转换为react,但正如我所知,如果不将contextIsolation设置为true,你就不能使用preload.js文件,但出于某种原因,每当我将其设置为true时,我的react组件根本不会呈现,窗口打开得很好,控制台中没有错误,但组件只是不渲染/加载。有人知道我做错了什么吗?我为每个应用程序使用的版本是Electron(28.0.0),React(18.2.0),React-Dom(18.2.0).我试过降级一些或所有包的版本,我的react组件渲染的问题严格源于contextIsolation:true.我已经编辑了这个问题,以包括我的webpack.config.js
./GUI/Auth/auth.jsx

import React, { useState, useEffect } from 'react';
import LunarLogo from '../../Dependencies/lunar.png';
import './auth.css';

function Auth() {
  const [licenseKey, setLicenseKey] = useState('');
  const [authMessage, setAuthMessage] = useState('');

  const handleLogin = () => {
    if (licenseKey) {
        window.electron.validateLicense(licenseKey);
        
    } else {
        setAuthMessage('Input License Key');
    }
  };

  return (
    <div className="split-screen">
      <div class="drag-area"></div>
        <div className="left-pane">
            <div className="logo-container">
              <img src={LunarLogo} alt="Lunar Logo" className="logo" />
              <h1 className="app-name">Lunar Tools</h1>
            </div>
            <div className="welcome-text">
              <h2>Welcome to Lunar Tools</h2>
              <p>The last toolbox you'll ever need. Supporting all your botting needs!</p>
            </div>
            <div className="login-container">
              <span className="login-heading">Login</span>
              <p className="license-key-instruction">Enter your license key to continue</p>
              <input 
                type="text" 
                placeholder="Enter Key" 
                className="license-input"
                value={licenseKey}
                onChange={(e) => setLicenseKey(e.target.value)}
              />
              <div className="button-container">
                <button className="login-btn" onClick={handleLogin}>Login</button>
                <button className="support-btn">Support</button>
              </div>
            </div>
            {authMessage && (
              <div className="authentication-status">
                <span style={{ color: '#B52D2D' }}>{authMessage}</span>
              </div>
            )}
        </div>
        <div className="right-pane">
          <img src={LunarLogo} alt="Clipart" className="right-clipart" />
        </div>
    </div>
  );
}

export default Auth;

字符串
./GUI/index.js

import React from "react";
import ReactDOM from "react-dom/client";
import Auth from './Auth/auth';
import './index.css';

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Auth />
  </React.StrictMode>
);


./GUI/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lunar</title>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet">
    <script src="https://kit.fontawesome.com/6483512793.js" crossorigin="anonymous"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>


main.js

require('dotenv').config();
const fs = require('fs');
const os = require('os');
const path = require('path');
const { app, BrowserWindow, ipcMain } = require('electron');
const { autoUpdater, appUpdater } = require('electron-updater');
require('@electron/remote/main').initialize();

const discordRpc = require('./Functions/discordRpc');
const { startServer } = require('./Functions/server');
const { 
  decidePageToLoad, 
  validateLicenseHandler, 
  userDatabaseConnection, 
  applicationLaunched, 
  securityCheck 
} = require('./Functions/auth');

let mainWindow = null;
let serverAlreadyStarted = false;
const isDev = process.env.ELECTRON_ENV == 'dev';

autoUpdater.autoDownload = false;
autoUpdater.autoInstallOnAppQuit = true;

ipcMain.on('start-download', (event) => {
  autoUpdater.downloadUpdate();
});


autoUpdater.on('checking-for-update', () => {
  console.log('Checking for updates...');
});

autoUpdater.on('update-available', (info) => {
  showUpdatePopup(info);
});
  
autoUpdater.on('update-not-available', (info) => {
  console.log('No updates available.', info);  
});

autoUpdater.on('error', (err) => {
  console.error('Error in auto-updater:', err);
});

autoUpdater.on('download-progress', (progressObj) => {
  let log_message = `Download speed: ${progressObj.bytesPerSecond}`;
  log_message = log_message + ` - Downloaded ${progressObj.percent}%`;
  log_message = log_message + ` (${progressObj.transferred}/${progressObj.total})`;
  
  win.webContents.send('download-progress', progressObj);
});

autoUpdater.on('update-downloaded', (info) => {
  autoUpdater.quitAndInstall();
});

const renderWindow = async () => {
  mainWindow = new BrowserWindow({
    width: 1400,
    height: 800,
    minWidth: 1400,
    minHeight: 800,
    frame: false,
    backgroundColor: '#0E0F16',
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: true,
      devTools: isDev,
      preload: path.join(__dirname, 'preload.js')
    },
    icon: path.join(__dirname, './GUI/Dependencies/Lunar Logo.png'),
    resizable: true
  });
  require('@electron/remote/main').enable(mainWindow.webContents);

  ipcMain.on('validate-license', (event, inputLicenseKey) => {
    validateLicenseHandler(event, inputLicenseKey, mainWindow);
  });

  if (isDev) {
    mainWindow.loadURL('http://localhost:3000/');

  } else {
    mainWindow.loadFile('./build/index.html');
  }

  mainWindow.setMenu(null);
  mainWindow.webContents.openDevTools();
  /* mainWindow.webContents.on('devtools-opened', () => {
    mainWindow.webContents.closeDevTools();
  }); */

  ipcMain.on('validate-license', (event, inputLicenseKey) => {
    validateLicenseHandler(event, inputLicenseKey, win);
  });

  discordRpc();
  applicationLaunched();
  setInterval(() => {
    securityCheck()
  }, 10000);

  ipcMain.on('request-server-status', (event) => {
    if (!serverAlreadyStarted) {
      startServer((status) => {
        serverAlreadyStarted = true; 
        win.webContents.send('server-status-reply', status);
      });
    } else {
      win.webContents.send('server-status-reply', 'Connected');
    }
  });
};

app.commandLine.appendSwitch('ignore-gpu-blacklist');
app.disableHardwareAcceleration();
app.whenReady().then(() => {
  process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true';
  renderWindow();
  require('./Functions/discordRpc');
  autoUpdater.checkForUpdates();
});

module.exports.getMainWindow = () => mainWindow;


webpack.config.js

const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const HtmlWebPackPlugin = require('html-webpack-plugin');

module.exports = [
  {
    entry: './main.js',
    name: 'electron',
    target: 'electron-main',
    externals: [nodeExternals()],
    resolve: {
      extensions: [".*",".js",".json"]
    },
    output: {
      path: __dirname + '/build',
      publicPath: '/',
      filename: 'app.js'
    },
    plugins: []
  },
  {
    entry: './GUI/index.js',
    name: 'react',
    target: 'electron-renderer',
    module: {
      rules: [
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules/,
          use: ['babel-loader']
        },
        { test: /\.css$/, use: ['style-loader', 'css-loader'] },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: ['file-loader']
        }
      ]
    },
    resolve: {
      extensions: [".*",".js",".jsx",".json",".css",".svg"]
    },
    output: {
      path: __dirname + '/build',
      publicPath: './',
      filename: 'bundle.js'
    },
    devServer: {
      static: {
        directory: __dirname + '/build/',
      },
      compress: true
    },
    plugins: [
      new HtmlWebPackPlugin({
        filename: 'index.html',
        template: 'GUI/index.html'
      })
    ]
  }
];


preload.js

const remote = require('@electron/remote');
const { contextBridge, ipcRenderer, shell } = require('electron');

contextBridge.exposeInMainWorld('electron', {
    close: () => remote.getCurrentWindow().close(),
    minimize: () => remote.getCurrentWindow().minimize(),
    getCurrentWindow: () => remote.getCurrentWindow(),
    receive: (channel, func) => {
        ipcRenderer.on(channel, (event, ...args) => func(...args));
    },
    validateLicense: (licenseKey) => {
        ipcRenderer.send('validate-license', licenseKey);
    },
    onAuthenticationFailed: (callback) => {
        ipcRenderer.on('authentication-failed', (event, message) => {
            callback(message);
        });
    },
    clearAuthenticationMessage: () => {
        ipcRenderer.removeAllListeners('authentication-failed');
    }
});

gpfsuwkq

gpfsuwkq1#

我已经解决了我的问题,在任何或所有的jsx文件中,我不能直接从electron包中调用import ipcRenderer,我也不能使用这个命令cross-env ELECTRON_ENV=dev electron ./build/app.js,我必须直接运行

electron .

字符串
使用我的main.js,而不是webpack中捆绑的app.js。

相关问题