Hallo
Ich verwende unter anderem Electron mit React.js und babelify (Liste unten).
Der Versuch, require('electron')
zu verwenden, um beispielsweise Zugriff auf BrowserWindow
von electron zu erhalten, führt dazu, dass die Konsole den folgenden Fehler anzeigt:
index.js:4 Uncaught TypeError: fs.readFileSync is not a function
Ich kann jedoch const electron = require('electron');
in main.js verwenden. Für das, was es wert ist, verwende ich auch watchify, um alles in ein js-Bundle zu packen.
Hier ist die vollständige Liste der Abhängigkeiten in meiner package.json:
"devDependencies": {
"axios": "^0.9.1",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babelify": "^7.2.0",
"classnames": "^2.2.3",
"electron": "^1.3.5",
"electron-reload": "^0.2.0",
"jquery": "^2.2.3",
"react": "^0.14.8",
"react-autocomplete": "^1.0.0-rc2",
"react-dom": "^0.14.7",
"react-sound": "^0.4.0",
"soundmanager2": "^2.97.20150601-a"
},
index.js:4 Uncaught TypeError: fs.readFileSync ist keine Funktion
Können Sie Zeile 4 von index.js
hier einfügen? Oder ein vollerer Stack-Trace?
Ich glaube, es bezieht sich auf index.js von Elektron, das sich selbst in Knotenmodulen des Projekts befindet. Hier sind die Inhalte dieser Datei:
var fs = require('fs')
var path = require('path')
module.exports = path.join(__dirname, fs.readFileSync(path.join(__dirname, 'path.txt'), 'utf-8'))
Der gesamte Stack-Trace deutet auf einen Konflikt mit React.js hin:
Was passiert, wenn Sie require('fs').readFileSync
über die Registerkarte „Konsole“ der Entwicklertools ausführen?
Es sieht so aus, als würde das electron-prebuilt
-Knotenmodul (die von Ihnen eingefügte Datei) in Ihrer gepackten App landen, was Sie meiner Meinung nach nicht möchten, da es stattdessen das integrierte electron
-Requirement verwenden sollte.
@nukeop Wie startest du deine App? Ihr `Startskript sollte so aussehen.
"scripts": {
"start": "electron ."
}
Ich habe das Gefühl, dass Sie versuchen, Ihr main.js
mit Knoten auszuführen
node main.js
Was nicht funktionieren wird
Was passiert, wenn Sie require('fs').readFileSync auf der Registerkarte "Konsole" der Entwicklertools ausführen?
Unmittelbar nachdem dieser Fehler ausgelöst wurde, kann ich require('fs').existsSync
in der Konsole ausführen, um eine Definition der Funktion zu drucken. Es funktioniert auch vor dem Fehler.
Es sieht so aus, als würde das von Electron vorgefertigte Knotenmodul (die Datei, die Sie eingefügt haben) in Ihrer gepackten App landen, was Sie meiner Meinung nach nicht wollen, da es stattdessen das eingebaute Electron require verwenden sollte.
Während ich entwickle, läuft im Hintergrund eine Watchify-Instanz, die mein Paket ständig aktualisiert. Ich habe es im scripts-Abschnitt von package.json wie folgt definiert:
"watch": "watchify app/app.js -t babelify -o public/js/bundle.js --debug --verbose"
Irgendwelche Ratschläge zur Vermeidung der Bündelung electron-prebuilt
?
@nukeop Electron unterstützt intern erfordern, sodass Sie browserify nicht verwenden müssen.
Soweit mir bekannt ist, möchten Sie browserify verwenden, müssen Sie "Elektron" ausschließen.
Interessant, könnte es sein, dass watchify/browserify dies ruiniert? Es hat bisher ok funktioniert.
Jetzt bin ich mir nicht sicher, wie ich das Programm ohne es ausführen soll.
Laufen Sie buchstäblich nur
electron .
Aus Ihrem Haupt-App-Ordner müssen Sie nichts bündeln, wenn Sie Electron verwenden, da es intern über eine vollständige Knotenumgebung verfügt.
_Ich werde dies schließen, da es sich um ein Browserify-Problem handelt_
Das habe ich die ganze Zeit gemacht, das Programm in eine einzige .js-Datei gepackt, die in einer einfachen HTML-Datei enthalten ist mit:
<script src="public/js/bundle.js">
</script>
Und alles funktioniert, außer wenn ich require verwende. Dies ist ein Problem bei der Interaktion zwischen den beiden Modulen.
Wenn ich nicht das ganze Programm in ein Bundle packe, habe ich keine einfache Möglichkeit, es auszuführen, da meine main.js nur electron startet und die HTML-Datei lädt, die das Bundle enthält.
@nukeop Der Renderer-Prozess in Electron hat auch Zugriff auf eine vollständige Node/Commonjs-Umgebung, sodass Sie nichts bündeln müssen.
Wenn ich nicht das ganze Programm in ein Bundle packe, habe ich keine einfache Möglichkeit, es auszuführen, da meine main.js nur electron startet und die HTML-Datei lädt, die das Bundle enthält.
Ich bin mir nicht sicher, ob ich das hier verstehe, jedes Skript, das Sie in Ihre HTML-Datei laden, hat eine vollständige commonjs-Umgebung und kann daher require
verwenden, um zusätzliche Dateien zu laden, ohne etwas zu durchsuchen
Für alle, die in Zukunft auf dieses Problem stoßen und diesen Thread lesen, ist die Verwendung window.require
anstelle von require eine Möglichkeit, den Konflikt zwischen der Funktion require
von electron und browserify zu vermeiden.
FWIW, ich bin auf das gleiche Problem gestoßen, als ich versuchte, Elektron im Renderer-Prozess mit create-react-app zu verwenden, das webpack im Backend anstelle von browserify verwendet. window.require
scheint es auch für mich zu lösen, obwohl mir nicht ganz klar ist, warum.
Bearbeiten : Ich habe herausgefunden, warum :-) Wir wollen require
electron
während der Laufzeit aus der zur Laufzeit bereitgestellten nodejs-Umgebung und nicht aus der nodejs-Umgebung, die während der Kompilierung durch das Webpack verwendet wird. Standardmäßig sind Globals an window
gebunden und die Webpack-Kompilierung ignoriert das Globale window
- daher funktioniert window.require
.
Eine andere Möglichkeit, webpack anzuweisen, einen globalen Namen zu ignorieren, besteht darin, einen Kommentar wie /*global Android*/
in der JS-Datei zu verwenden. In einem anderen Projekt, bei dem eine von CRA erstellte App in einem Android-WebView verwendet wurde, habe ich das obige verwendet, um Zugriff auf ein Java-Objekt zu erhalten, das JS über die von Webview bereitgestellte JavaScript-Schnittstelle bereitgestellt wird.
@nukeop - danke für deinen letzten Beitrag; es hat mir sehr geholfen. window.require
hat bei mir funktioniert.
Ja, mein Problem beim Erstellen einer Reaktions-App / Webpack wurde behoben.
Veränderung
import electron, { ipcRenderer } from 'electron'
zu
const electron = window.require("electron")
@srinathh wie stellen Sie Ihre CRA-App als Renderer in Ihrem Main zur Verfügung / laden Sie sie? bauen Sie zuerst (und ändern die statischen HTML-Ressourcenpfade)
Ja, mein Arbeitsablauf besteht derzeit darin, npm run build
mit den CRA-Skripten auszuführen und dann die Ausgabe im Ordner build
mit Elektron auszuführen. Sie müssen die statischen Ressourcenpfade nicht manuell ändern. In den package.json
für CRA-Skripten müssen Sie nur die homepage
wie folgt festlegen und die Pfade werden entsprechend festgelegt.
"homepage": "./"
Außerdem habe ich main.js
und package.json
für die Elektron-App im Ordner public
. Wenn Sie also den Build ausführen, werden sie automatisch kopiert und Sie können einfach electron build/
ausführen, um Ihre App zu starten.
Ich würde eigentlich gerne in der Lage sein, die npm start
mit Elektron für die Entwicklung zu machen, aber ich bin noch nicht dazu gekommen, herauszufinden, wie das funktioniert. Ich schätze, ich muss eject
machen und das Skript von Hand ändern.
Wenn Sie ein Beispiel für die Einrichtung sehen möchten, werfen Sie einen Blick auf https://github.com/srinathh/snippetfu
Ich verwende nicht Electron, sondern Node-Webkit (nw.js).
Die Verwendung window.require
hat auch mein Problem behoben. Vielen Dank dafür!
@nukeop window.require
hat es mir auch angetan, vielen Dank! 🎉
@nukeop Ich habe den gleichen Fehler, aber es ist gelöst window.require Trick, vielen Dank!
window.require
hat das Problem von fs.existsSync is not a function
gelöst, aber es führte zu einem weiteren Fehler: window.require
ist keine Funktion. Wie soll ich es lösen?
@steric85 verwendest du browserify, babel oder webpack? Möglicherweise müssen Sie Ihren Code transpilieren
@Alxmerino Ich verwende Webpack.
Stellen Sie sicher, dass Sie Ihren Code kompilieren
@ steric85 , ich habe das window.require is not a function
in Typoskript gesehen, ich habe es geschafft, es auf diese Weise zu beheben:
declare global {
interface Window {
require: any;
}
}
const electron = window.require('electron');
Ich verwende die obige Methode für den Zugriff auf den ipcRenderer von Elektron in meiner Angular-App, aber die Angular-Änderungserkennung funktioniert nicht, wenn ich ein Observable mit einem ipcRenderer-Nachrichtenhandler aktualisiere.
Liegt es daran, dass Angular nicht weiß, dass ipcRenderer ein EventEmitter ist und dass es eine Änderungserkennung ausführen muss, wenn ipcRenderer-Ereignisse eingehen?
In Angular 2 habe ich applicationRef.tick()
aufgerufen, um Angular explizit mitzuteilen, dass es seinen Zustand aktualisieren soll. https://angular.io/api/core/ApplicationRef
Ich stehe vor einem sehr ähnlichen Problem wie @nukeop und @srinathh : Ich habe mein Electron + React + Webpack-Projekt nach dieser Artikelanleitung eingerichtet, wo der Autor am Ende den Trick mit window.require
erwähnt. Ich habe nur require('electron')
zwei Stellen in meinem Projekt; im Einstiegspunkt für Electron und in einer JavaScript-Controller-Klasse, die von einigen React-Komponenten benötigt wird. In meiner Electron-Einstiegspunktdatei mache ich einfach const electron = require('electron');
, da es im Hauptprozess laufen sollte (richtig?), und in meiner Controller-Klasse mache ich const Electron = window.require('electron').remote;
gefolgt von const Jsonfile = Electron.require('jsonfile');
, was der richtige Weg sein sollte, da es im Renderer-Prozess ausgeführt wird. Aber ich bekomme den gleichen Fehler wie @nukeop ("TypeError: fs.ExistsSync is not a function") in Zeile sechs in node_modules/electron/index.js, der so aussieht:
var fs = require('fs')
var path = require('path')
var pathFile = path.join(__dirname, 'path.txt')
if (fs.existsSync(pathFile)) {
module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
} else {
throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
}
Ich habe versucht, node_modules/electron zu löschen und erneut zu installieren.
Ich verwende Electron 1.7.5 unter macOS 10.12.6 und starte mein Projekt mit npm run dev
als Setup im Artikel.
Aktualisieren; Ich habe das require
gefunden, das meinen Fehler verursacht hat. Ich habe versucht, require('electron-react-devtools')
in meiner React index.js auszuführen. Das Ändern in const ReactDevtools = Electron.require('electron-react-devtools');
hat die Fehler gestoppt, aber jetzt scheint es, dass ich .inject()
in der ReactDevtools-Instanz nicht aufrufen kann ("ist keine Funktion"), aber das sollte hier nicht besprochen werden .
@steric85 Das liegt daran, dass Sie die App in der Webseitenumgebung ausführen => Sie müssen die App in der Electron-Umgebung (Nodejs-Umgebung) ausführen.
Ich bekomme immer noch window.require is not a function
. Ich verwende Electron mit React Starter Kit (https://github.com/kriasoft/react-starter-kit). Alles funktioniert gut, außer diesem.
Ich habe meine Electron-App so eingestellt, dass sie meine App aus dem Internet lädt, sodass die App nicht lokal ausgeführt wird:
https://gist.github.com/holgersindbaek/68f6db82f507967a51ca75c527faeff6
Was ich versuche, ist, ipcRenderer
in einer meiner React-Dateien aufzurufen. Ich bin mir nicht sicher, ob es überhaupt möglich ist, wenn meine App aus dem Internet geladen wird. Irgendwelche Vorschläge?
@holgersindbaek Sie sollten Ihre App nicht in Browsern wie Chrome, Firefox usw. anzeigen. Es funktioniert nicht, da es sich um die Webseitenumgebung handelt.
Sie sollten Ihre App in einem Electron-Fenster anzeigen.
Das bin ich, aber ich verwende Electron so, dass ich meine App bei jedem Start von der Website lade. Im Wesentlichen zeige ich eine Website in meiner Elektron-App. Siehe obige Datei. Ich will nur sichergehen, dass ich wirklich nichts tun kann?!
Electron kann beliebige URLs laden. Um eine URL zu laden, verwenden Sie diese Funktion mainWindow.loadURL(url)
=> In der Elektronenfensteransicht kann dieser URL-Javascript-Code auf require, ipc usw. zugreifen.
In Ordnung. Ich werde das versuchen.
window.require
auf Elektron hat nicht funktioniert, aber window.require
für fs
hat funktioniert.
Nicht wirklich sicher, warum. Aber es funktioniert und da es sich um ein kleines persönliches Projekt handelt, werde ich das Thema nicht vorantreiben.
Danke @nukeop
Hallo, das ist meine package.json, ich benutze Webpack, keines davon hat mein Problem gelöst, hat jemand eine Lösung? Nachdem ich window.require verwendet habe, habe ich den Fehler "Fenster ist nicht definiert" erhalten.
'streng verwenden';
var Elektron = require('Elektron')
var app = elektron.app;
var BrowserWindow = Elektron.BrowserWindow;
var mainWindow = null;
app.on('bereit', function() {
mainWindow = new BrowserWindow({width: 800, height: 600});
mainWindow.loadURL('file://' + __dirname + '/index.electron.html');
mainWindow.webContents.openDevTools();
});
Ich verwende Typoskript und ich musste verwenden
const electron = (<any>window).require("electron");
um meinen Renderer dazu zu bringen, mit meinem Main zu kommunizieren. Hoffe, das hilft jemandem.
Das hat bei mir funktioniert.
Wenn Sie zB eine Fernbedienung benötigen, dann
const window deklarieren: any;
const {remote} = window.require('electron');
Hallo, danke Mann.
Am Sonntag, 3. Dezember 2017 um 21:29 Uhr, Michael - ሚካኤል ሰልጠነ <
[email protected]> schrieb:
Das hat bei mir funktioniert.
Wenn Sie zB eine Fernbedienung benötigen, dannconst window deklarieren: any;
const {remote} = window.require('electron');—
Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/electron/electron/issues/7300#issuecomment-348801405 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/ARDyd4c3aOkMbb058xklujMMbnmaoxKGks5s8uGVgaJpZM4KDU6t
.
@solominh Danke für deine Erklärungen hier . Ich habe jedoch eine ähnliche Konfiguration wie @holgersindbaek , welche Umgebung ist ein Preload-Skript in einer Webansicht?
Die Info:
mainWindow.loadURL(url)
, wobei url eine lokale index.html ist<webview>
preload
-Feld, das inject.js lädt, und dieses Skript führt window.require('electron') aus.Bemerkungen:
const electron = require('electron')
verwende, bekomme ich den Fehler fs.readFileSync is not a function
const electron = window.require('electron')
verwende, bekomme ich den Fehler window.require is not a function
.BEARBEITEN: Gelöst für mich mit <webview nodeintegration="true">
und window.require. Hinterlassen Sie hier eine Notiz zum späteren Nachschlagen.
window.require hat bei mir funktioniert! Danke Leute!
Fehlermeldung im Browser, als ich dies versuchte
Ich habe vergessen, nodeIntegration: false
zurückzusetzen, wodurch sogar window.require()..
deaktiviert wird. dummer Fehler. Ich hoffe, das erspart jemandem eine Stunde Recherche.
@phil294 Danke Mann! Sie haben wirklich eine Stunde der Recherche gespart.
Hallo @micsel ,
Ich habe das const-Fenster deklariert: any;
aber es wirft einen Syntaxfehler.
Irgendwelche Ideen warum?
Ja, setzen Sie das const-Fenster deklarieren: beliebig; ganz oben, direkt hinter den Importen.
Wenn Sie erhalten, dass window.require keine Funktion ist und Sie Angular-CLI verwenden, verwenden Sie Folgendes, um die Windows-Schnittstelle zu instanziieren:
./src/typings.d.ts
declare var window: Window;
interface Window {
require: any;
}
Dann können Sie dies verwenden, um Elektron einzuschließen:
const { ipcRenderer } = window.require('electron');
Wenn Sie Angular 2+ in der Elektron-App verwenden, importieren Sie die Bibliothek „ngx-electron“ und verwenden Sie diese in any.componets.ts
import { ElectronService } from 'ngx-electron';
//constructor
constructor(
private elt: ElectronService
){
var fs = this.elt.remote.require('fs');
}
Ich verwende React Js mit Electron und wenn ich diese Zeile in den Start des Terminal-Garns führe, wird mir der Fehler Uncaught Type Error angezeigt: window.require ist keine Funktion. Ich verwende kein Typoskript, wie das Fenster in React Js deklariert wird
Leute, die immer noch mit dem Problem konfrontiert sind, verderben irgendwie die Konsistenz der Verwendung von import
-Anweisungen in der gesamten Codebasis, wenn sie window.require()
machen. Eine einfache Alternative besteht darin, Ihr Webpack target
auf electron-renderer
zu setzen. Wenn Sie Create React App verwenden, kann das Auswerfen ein Chaos sein. Daher können Sie dieses Paket verwenden, das das Webpack-Hooking für Sie übernimmt, und Sie können es z. B. für import fs from 'fs'
in Ihren React-Komponenten (oder jedem anderen Knotenmodul) verwenden, glücklich in Ihrem Leben :)
Unter Windows mit Vue CLI 3 funktioniert window.require, erfordert jedoch einen vollständigen Pfad anstelle eines relativen Pfads von "node_modules/".
Aber ähnlich wie im React-Fall kann Webpack durch Bearbeiten von vue.config.js richtig für Vue konfiguriert werden. "require" funktioniert dann wie erwartet.
vue.config.js:
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.output.publicPath = `${process.cwd()}/dist/`
}
config.target = 'electron-renderer'
}
}
router.js (dies ist nur ein Beispiel, es würde in jeder anderen vue js-Datei funktionieren)
const Store = require("electron-store");
const store = new Store();
_Ich möchte das fast nicht hinzufügen, aber es hätte mir ein oder zwei Stunden Debugging erspart._
Ich musste rm -rf node_modules && npm install
um dieses Problem zu beheben. Ich konnte dann window
aus window.require
entfernen und die Dinge funktionierten wieder. Hoffentlich hilft das jemand anderem.
@cperthuis Ich möchte nur DANKE sagen!! Hahah, ich benutze nicht einmal Vue, aber logisches Denken hat mich dazu gebracht, herauszufinden, dass ich meine webpack.config.js ändern kann, um eine Zieleigenschaft zu haben :)
LIEF WIE AM SCHNÜRCHEN.
Hallo,
window.require
funktioniert in einer lokalen Dev-Serverumgebung, aber nicht in einer Prod-Umgebung, nachdem die React-App in einer minimierten HTML-Datei erstellt wurde.
function createWindow() {
win = new BrowserWindow({
width: 1280,
height: 720,
icon: path.join(__dirname, 'assets/icons/png/64x64.png'),
webPreferences: {
nodeIntegration: true,
preload: __dirname + '/preload.js'
}
})
win.setPosition(0, 0)
win.loadURL(isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, 'build/index.html')}`)
}
Es funktioniert mit localhost:3000
, aber nicht mit file://${path.join(__dirname, 'build/index.html')}
@cperthuis , Ihr Fix funktionierte für nicht ausgeworfene CRA-Apps mit „react-app-rewired“. Danke schön.
Mit Create-React-App 2 können Sie das npm-Modul craco
verwenden:
https://www.npmjs.com/package/@craco/craco
Ändern Sie in Ihrer package.json react-scripts
durch craco
craco.config.js
module.exports = {
webpack: {
configure: {
target: 'electron-renderer'
}
}
};
Und in haben Sie so Zugriff auf Ihren Electron-Kontext:
import Electron from 'electron';
const { dialog } = Electron.remote;
@ Maxou44 danke für den Tipp zu Craco & Elektron. Es ist genau das, was ich brauchte. Falls jemand ein Beispiel sucht...
@wwlib Kein Problem, freut mich zu sehen, dass es dir geholfen hat 🥳
Ich habe vergessen,
nodeIntegration: false
zurückzusetzen, wodurch sogarwindow.require()..
deaktiviert wird. dummer Fehler. Ich hoffe, das erspart jemandem eine Stunde Recherche.
Ich danke dir sehr.
Bitte beachten Sie, dass es beim Laden von Remote-Inhalten wichtig ist, nodeIntegration
auf false zu setzen: https://electronjs.org/docs/tutorial/security#2 -disable-nodejs-integration-for-remote -Inhalt
Hallo,
Ich habe den gleichen Fehler. Bei der Verwendung von window.require wird der Fehler Uncaught TypeError: fs.readFileSync is not a function
behoben, aber ich habe einen anderen Fehler Uncaught TypeError: window.require is not a function
gefunden.
Gibt es einen Vorschlag, wie man das beheben kann. Ich verwende browserify auf node js.
Für alle, die immer noch daran festhalten: Sie erhalten den Fehler window.require is not a function
, es sei denn, Sie deklarieren nodeIntergation
explizit als true
, wenn Sie Ihr BrowserWindow
deklarieren:
new BrowserWindow({
webPreferences: {
nodeIntegration: true,
}
});
Die einzige gute Lösung, die ich gefunden habe, ist folgende:
react-app-rewired
-Paket installiereneject
-ing des CRA einzufügen: "scripts": {
...
"start": "react-app-rewired start",
},
config-overrides.js
mit entsprechendem Inhalt hinzu:module.exports = function override (config, env) {
config.target = 'electron-renderer'
return config;
}
Danke an: @Lilanga Kommentar , @agrublev Kommentar und Ersteller von React-App-Rewired .
Aktualisiert:
Eigentlich die 2. Version, wie man dasselbe macht: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer
Aktualisiert2:
@nukeop Ich habe einige irreführende Aussagen entfernt, da ich keine Zeit hatte, Debatten darüber zu verfolgen, warum Browserify nicht verwendet werden sollte oder warum es verwendet werden sollte, und kann jetzt keine detaillierte Erklärung aufschreiben, was ich meinte. Aber ich werde meine persönliche Meinung dazu behalten, dass "nur window.require
das Problem lösen wird" sehr unzuverlässig erscheint.
Wie falsch?
Es ist eine React-App, die innerhalb der Electron-Umgebung ausgeführt werden muss und nicht umgekehrt
Was?
_Ich möchte das fast nicht hinzufügen, aber es hätte mir ein oder zwei Stunden Debugging erspart._
Ich musste
rm -rf node_modules && npm install
um dieses Problem zu beheben. Ich konnte dannwindow
auswindow.require
entfernen und die Dinge funktionierten wieder. Hoffentlich hilft das jemand anderem.
Wow.. ALLES in diesem Thread ausprobiert und deine Wiederholung verpasst, weil es keine Upvotes gibt.. Immer noch window is not a function
..
entfernt und neu installiert node_modules
und es funktioniert.
PS: Sie müssen immer noch alle Lösungen machen, aber wenn Sie alles gemacht haben
und immer noch dasselbe neu installieren node_modules
Du hast meinen Tag gerettet @joshuapinter !
Mit React-Create-App habe ich die gleichen Fehler gefunden.
Die Lösung war bisher:
const electron = window.require("electron")
im Elektronenteil BrowserWindow
fügen Sie nodeIntegration:true
wie folgt hinzu.
mainWindow = new BrowserWindow({ width: 900, height: 680, webPreferences: { webSecurity: false, nodeIntegration: true } });
Die einzige gute Lösung, die ich gefunden habe, ist folgende:
- als dev-abhängiges
react-app-rewired
-Paket installieren- Verwenden Sie dieses Modul, um eine benutzerdefinierte Webpack-Konfiguration ohne
eject
-ing des CRA einzufügen:"scripts": { ... "start": "react-app-rewired start", },
- und füge die Datei
config-overrides.js
mit entsprechendem Inhalt hinzu:module.exports = function override (config, env) { config.target = 'electron-renderer' return config; }
Danke an: @Lilanga Kommentar , @agrublev Kommentar und Ersteller von React-App-Rewired .
Aktualisiert:
Eigentlich die 2. Version, wie man dasselbe macht: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sferAktualisiert2:
@nukeop Ich habe einige irreführende Aussagen entfernt, da ich keine Zeit hatte, Debatten darüber zu verfolgen, warum Browserify nicht verwendet werden sollte oder warum es verwendet werden sollte, und kann jetzt keine detaillierte Erklärung aufschreiben, was ich meinte. Aber ich werde meine persönliche Meinung dazu behalten, dass "nurwindow.require
das Problem lösen wird" sehr unzuverlässig erscheint.
Das hat bei mir funktioniert. Danke schön
Das Problem mit window.require
ist, dass es nur für das Paket der obersten Ebene funktioniert.
zB Wenn ich fs
direkt verwende, funktioniert es. Aber wenn ich ein Paket verwende, das eine Abhängigkeit von fs
hat, bekomme ich immer noch eine Ausnahme.
window.require
es funktioniert bei mir nicht, wenn ich die Funktion in der React App aufrufe. Ich habe "TypeError: window.require is not a function" erhalten.
App.js
:
``` Javascript
import React, { useEffect, useState } from 'react';
importiere './App.css';
const ipcRenderer = window.require('elektron').ipcRenderer;
Funktion App() {
useEffect( () => {
ipcRenderer.on('ping', (event, message) => { console.log(message) });
}, []);
return (
<div className = 'App'>
<div className = 'Header-Arrow'></div>
<div className = 'Box'>
<p>Press ⌘ + ⇧ + 4</p>
</div>
</div>
);
}
Standard-App exportieren;
````
Hauptfenstervariable auf Main.js
:
``` Javascript
// Erstellen Sie das Browserfenster.
Hauptfenster = neues Browserfenster ({
alwaysOnTop: wahr,
Rahmen: falsch,
Vollbildfähig: falsch,
transparent: wahr,
titleBarStyle: 'customButtonsOnHover',
zeigen: falsch,
Breite: 300,
Höhe: 350,
Webeinstellungen: {
nodeIntegration: true,
Vorladen: __dirname + '/preload.js'
}
});
```
**
Preload.js`**:
javascript
window.ipcRenderer = require('electron').ipcRenderer;
Was fehlt mir?
Also Problem gelöst. Ich antworte mir selbst, weil vielleicht jemand davon profitieren kann (ich hing stundenlang fest). Wenn Sie eine Preload.js
-Datei haben, müssen Sie window.require('electron').ipcRenderer
nicht erneut vom Àpp.js
(Renderer) aufrufen; Sie rufen die Variable direkt als window.ipcRenderer
wie folgt auf:
App.js
:
````javascript
import React, { useEffect, useState } from 'react';
importiere './App.css';
Funktion App() {
useEffect( () => {
window.ipcRenderer.on('ping', (event, message) => { console.log(message) });
}, []);
return (
<div className = 'App'>
<div className = 'Header-Arrow'></div>
<div className = 'Box'>
<p>Press ⌘ + ⇧ + 4</p>
</div>
</div>
);
}
Standard-App exportieren;
````
Hauptfenstervariable auf Main.js
:
javascript
// Create the browser window.
mainWindow = new BrowserWindow({
alwaysOnTop: true,
frame: false,
fullscreenable: false,
transparent: true,
titleBarStyle: 'customButtonsOnHover',
show: false,
width: 300,
height: 350,
webPreferences: {
nodeIntegration: true,
preload: __dirname + '/preload.js'
}
});
Preload.js
:
javascript
window.ipcRenderer = require('electron').ipcRenderer;
Nach dem Ausführen der App über die Befehlszeile gibt das vom React-Prozess generierte Fenster einen Fehler aus (ipcRenderer ist nicht definiert). Ignoriere es. Das vom Electron-Prozess (Haupt-App) generierte Fenster funktioniert einwandfrei.
Mit Create-React-App 2 können Sie das npm-Modul
craco
verwenden:https://www.npmjs.com/package/@craco/craco
Ändern Sie in Ihrer package.json
react-scripts
durchcraco
craco.config.js
module.exports = { webpack: { configure: { target: 'electron-renderer' } } };
Ich hatte die Probleme sowohl bei require("fs")
als auch bei window.require("fs")
. Danke an @Maxou44 für die Einführung von CRACO in diese Diskussion.
Um das Problem zu lösen, habe ich 3 Änderungen in meinem Projekt vorgenommen:
new BrowserWindow({ width: 1200, height: 800 })
new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } })
const fs = require("fs")
durch const fs = require("electron").remote.require("fs")
ersetztWeitere Erläuterungen finden Sie in diesem Git-Repo von @wwlib https://github.com/wwlib/cra-craco-electron-example
Ich habe den ganzen Thread von oben nach unten gelesen und nichts hat funktioniert.
AUSSER, die obige Methode von @Saroopashree . Danke @Saroopashree für das Teilen der Lösung.
Ich denke, da sich React und Webpack seit dem Start des Threads etwas geändert haben, sind die obigen Lösungen veraltet. Ich kann mich natürlich irren, aber mit der obigen Methode hat es funktioniert.
Folgendes habe ich getan:
npm install craco -D
module.exports = {
webpack: {
configure: {
target: 'electron-renderer'
}
}
};
new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } })
in main.js aktualisiert. Natürlich mit unterschiedlicher Breite und Höhe.npm start
, um den Entwicklungsserver für die React-App zu starten, die mit create-react-app erstellt wurde. Dadurch wurde ein Tab mit denselben Fehlern geöffnet. Und ich fühlte mich wieder müde.npm run electron
ausgeführt, um die Elektron-App auszuführen.Also danke @Saroopashree.
Wenn Sie versuchen, auf „Elektron“ oder seine andere Komponente innerhalb einer Reaktionskomponente/Klasse zuzugreifen, versuchen Sie Folgendes: #336757899
Vielen Dank an @tumbledwyer für das Posten des Links zu einer Lösung, die für mich funktioniert:
Aktualisiert:
Eigentlich die 2. Version, wie man dasselbe macht: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer
Die Lösung von Randy Findley:
Wenn Sie jetzt wie ich auf das Modul fs
zugreifen müssen, werden Sie schnell auf den Fehler Module not found
stoßen
Installieren Sie zuerst Rescripts .
yarn add @rescripts/cli @rescripts/rescript-env --dev
Ändern Sie dann die Skript-Tags in package.json von diesem ...
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
dazu
"start": "rescripts start",
"build": "rescripts build",
"test": "rescripts test",
Fügen Sie nun eine neue Datei namens .rescriptsrc.js
mit folgendem Inhalt hinzu:
module.exports = [require.resolve('./.webpack.config.js')]
Fügen Sie schließlich eine weitere neue Datei namens .webpack.config.js
mit folgendem Inhalt hinzu:
// define child rescript
module.exports = config => {
config.target = 'electron-renderer';
return config;
}
Jetzt können Sie das Modul fs
verwenden, keine Sorge.
Worauf @ledleds hingewiesen hat, hat bei mir funktioniert, indem ich CRA mit Typscript und Electron verwendet habe. Dann habe ich webPreferences so deklariert:
webPreferences: {
preload: path.join(__dirname, 'preload.js')
},
das scheint also das Überschreiben/Setzen von nodeIntegration auf false zu sein, also das Setzen auf true und das Neustarten der App löste das Problem (Sie müssen die App neu starten, um das Electron-Fenster mit dieser Konfiguration zu laden).
NodeIntegration so auf true setzen
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true
},
Für alle, die immer noch daran festhalten: Sie erhalten den Fehler
window.require is not a function
, es sei denn, Sie deklarierennodeIntergation
explizit alstrue
, wenn Sie IhreBrowserWindow
deklarieren:new BrowserWindow({ webPreferences: { nodeIntegration: true, } });
reagieren-app-neu verdrahtet
Dies war die einzige gute Lösung, die ich in Bezug auf die Skalierbarkeit gefunden habe. Ich denke nicht, dass sich jemand auf window.require verlassen sollte
Warum sollte window.require nicht skalierbar sein?
Für alle, die zufällig mit diesem oder ähnlichen Problemen zu kämpfen haben und Vue und vue-electron-builder verwenden, siehe hier
Für alle, die immer noch damit zu kämpfen haben, insbesondere wenn es darum geht, die Elektronenanwendung über eine Reaktionstaste zu beenden, lesen Sie bitte weiter.
Was bei mir geholfen hat war folgendes:
Wenn Sie Ihr Fenster deklarieren, stellen Sie sicher, dass Sie aus Sicherheitsgründen nodeIntegration: true
festlegen, da dies derzeit standardmäßig false
ist. Normalerweise geschieht dies in Ihrer electron.js
-Datei.
Wie @packetstracer bereits erwähnt hat: _Sie müssen die App neu starten, um das Electron-Fenster mit dieser Konfiguration zu laden_
mainWindow = new BrowserWindow({
//...
webPreferences: {
nodeIntegration: true,
},
});
electron.js
die folgende Anweisung ganz oben ein, um sicherzustellen, dass ipcMain
auf das Ereignis _"close-me"_ lauscht:const { ipcMain } = require("electron");
ipcMain.on("close-me", (evt, arg) => {
app.quit();
});
window.require
-Anweisung hinzu. Das übliche require
hat nicht funktioniert:const ipcRenderer = window.require("electron").ipcRenderer;
<Button label="close" onClick={(e) => ipcRenderer.send("close-me")} />
Fühlen Sie sich frei, zu kommentieren und Feedback zu geben. Ich bin noch neu bei Elektron.
Ich weiß, dass der Zusammenhang mit dem Beenden-Button nicht zusammenhängt, aber ich konnte keinen besser geeigneten Thread finden. Bitte zögern Sie nicht, mich auf einen anderen, passenderen Thread zu verweisen, falls es einen gibt.
Meine Konfiguration:
"electron": "9.2.0",
"electron-builder": "22.8.0",
"electron-packager": "15.0.0",
für mich gelöst!! Danke @nukeop
`
`
Weiß jemand, wie man den richtigen Typ in Typoskript einrichtet?
Ich habe im Moment folgendes
export const electron = window.require('electron').remote
Ich möchte so etwas wie
export const electron = window.require('electron').remote as ElectronType
Die IDE weiß also, wie die Elektronen-API automatisch vervollständigt wird.
@timsamart es funktioniert. Danke, das spart mir Tage Arbeit. 🤣
Nachdem ich viele Stunden damit verbracht habe, buchstäblich alles oben genannte auszuprobieren, habe ich den Teil verpasst, falls Sie BrowserView
verwenden, genau wie BrowserWindow
müssen Sie node.js explizit aktivieren:
new BrowserView({ // is a BrowserView not a BrowserWindow
webPreferences: {
nodeIntegration: true,
},
})
Hilfreichster Kommentar
Für alle, die in Zukunft auf dieses Problem stoßen und diesen Thread lesen, ist die Verwendung
window.require
anstelle von require eine Möglichkeit, den Konflikt zwischen der Funktionrequire
von electron und browserify zu vermeiden.