我目前正在尝试学习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');
}
});
型
1条答案
按热度按时间gpfsuwkq1#
我已经解决了我的问题,在任何或所有的jsx文件中,我不能直接从electron包中调用
import ipcRenderer
,我也不能使用这个命令cross-env ELECTRON_ENV=dev electron ./build/app.js
,我必须直接运行字符串
使用我的main.js,而不是webpack中捆绑的app.js。