Electron: Membutuhkan elektron di luar main.js menyebabkan TypeError

Dibuat pada 22 Sep 2016  ·  82Komentar  ·  Sumber: electron/electron

  • Versi elektron: 1.3.5
  • Sistem operasi: Mint 17

Halo

Saya menggunakan Electron dengan React.js dan babelify, di antara plugin lainnya (daftar di bawah).
Mencoba menggunakan require('electron') , misalnya untuk mendapatkan akses ke elektron BrowserWindow , menghasilkan konsol yang menampilkan kesalahan berikut:
index.js:4 Uncaught TypeError: fs.readFileSync is not a function

Namun, saya dapat menggunakan const electron = require('electron'); di main.js. Untuk apa nilainya, saya juga menggunakan watchify untuk mengemas semuanya ke dalam bundel js.

Berikut adalah daftar lengkap dependensi di package.json saya:

"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"
    },
blockeneed-info ❌

Komentar yang paling membantu

Bagi siapa pun yang menghadapi masalah ini di masa mendatang dan membaca utas ini, menggunakan window.require alih-alih memerlukan adalah salah satu kemungkinan untuk menghindari konflik antara fungsi require elektron dan browserify.

Semua 82 komentar

index.js:4 TypeError Tidak Tertangkap: fs.readFileSync bukan fungsi

Bisakah Anda memasukkan baris 4 dari index.js di sini? Atau jejak tumpukan yang lebih lengkap?

Saya percaya ini mengacu pada index.js elektron, yang terletak di node-modul proyek. Berikut isi dari file ini:

var fs = require('fs')
var path = require('path')

module.exports = path.join(__dirname, fs.readFileSync(path.join(__dirname, 'path.txt'), 'utf-8'))

Seluruh jejak tumpukan menunjukkan konflik dengan React.js:

Stack trace

Apa yang terjadi jika Anda menjalankan require('fs').readFileSync dari tab Konsol pada alat dev?

Sepertinya modul node electron-prebuilt (file yang Anda tempel) berakhir di aplikasi paket Anda yang menurut saya tidak Anda inginkan karena seharusnya menggunakan electron bawaan sebagai gantinya.

@nukeop Bagaimana Anda meluncurkan aplikasi Anda. `Skrip awal Anda akan terlihat seperti.

"scripts": {
  "start": "electron ."
}

Saya merasa Anda mencoba menjalankan main.js Anda dengan node

node main.js

Yang tidak akan berhasil

Apa yang terjadi jika Anda menjalankan require('fs').readFileSync dari tab Konsol alat dev?

Tepat setelah kesalahan ini terjadi, saya dapat menjalankan require('fs').existsSync di konsol untuk mencetak definisi fungsi. Ini juga berfungsi sebelum kesalahan.

Sepertinya modul node prebuilt elektron (file yang Anda tempel) berakhir di aplikasi paket Anda yang menurut saya tidak Anda inginkan karena seharusnya menggunakan kebutuhan elektron bawaan.

Saya memiliki instance watchify yang berjalan di latar belakang saat saya mengembangkan yang terus memperbarui paket saya. Saya mendefinisikannya di bagian skrip package.json seperti ini:

"watch": "watchify app/app.js -t babelify -o public/js/bundle.js --debug --verbose"

Adakah saran untuk menghindari bundling electron-prebuilt ?

Dukungan @nukeop Electron membutuhkan secara internal sehingga Anda tidak perlu menggunakan browserify.

Sejauh yang saya ketahui, saya ingin Anda menggunakan browserify, Anda harus mengecualikan "elektron".

Menarik, mungkinkah watchify/browserify merusak ini? Ini telah bekerja dengan baik sejauh ini.

Sekarang saya tidak yakin bagaimana menjalankan program tanpa itu.

Secara harfiah lari saja

electron .

Dari folder aplikasi utama Anda, Anda tidak perlu membundel apa pun saat menggunakan Electron karena ia memiliki lingkungan simpul penuh secara internal.

_Saya akan menutup ini karena ini adalah masalah Browserify_

Itulah yang telah saya lakukan selama ini, mengemas program ke dalam satu file .js, yang disertakan dalam file html sederhana dengan:

  <script src="public/js/bundle.js">
  </script>

Dan semuanya berfungsi, kecuali ketika saya menggunakan require. Ini adalah masalah dengan interaksi antara dua modul.

Jika saya tidak mengemas seluruh program ke dalam bundel, saya tidak memiliki cara mudah untuk menjalankannya, karena main.js saya hanya memulai elektron dan memuat file html yang menyertakan bundel.

@nukeop Proses renderer di dalam Electron juga memiliki akses ke lingkungan node/commonjs penuh, jadi Anda tidak perlu membundel apa pun.

Jika saya tidak mengemas seluruh program ke dalam bundel, saya tidak memiliki cara mudah untuk menjalankannya, karena main.js saya hanya memulai elektron dan memuat file html yang menyertakan bundel.

Saya tidak yakin saya mengerti di sini, skrip apa pun yang Anda muat di file HTML Anda memiliki lingkungan commonjs penuh dan karenanya dapat menggunakan require untuk memuat file tambahan tanpa browser apa pun

Bagi siapa pun yang menghadapi masalah ini di masa mendatang dan membaca utas ini, menggunakan window.require alih-alih memerlukan adalah salah satu kemungkinan untuk menghindari konflik antara fungsi require elektron dan browserify.

FWIW, saya mengalami masalah yang sama saat mencoba menggunakan elektron dalam proses renderer dengan create-react-app yang menggunakan webpack di backend alih-alih browserify. window.require tampaknya menyelesaikannya untuk saya juga meskipun saya tidak sepenuhnya jelas mengapa.

Sunting : Saya menemukan alasannya :-) Kami ingin require electron selama runtime dari lingkungan nodejs yang disediakan pada saat runtime daripada lingkungan nodejs yang digunakan selama kompilasi oleh webpack. Secara default, global terikat ke window dan kompilasi webpack mengabaikan window global - karenanya window.require berfungsi.

Cara lain untuk memberitahu webpack untuk mengabaikan nama global adalah dengan menggunakan komentar seperti /*global Android*/ di file JS. Dalam proyek lain menggunakan aplikasi yang dibangun CRA di Android WebView, saya menggunakan yang di atas untuk mendapatkan akses ke objek Java yang diekspos ke JS melalui antarmuka JavaScript yang disediakan oleh Webview.

@nukeop - terima kasih atas posting terakhir Anda; itu banyak membantu saya. window.require bekerja untuk saya.

ya, masalah buat aplikasi reaksi/webpack saya telah diperbaiki.
mengubah

import electron, { ipcRenderer } from 'electron'

ke

const electron = window.require("electron")

@srinathh bagaimana Anda mengekspos/memuat aplikasi CRA Anda sebagai penyaji di utama Anda? apakah Anda membangun terlebih dahulu (dan memodifikasi jalur sumber daya statis html)

Ya, alur kerja saya saat ini pada dasarnya adalah menjalankan npm run build menggunakan skrip CRA dan kemudian menjalankan output di folder build dengan elektron. Anda tidak perlu mengubah jalur sumber daya statis secara manual. Di package.json untuk skrip CRA, Anda hanya perlu mengatur homepage seperti ini dan jalurnya akan diatur dengan tepat.

    "homepage": "./"

Selain itu, saya memiliki main.js dan package.json untuk aplikasi elektron di folder public . Jadi menjalankan build secara otomatis menyalinnya & Anda bisa menjalankan electron build/ untuk memulai aplikasi Anda.

Saya sebenarnya ingin dapat melakukan npm start dengan elektron untuk pengembangan tetapi saya belum menemukan cara untuk membuatnya bekerja. Saya kira saya harus melakukan eject dan memodifikasi skrip dengan tangan.

Jika Anda ingin melihat contoh penyiapan - lihat https://github.com/srinathh/snippetfu

Saya tidak menggunakan Electron, tetapi Node-Webkit (nw.js).
Menggunakan window.require juga memperbaiki masalah saya. Terimakasih banyak untuk ini!

@nukeop window.require melakukan trik untuk saya juga terima kasih banyak! 🎉.

@nukeop Saya mendapat kesalahan yang sama, tetapi sudah dipecahkan trik window.require, terima kasih banyak!

window.require memang menyelesaikan masalah fs.existsSync is not a function tetapi itu menyebabkan kesalahan lain: window.require bukan fungsi. Bagaimana cara mengatasinya?

@steric85 apakah Anda menggunakan browserify, babel atau webpack? Anda mungkin perlu mengubah kode Anda

@Alxmerino saya menggunakan webpack.

pastikan Anda mengkompilasi kode Anda

@steric85 , saya menghadapi window.require is not a function dalam TypeScript, saya berhasil memperbaikinya dengan cara ini:

declare global {
  interface Window {
    require: any;
  }
}

const electron = window.require('electron');

Saya menggunakan metode di atas untuk mengakses ipcRenderer dari elektron di aplikasi Angular saya tetapi deteksi perubahan Angular tidak berfungsi ketika saya memperbarui Observable menggunakan penangan pesan ipcRenderer.
Apakah karena Angular tidak tahu bahwa ipcRenderer adalah EventEmitter dan perlu menjalankan deteksi perubahan saat acara ipcRenderer masuk?

di Angular 2 saya biasa memanggil applicationRef.tick() untuk secara eksplisit memberi tahu angular untuk menyegarkan statusnya. https://angular.io/api/core/ApplicationRef

Saya menghadapi masalah yang sangat mirip dengan @nukeop dan @srinathh : Saya mengatur proyek Electron + React + Webpack saya mengikuti panduan artikel ini , di mana penulis di bagian akhir menyebutkan triknya dengan window.require . Saya hanya require('electron') dua tempat di proyek saya; di titik masuk untuk Electron, dan di kelas pengontrol JavaScript yang diperlukan oleh beberapa komponen React. Dalam file titik masuk Electron saya, saya cukup melakukan const electron = require('electron'); , karena itu harus berjalan di proses utama (kan?), dan di kelas pengontrol saya, saya melakukan const Electron = window.require('electron').remote; diikuti oleh const Jsonfile = Electron.require('jsonfile'); , yang seharusnya menjadi cara untuk melakukannya karena sedang berjalan dalam proses penyaji. Tapi saya mendapatkan kesalahan yang sama dengan @nukeop ("TypeError: fs.ExistsSync is not a function") pada baris enam di node_modules/electron/index.js yang terlihat seperti ini:

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')
}

Saya sudah mencoba menghapus node_modules/electron dan menginstal lagi.
Saya menggunakan Electron 1.7.5 di macOS 10.12.6, dan memulai proyek saya menggunakan npm run dev sebagai penyiapan dalam artikel.

Memperbarui; Saya menemukan require yang menyebabkan kesalahan saya, saya mencoba melakukan require('electron-react-devtools') di React index.js saya. Mengubahnya menjadi const ReactDevtools = Electron.require('electron-react-devtools'); menghentikan kesalahan, tetapi sekarang sepertinya saya tidak dapat memanggil .inject() dalam instance ReactDevtools ("bukan fungsi"), tetapi itu mungkin bukan sesuatu untuk dibahas di sini .

@steric85 Itu karena Anda menjalankan aplikasi di lingkungan halaman web => Anda harus menjalankan aplikasi di lingkungan Electron (lingkungan Nodejs)

  • membutuhkan('elektron') => Webpack akan menggabungkan modul elektron ke bundle.js => elektron menggunakan modul fs => Webpack tidak mengerti
  • window.require('electron') => Webpack akan mengabaikan fungsi yang dibutuhkan
  • Di lingkungan halaman web, window.require tidak akan ditentukan
  • Di lingkungan nodejs, window.require akan berfungsi
    => Buka aplikasi Anda di jendela Electron (bukan di jendela browser seperti Chrome, Firefox, dll.

Saya masih mendapatkan window.require is not a function . Saya menggunakan Electron dengan React Starter Kit (https://github.com/kriasoft/react-starter-kit). Semuanya bekerja dengan baik, kecuali ini.

Saya telah mengatur aplikasi Electron saya untuk memuat aplikasi saya dari web, sehingga aplikasi tidak berjalan secara lokal:
https://Gist.github.com/holgersindbaek/68f6db82f507967a51ca75c527faeff6

Apa yang saya coba lakukan, adalah memanggil ipcRenderer di salah satu file React saya. Saya tidak yakin apakah itu mungkin ketika aplikasi saya sedang dimuat dari web. Ada saran?

@holgersindbaek Anda seharusnya tidak melihat aplikasi Anda di browser seperti Chrome, Firefox, dll. Ini tidak akan berfungsi karena ini adalah lingkungan halaman web.
Anda harus melihat aplikasi Anda di jendela Electron.

Ya, tetapi saya menggunakan Electron dengan cara, di mana saya memuat aplikasi saya dari situs web pada setiap peluncuran. Pada dasarnya saya menampilkan situs web di aplikasi elektron saya. Lihat berkas di atas. Saya hanya ingin memastikan bahwa tidak ada yang bisa saya lakukan?!

Elektron dapat memuat URL apa pun. Untuk memuat URL, Anda harus menggunakan fungsi ini mainWindow.loadURL(url)
=> Dalam tampilan jendela elektron, kode javascript URL tersebut dapat mengakses persyaratan, ipc, dll.

Baik. Saya akan mencobanya.

window.require pada elektron tidak berfungsi, tetapi window.require untuk fs berhasil.

Tidak begitu yakin mengapa. Tapi itu berhasil dan karena ini adalah proyek pribadi kecil, saya tidak akan mendorong masalah ini.

Terima kasih @nukeop

Hai, Ini package.json saya, saya menggunakan webpack, tidak ada yang menyelesaikan masalah saya, apakah ada yang punya solusi? Setelah saya menggunakan window.require, saya mendapat kesalahan "window tidak ditentukan"

'gunakan ketat';

var elektron = membutuhkan('elektron')
var aplikasi = electron.app;
var BrowserWindow = electron.BrowserWindow;
var jendela utama = nol;

app.on('siap', fungsi() {
mainWindow = new BrowserWindow({lebar: 800, tinggi: 600});

mainWindow.loadURL('file://' + __dirname + '/index.electron.html');

mainWindow.webContents.openDevTools();

});

Saya menggunakan TypeScript dan saya harus menggunakan

const electron = (<any>window).require("electron");

untuk membuat penyaji saya berkomunikasi dengan main. Semoga ini bisa membantu seseorang.

Ini berhasil untuk saya.
Misalnya jika Anda ingin membutuhkan remote, maka

mendeklarasikan jendela const: any;
const { jarak jauh } = window.require('elektron');

Hai, terima kasih.

Pada Minggu, 3 Des 2017 pukul 21:29, Michael - <
[email protected]> menulis:

Ini berhasil untuk saya.
Misalnya jika Anda ingin membutuhkan remote, maka

mendeklarasikan jendela const: any;
const { jarak jauh } = window.require('elektron');


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/electron/electron/issues/7300#issuecomment-348801405 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/ARDyd4c3aOkMbb058xklujMMbnmaoxKGks5s8uGVgaJpZM4KDU6t
.

@solominh Terima kasih atas penjelasan Anda di sini . Namun saya memiliki konfigurasi yang mirip dengan @holgersindbaek , lingkungan mana yang merupakan skrip pramuat dalam tampilan web?

Informasi:

  • Entri elektron saya menjalankan mainWindow.loadURL(url) , di mana url adalah index.html lokal
  • index.html ini memiliki <webview>
  • Tampilan web memiliki bidang preload yang memuat inject.js, dan skrip ini melakukan window.require('electron').

Catatan:

  • Jika saya menggunakan const electron = require('electron') , saya memiliki kesalahan fs.readFileSync is not a function
  • Jika saya menggunakan const electron = window.require('electron') , saya memiliki kesalahan window.require is not a function .
  • inject.js dibundel melalui webpack (dapat menempelkan konfigurasi jika relevan).

EDIT: Dipecahkan untuk saya menggunakan <webview nodeintegration="true"> dan window.require. Meninggalkan catatan di sini untuk referensi di masa mendatang.

window.require bekerja untuk saya! Terima kasih teman-teman!

https://imgur.com/a/ekWwD

pesan kesalahan di browser ketika saya mencoba ini

Lupa mengembalikan nodeIntegration: false yang bahkan menonaktifkan window.require().. . kesalahan bodoh. Semoga ini membuat seseorang meluangkan waktu satu jam untuk meneliti.

@phil294 Terima kasih kawan! Anda benar-benar menghemat satu jam penelitian.

Hai @micsel ,
Saya menyertakan jendela deklarasi const: any;
tapi itu melempar kesalahan sintaks.
Ada ide kenapa?

Ya, letakkan jendela deklarasi const: any; di bagian atas, tepat setelah tempat impor.

Jika Anda mendapatkan window.require bukan fungsi dan Anda menggunakan Angular-CLI, gunakan yang berikut ini untuk membuat instance antarmuka Window:

./src/typings.d.ts

declare var window: Window;
interface Window {
    require: any;
}

Kemudian Anda dapat menggunakan ini untuk memasukkan elektron:
const { ipcRenderer } = window.require('electron');

jika Anda menggunakan angular 2+ di aplikasi elektron, maka impor lib "ngx-electron" dan gunakan ini di any.componets.ts

import { ElectronService } from 'ngx-electron';

//constructor
constructor(
    private elt: ElectronService
  ){
  var fs = this.elt.remote.require('fs');
}

Saya menggunakan react js dengan elektron dan ketika saya menjalankan baris ini ke terminal yarn run start itu memberi saya kesalahan Uncaught Type Error: window.require bukan fungsi saya tidak menggunakan TypeScript bagaimana mendeklarasikan jendela di React Js

Orang yang masih menghadapi masalah, entah bagaimana melakukan window.require() merusak konsistensi penggunaan pernyataan import di seluruh basis kode. Alternatif yang mudah adalah mengatur webpack Anda target ke electron-renderer . Jika menggunakan Create React App , ejecting bisa jadi berantakan. Oleh karena itu, Anda dapat menggunakan paket ini yang melakukan pengaitan webpack untuk Anda dan Anda dapat menggunakannya untuk mis., import fs from 'fs' dalam komponen Bereaksi Anda (atau modul simpul lainnya), dengan senang hati dalam hidup Anda :)

Pada windows dengan Vue CLI 3, window.require akan bekerja tetapi akan membutuhkan path lengkap daripada path relatif dari "node_modules/".

Tetapi mirip dengan kasus React, webpack dapat dikonfigurasi dengan benar untuk Vue dengan mengedit vue.config.js. "memerlukan" kemudian akan berfungsi seperti yang diharapkan.

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 (ini hanya sebuah contoh, ini akan berfungsi di file vue js lainnya)

const Store = require("electron-store");
const store = new Store();

_Saya hampir tidak ingin menambahkan ini tetapi itu akan menyelamatkan saya satu atau dua jam dari debugging._

Saya harus rm -rf node_modules && npm install untuk memperbaiki masalah ini. Saya kemudian dapat menghapus window dari window.require dan semuanya mulai berfungsi kembali. Semoga itu membantu orang lain.

@cperthuis Saya hanya ingin mengucapkan TERIMA KASIH!! Hahah saya bahkan tidak menggunakan Vue, tetapi pemikiran logis membuat saya mengetahui bahwa saya dapat mengubah webpack.config.js saya untuk memiliki properti target :)
image
BEKERJA SEPERTI CHARM.

Hai,

window.require bekerja di lingkungan server lokal dev tetapi tidak di lingkungan prod setelah membangun aplikasi React ke file HTML yang diperkecil.

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')}`)
}

Ini bekerja dengan localhost:3000 tetapi tidak dengan file://${path.join(__dirname, 'build/index.html')}

https://imgur.com/EE7jxZq

@cperthuis , perbaikan Anda berfungsi untuk aplikasi CRA yang tidak dikeluarkan menggunakan 'react-app-rewired'. Terima kasih.
image

Dengan Create-React-App 2, Anda dapat menggunakan modul craco npm:

https://www.npmjs.com/package/@craco/craco

Ubah react-scripts dengan craco di package.json . Anda

craco.config.js

module.exports = {
    webpack: {
        configure: {
            target: 'electron-renderer'
        }
    }
};

Dan Anda akan memiliki akses ke konteks Elektron Anda seperti itu:

import Electron from 'electron';
const { dialog } = Electron.remote;

@Maxou44 terima kasih atas tip tentang craco & elektron. Hanya itu yang saya butuhkan. Jika ada yang mencari contoh ...

https://github.com/wwlib/cra-craco-electron-example

@wwlib Tidak masalah, senang melihatnya membantu Anda

Lupa mengembalikan nodeIntegration: false yang bahkan menonaktifkan window.require().. . kesalahan bodoh. Semoga ini membuat seseorang meluangkan waktu satu jam untuk meneliti.

Terima kasih banyak.

Harap perhatikan bahwa jika Anda memuat konten jarak jauh, penting untuk menyetel nodeIntegration ke false: https://electronjs.org/docs/tutorial/security#2 -disable-nodejs-integration-for-remote -isi

Hai,
Saya mengalami kesalahan yang sama. Saat menggunakan window.require, kesalahan Uncaught TypeError: fs.readFileSync is not a function telah diperbaiki tetapi saya menemukan kesalahan lain Uncaught TypeError: window.require is not a function .

Apakah ada saran tentang cara memperbaikinya. Saya menggunakan browserify pada node js.

Untuk siapa pun yang masih terjebak dalam hal ini: Anda akan mendapatkan kesalahan window.require is not a function kecuali Anda secara eksplisit mendeklarasikan nodeIntergation sebagai true ketika Anda mendeklarasikan BrowserWindow Anda :

new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
    }
});

Satu-satunya solusi yang cukup baik yang saya temukan adalah sebagai berikut:

  1. instal sebagai dependensi dev paket react-app-rewired
  2. Gunakan modul ini untuk menyuntikkan konfigurasi Webpack kustom tanpa eject -ing CRA:
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. dan tambahkan file config-overrides.js dengan konten yang sesuai:
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

Terima kasih kepada: @Lilanga comment , @agrublev comment dan pencipta react-app-rewired .

Diperbarui:
Sebenarnya versi ke-2 tentang cara melakukan hal yang sama: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Diperbarui2:
@nukeop Saya menghapus beberapa pernyataan menyesatkan karena kurangnya waktu untuk mengikuti perdebatan tentang mengapa tidak menggunakan Browserify atau mengapa menggunakannya dan tidak dapat menuliskan sekarang penjelasan terperinci apa yang saya maksud. Tetapi saya akan menyimpan pendapat pribadi tentang bahwa "gunakan window.require saja akan menyelesaikan masalah" tampaknya sangat tidak dapat diandalkan.

Salah bagaimana?

Ini adalah aplikasi React yang harus berjalan di dalam lingkungan Electron dan bukan sebaliknya

Apa?

_Saya hampir tidak ingin menambahkan ini tetapi itu akan menyelamatkan saya satu atau dua jam dari debugging._

Saya harus rm -rf node_modules && npm install untuk memperbaiki masalah ini. Saya kemudian dapat menghapus window dari window.require dan semuanya mulai berfungsi kembali. Semoga itu membantu orang lain.

Wow.. Mencoba SEMUA di utas ini dan melewatkan replay Anda karena tidak ada upvotes.. Masih mendapat window is not a function ..
dihapus dan diinstal ulang node_modules dan berfungsi.

PS: Anda masih perlu melakukan semua solusi tetapi jika Anda melakukan semuanya
dan masih sama instal ulang node_modules

Anda menyelamatkan hari saya @joshuapinter !

Menggunakan react-create-app saya menemukan kesalahan yang sama.
Solusinya sejauh ini adalah:
const electron = window.require("electron") pada bagian elektron BrowserWindow tambahkan nodeIntegration:true dengan cara berikut.
mainWindow = new BrowserWindow({ width: 900, height: 680, webPreferences: { webSecurity: false, nodeIntegration: true } });

Satu-satunya solusi yang cukup baik yang saya temukan adalah sebagai berikut:

  1. instal sebagai dependensi dev paket react-app-rewired
  2. Gunakan modul ini untuk menyuntikkan konfigurasi Webpack kustom tanpa eject -ing CRA:
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. dan tambahkan file config-overrides.js dengan konten yang sesuai:
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

Terima kasih kepada: @Lilanga comment , @agrublev comment dan pencipta react-app-rewired .

Diperbarui:
Sebenarnya versi ke-2 tentang cara melakukan hal yang sama: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Diperbarui2:
@nukeop Saya menghapus beberapa pernyataan menyesatkan karena kurangnya waktu untuk mengikuti perdebatan tentang mengapa tidak menggunakan Browserify atau mengapa menggunakannya dan tidak dapat menuliskan sekarang penjelasan terperinci apa yang saya maksud. Tetapi saya akan menyimpan pendapat pribadi tentang bahwa "gunakan window.require saja akan menyelesaikan masalah" tampaknya sangat tidak dapat diandalkan.

Ini berhasil untuk saya. Terima kasih

Masalah dengan window.require adalah ini hanya berfungsi untuk paket tingkat atas.
misalnya Jika saya menggunakan fs secara langsung, itu berfungsi. Tetapi jika saya menggunakan paket yang memiliki ketergantungan pada fs maka saya masih mendapatkan pengecualian.

window.require itu tidak berfungsi untuk saya ketika saya memanggil fungsi di dalam Aplikasi React. Saya mendapat "TypeError: window.require bukan fungsi".

App.js :
```javascript
import React, { useEffect, useState } dari 'react';
impor './App.css';

const ipcRenderer = window.require('electron').ipcRenderer;

fungsi Aplikasi() {

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>
);

}

ekspor Aplikasi default;
````

Variabel mainwindow pada Main.js :
```javascript
// Buat jendela browser.
mainWindow = new BrowserWindow({
selaluOnTop: benar,
bingkai: palsu,
layar penuh: salah,
transparan: benar,
titleBarStyle: 'customButtonsOnHover',
menunjukkan: palsu,
lebar: 300,
tinggi: 350,
webPreferensi: {
simpulIntegrasi: benar,
pramuat: __dirname + '/preload.js'
}
});

``` ** Pramuat.js`**:

javascript window.ipcRenderer = require('electron').ipcRenderer;

Apa yang saya lewatkan?

Jadi, masalah terpecahkan. Saya menjawab sendiri karena mungkin seseorang dapat mengambil manfaat darinya (saya terjebak selama berjam-jam). Jika Anda memiliki file Preload.js , Anda tidak perlu memanggil window.require('electron').ipcRenderer lagi dari Àpp.js (renderer); anda memanggil langsung variabel sebagai window.ipcRenderer seperti ini:

App.js :

````javascript
import React, { useEffect, useState } dari 'react';
impor './App.css';

fungsi Aplikasi() {

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>
);

}

ekspor Aplikasi default;
````

Variabel mainwindow pada 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;

Setelah menjalankan aplikasi dari baris perintah, jendela yang dihasilkan oleh proses React akan memunculkan kesalahan (ipcRenderer tidak ditentukan). Abaikan itu. Jendela yang dihasilkan oleh proses Electron (aplikasi utama) akan berfungsi dengan baik.

Dengan Create-React-App 2, Anda dapat menggunakan modul craco npm:

https://www.npmjs.com/package/@craco/craco

Ubah react-scripts dengan craco di package.json . Anda

craco.config.js

module.exports = {
    webpack: {
        configure: {
            target: 'electron-renderer'
        }
    }
};

Saya memiliki masalah saat require("fs") serta window.require("fs") . Terima kasih kepada @Maxou44 untuk pengenalan CRACO dalam diskusi ini.

Untuk mengatasi masalah ini, saya membuat 3 perubahan dalam proyek saya:

  1. Menggunakan CRACO seperti yang disarankan oleh @Maxou44.
  2. Di public/main.js (beberapa mungkin menamai file ini sebagai electron.js), diubah
    new BrowserWindow({ width: 1200, height: 800 })
    ke
    new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } })
  3. Mengganti const fs = require("fs") menjadi const fs = require("electron").remote.require("fs")

Rujuk repo git ini oleh @wwlib untuk klarifikasi lebih lanjut https://github.com/wwlib/cra-craco-electron-example

Saya membaca seluruh utas dari atas ke bawah dan tidak ada yang berhasil.
KECUALI, metode @Saroopashree di atas. Terima kasih @Saroopashree untuk berbagi solusi.
Saya kira sejak react dan webpack agak berubah sejak awal utas, solusi di atas sudah usang. Saya mungkin salah tentu saja tetapi menggunakan metode di atas berhasil.
Inilah yang saya lakukan:

  1. Menjalankan npm install craco -D
  2. Buat file konfigurasi craco.config.js dan tempel kode berikut:
    module.exports = { webpack: { configure: { target: 'electron-renderer' } } };
  3. Memperbarui new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } }) di main.js. Tentunya dengan lebar dan tinggi yang berbeda.
  4. Jalankan npm start untuk memulai server pengembangan untuk aplikasi reaksi yang dibuat menggunakan create-react-app. Ini membuka tab dengan kesalahan yang sama. Dan aku merasa lelah lagi.
  5. Jalankan npm run electron untuk menjalankan aplikasi elektron.
    Dan Viola!!! Saya bisa melihat halamannya.

Jadi terima kasih @Saroopashree.

Jika Anda mencoba mengakses 'elektron' atau komponen lainnya di dalam komponen/kelas reaksi, coba ini: #336757899

Terima kasih kepada @tummbledwyer karena telah memposting tautan ke solusi yang sesuai untuk saya:

Diperbarui:
Sebenarnya versi ke-2 tentang cara melakukan hal yang sama: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Solusi dari Randy Findley:
Sekarang, jika Anda perlu mengakses modul fs seperti yang saya lakukan, Anda akan segera menemukan kesalahan Module not found

Pertama, instal Rescripts .

yarn add @rescripts/cli @rescripts/rescript-env --dev

Kemudian, ubah tag skrip di package.json dari ini ...

"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",

untuk ini

"start": "rescripts start",
"build": "rescripts build",
"test": "rescripts test",

Sekarang tambahkan file baru bernama .rescriptsrc.js dengan isi sebagai berikut:

module.exports = [require.resolve('./.webpack.config.js')]

Terakhir tambahkan file baru lainnya bernama .webpack.config.js dengan isi sebagai berikut:

// define child rescript
module.exports = config => {
  config.target = 'electron-renderer';
  return config;
}

Sekarang Anda dapat menggunakan modul fs , jangan khawatir.

Apa yang ditunjukkan @ledleds berhasil untuk saya, menggunakan CRA dengan typscript dan Electron. Maka masalahnya adalah saya mendeklarasikan webPreferences seperti ini:

    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    },

sehingga tampaknya menimpa/mengatur nodeIntegration ke false, jadi menyetelnya ke true dan meluncurkan kembali aplikasi memecahkan masalah (Anda harus meluncurkan kembali aplikasi untuk memuat jendela Electron dengan konfigurasi itu)

mengatur nodeIntegration menjadi true seperti ini

    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true
    },

Untuk siapa pun yang masih terjebak dalam hal ini: Anda akan mendapatkan kesalahan window.require is not a function kecuali Anda secara eksplisit mendeklarasikan nodeIntergation sebagai true ketika Anda mendeklarasikan BrowserWindow Anda :

new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
    }
});

reaksi-aplikasi-rewired

Ini adalah satu-satunya solusi bagus yang saya temukan dalam hal skalabilitas, saya tidak berpikir siapa pun harus bergantung pada window.require

Mengapa window.require tidak dapat diskalakan?

Bagi siapa saja yang kebetulan mengalami masalah ini atau masalah serupa dan menggunakan Vue dan pembuat elektron vue, lihat di sini

Bagi siapa pun yang masih berjuang dengan ini terutama mengenai keluar dari aplikasi elektron melalui tombol reaksi, silakan baca terus.

Apa yang membantu saya adalah sebagai berikut:

  1. Ketika Anda mendeklarasikan jendela Anda, pastikan Anda menyetel nodeIntegration: true karena ini saat ini secara default false untuk alasan keamanan. Biasanya itu dilakukan di file electron.js Anda.

  2. Seperti yang telah disebutkan @packetstracer : _Anda harus meluncurkan kembali aplikasi untuk memuat jendela Electron dengan konfigurasi itu_

mainWindow = new BrowserWindow({
//...
  webPreferences: {
    nodeIntegration: true,
  },
});
  1. Juga di electron.js Anda, letakkan pernyataan berikut di dekat bagian atas ini memastikan bahwa ipcMain akan mendengarkan acara _"close-me"_:
const { ipcMain } = require("electron");
ipcMain.on("close-me", (evt, arg) => {
  app.quit();
});
  1. Di komponen reaksi tempat tombol _"close"_ Anda berada, tambahkan pernyataan window.require berikut setelah impor Anda. require yang biasa tidak berfungsi:
const ipcRenderer = window.require("electron").ipcRenderer;
  1. Dan untuk menutup aplikasi Anda, panggil pernyataan berikut. Itu harus mengirim acara _"close-me"_ ke ipcMain:
<Button label="close" onClick={(e) => ipcRenderer.send("close-me")} />

Jangan ragu untuk berkomentar dan memberikan umpan balik Saya masih baru di elektron.
Saya tahu konteks dengan tombol berhenti tidak terkait tetapi saya tidak dapat menemukan utas yang lebih cocok. Silakan arahkan saya ke utas lain yang lebih cocok jika ada.

Konfigurasi saya:

"electron": "9.2.0",
"electron-builder": "22.8.0",
"electron-packager": "15.0.0",

diselesaikan untuk saya!! Terima kasih @nukeop

`
`

Adakah yang tahu cara mengatur tipe yang tepat di TypeScript?

Saya memiliki yang berikut saat ini

export const electron = window.require('electron').remote

Saya ingin sesuatu seperti

export const electron = window.require('electron').remote as ElectronType

jadi IDE tahu cara melengkapi API elektron secara otomatis.

@timsamart itu berhasil. Terima kasih, ini menghemat hari kerja saya. 🤣.

Setelah menghabiskan berjam-jam mencoba semua hal di atas, saya melewatkan bagian jika Anda menggunakan BrowserView , seperti BrowserWindow Anda perlu mengaktifkan node.js secara eksplisit:

     new BrowserView({ // is a BrowserView not a BrowserWindow
        webPreferences: {
          nodeIntegration: true,
        },
      })
Apakah halaman ini membantu?
0 / 5 - 0 peringkat