Electron: Exigir elétron fora do main.js causa um TypeError

Criado em 22 set. 2016  ·  82Comentários  ·  Fonte: electron/electron

  • Versão eletrônica: 1.3.5
  • Sistema operacional: Mint 17

Olá

Estou usando o Electron com React.js e babelify, entre outros plugins (lista na parte inferior).
A tentativa de usar require('electron') , por exemplo, para obter acesso ao BrowserWindow do electron, resulta no console mostrando o seguinte erro:
index.js:4 Uncaught TypeError: fs.readFileSync is not a function

Eu posso, no entanto, usar const electron = require('electron'); em main.js. Por que vale a pena, também estou usando watchify para empacotar tudo em um pacote js.

Aqui está a lista completa de dependências no meu 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"
    },
blockeneed-info ❌

Comentários muito úteis

Para quem encontrar esse problema no futuro e ler este tópico, usar window.require em vez de require é uma possibilidade de evitar o conflito entre a função require do electron e do browserify.

Todos 82 comentários

index.js:4 Uncaught TypeError: fs.readFileSync não é uma função

Você pode incluir a linha 4 de index.js aqui? Ou um rastreamento de pilha mais completo?

Acredito que esteja se referindo ao index.js do electron, que está localizado nos módulos de nó do projeto. Aqui está o conteúdo deste arquivo:

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

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

O rastreamento de pilha inteiro sugere um conflito com o React.js:

Stack trace

O que acontece se você executar require('fs').readFileSync na guia Console das ferramentas de desenvolvimento?

Parece que o módulo de nó electron-prebuilt (o arquivo que você colou) está terminando em seu aplicativo empacotado, o que não acho que você queira, pois ele deve usar o electron built-in require.

@nukeop Como você está lançando seu aplicativo. Seu script de início deve se parecer com.

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

Tenho a sensação de que você está tentando executar seu main.js com node

node main.js

O que não vai funcionar

O que acontece se você executar require('fs').readFileSync na guia Console das ferramentas de desenvolvimento?

Logo após esse erro ser lançado, consigo executar require('fs').existsSync no console para imprimir uma definição da função. Também funciona antes do erro.

Parece que o módulo de nó pré-construído de elétrons (o arquivo que você colou) está terminando em seu aplicativo empacotado, o que eu não acho que você queira, pois ele deve usar o elétron interno require.

Eu tenho uma instância watchify em execução em segundo plano enquanto estou desenvolvendo, que está atualizando continuamente meu pacote. Eu o defini na seção de scripts do package.json assim:

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

Algum conselho sobre como evitar o pacote electron-prebuilt ?

O suporte ao @nukeop Electron requer internamente para que você não precise usar o browserify.

Tanto quanto sei, se você quiser usar o browserify, deve excluir "electron".

Interessante, será que watchify/browserify está arruinando isso? Tem funcionado bem até agora.

Agora não sei como executar o programa sem ele.

Literalmente apenas corra

electron .

Na pasta principal do aplicativo, você não precisa agrupar nada ao usar o Electron, pois ele possui um ambiente de nó completo internamente.

_Vou fechar isso, pois é um problema do Browserify_

Isso é o que eu tenho feito o tempo todo, empacotando o programa em um único arquivo .js, que é incluído em um arquivo html simples com:

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

E tudo funciona, exceto quando eu uso require. Este é um problema com a interação entre os dois módulos.

Se eu não empacotar o programa inteiro em um pacote, não tenho uma maneira fácil de executá-lo, pois meu main.js apenas inicia o electron e carrega o arquivo html que inclui o pacote.

@nukeop O processo de renderização dentro do Electron também tem acesso a um ambiente de node/commonjs completo, então você não precisa empacotar nada.

Se eu não empacotar o programa inteiro em um pacote, não tenho uma maneira fácil de executá-lo, pois meu main.js apenas inicia o electron e carrega o arquivo html que inclui o pacote.

Não tenho certeza se entendi aqui, qualquer script que você carrega em seu arquivo HTML tem um ambiente commonjs completo e, portanto, pode usar require para carregar arquivos extras sem navegar em nada

Para quem encontrar esse problema no futuro e ler este tópico, usar window.require em vez de require é uma possibilidade de evitar o conflito entre a função require do electron e do browserify.

FWIW, me deparei com o mesmo problema ao tentar usar o electron no processo de renderização com create-react-app que usa webpack no back-end em vez de browserify. window.require parece resolver isso para mim também, embora eu não esteja totalmente claro por quê.

Edit : Eu descobri o porquê :-) Queremos require electron durante o tempo de execução do ambiente nodejs fornecido no tempo de execução, em vez do ambiente nodejs usado durante a compilação pelo webpack. Por padrão, os globais estão vinculados a window e a compilação do webpack ignora o window global - portanto, window.require funciona.

Outra maneira de dizer ao webpack para ignorar um nome global é usar um comentário como /*global Android*/ no arquivo JS. Em outro projeto usando o aplicativo CRA construído em um Android WebView, usei o acima para obter acesso a um objeto Java exposto ao JS por meio da interface JavaScript fornecida pelo Webview.

@nukeop - obrigado pelo seu último post; isto me ajudou bastante. window.require funcionou para mim.

sim corrigiu meu problema de criação de aplicativo / webpack.
mudança

import electron, { ipcRenderer } from 'electron'

para

const electron = window.require("electron")

@srinathh como você está expondo/carregando seu aplicativo CRA como renderizador no seu main? você está construindo primeiro (e modificando os caminhos de recursos estáticos html)

Sim, meu fluxo de trabalho atualmente é basicamente executar npm run build usando os scripts CRA e, em seguida, executar a saída na pasta build com o electron. Você não precisa modificar manualmente os caminhos de recursos estáticos. Nos scripts package.json para CRA, você só precisa definir o homepage assim e os caminhos serão definidos adequadamente.

    "homepage": "./"

Além disso, tenho main.js e package.json para o aplicativo de elétrons na pasta public . Portanto, executar a compilação os copia automaticamente e você pode simplesmente executar electron build/ para iniciar seu aplicativo.

Eu realmente gostaria de poder fazer o npm start com o electron para desenvolvimento, mas não consegui descobrir como fazer isso funcionar. Acho que vou ter que fazer um eject e modificar o script manualmente.

Se você quiser ver um exemplo da configuração - dê uma olhada em https://github.com/srinathh/snippetfu

Não estou usando o Electron, mas o Node-Webkit (nw.js).
Usar window.require também resolveu meu problema. Muito obrigado por isso!

@nukeop window.require fez o truque para mim também, muito obrigado! 🎉

@nukeop Recebi o mesmo erro, mas está resolvido o truque window.require, muito obrigado!

window.require resolveu o problema de fs.existsSync is not a function , mas levou a outro erro: window.require não é uma função. Como devo resolvê-lo?

@steric85 você está usando browserify, babel ou webpack? você pode precisar transpilar seu código

@Alxmerino Estou usando o webpack.

verifique se você está compilando seu código

@steric85 , eu enfrentei o window.require is not a function no typescript, consegui consertar assim:

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

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

Estou usando o método acima para acessar o ipcRenderer do electron no meu aplicativo Angular, mas a detecção de alterações Angular não está funcionando quando atualizo um Observable usando um manipulador de mensagens ipcRenderer.
É porque o Angular não sabe que o ipcRenderer é um EventEmitter e que precisa executar a detecção de alterações quando os eventos do ipcRenderer chegam?

em Angular 2 eu costumava chamar applicationRef.tick() para dizer explicitamente ao angular para atualizar seu estado. https://angular.io/api/core/ApplicationRef

Estou enfrentando um problema muito semelhante ao @nukeop e @srinathh : configurei meu projeto Electron + React + Webpack seguindo este guia de artigo , onde o autor no final menciona o truque com window.require . Eu só require('electron') dois lugares no meu projeto; no ponto de entrada para o Electron e em uma classe de controlador JavaScript que é exigida por alguns componentes do React. No meu arquivo de ponto de entrada do Electron eu simplesmente faço const electron = require('electron'); , já que ele deve estar rodando no processo principal (certo?), e na minha classe de controlador eu faço const Electron = window.require('electron').remote; seguido por const Jsonfile = Electron.require('jsonfile'); , que deve ser a maneira de fazer isso, pois está sendo executado no processo de renderização. Mas recebo o mesmo erro que @nukeop ("TypeError: fs.ExistsSync não é uma função") na linha seis em node_modules/electron/index.js que se parece com isso:

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

Eu tentei excluir node_modules/electron e instalar novamente.
Estou usando o Electron 1.7.5 no macOS 10.12.6 e começo meu projeto usando npm run dev conforme configuração no artigo.

Atualizar; Encontrei o require que causou meu erro, tentei fazer require('electron-react-devtools') no meu React index.js. Mudar para const ReactDevtools = Electron.require('electron-react-devtools'); parou os erros, mas agora parece que não consigo chamar .inject() na instância do ReactDevtools ("não é uma função"), mas isso pode não ser algo para discutir aqui .

@steric85 É porque você está executando o aplicativo no ambiente da página da Web => você deve executar o aplicativo no ambiente Electron (ambiente Nodejs)

  • require('electron') => Webpack irá agrupar o módulo electron para bundle.js => electron use fs module => Webpack não entende
  • window.require('electron') => Webpack irá ignorar a função require
  • No ambiente da página da web, window.require será indefinido
  • No ambiente nodejs, window.require funcionará
    => Abra seu aplicativo na janela Electron (não na janela do navegador como Chrome, Firefox, etc.

Ainda estou recebendo window.require is not a function . Estou usando o Electron com o React Starter Kit (https://github.com/kriasoft/react-starter-kit). Tudo está funcionando bem, exceto isso.

Eu configurei meu aplicativo Electron para carregar meu aplicativo da web, então o aplicativo não está sendo executado localmente:
https://gist.github.com/holgersindbaek/68f6db82f507967a51ca75c527faeff6

O que estou tentando fazer é chamar o ipcRenderer em um dos meus arquivos React. Não tenho certeza se é possível quando meu aplicativo está sendo carregado da web. Alguma sugestão?

@holgersindbaek Você não deve visualizar seu aplicativo em navegadores como Chrome, Firefox, etc. Não funcionará porque é o ambiente da página da web.
Você deve visualizar seu aplicativo em uma janela do Electron.

Estou, mas estou usando o Electron de uma maneira, onde estou carregando meu aplicativo do site em cada lançamento. Essencialmente, estou mostrando um site no meu aplicativo de elétrons. Veja o arquivo acima. Eu só quero ter certeza de que não há realmente nada que eu possa fazer?!

Electron pode carregar qualquer URL. Para carregar uma URL você deve usar esta função mainWindow.loadURL(url)
=> Na visualização da janela eletrônica, esse código javascript da URL pode acessar require, ipc, etc.

OK. Vou tentar isso.

window.require no elétron não funcionou, mas window.require para fs sim.

Não tenho certeza do porquê. Mas está funcionando e, como é um pequeno projeto pessoal, não vou insistir no assunto.

Obrigado @nukeop

Oi, Este é o meu package.json, estou usando o webpack, nenhum deles resolveu meu problema, alguém tem uma solução? Depois de usar window.require, recebi o erro "a janela não está definida"

'usar estrito';

var elétron = require('elétron')
var app = elétron.app;
var BrowserWindow = electron.BrowserWindow;
var janela principal = null;

app.on('pronto', function() {
mainWindow = new BrowserWindow({largura: 800, altura: 600});

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

mainWindow.webContents.openDevTools();

});

Estou usando texto datilografado e tive que usar

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

para fazer com que meu renderizador se comunique com meu main. Espero que isso ajude alguém.

Isso funcionou para mim.
Por exemplo, se você deseja exigir controle remoto, então

declare const window: any;
const { remoto } = window.require('electron');

Olá, obrigado cara.

No domingo, 3 de dezembro de 2017 às 21h29, Michael - ሚካኤል ሰልጠነ <
[email protected]> escreveu:

Isso funcionou para mim.
Por exemplo, se você deseja exigir controle remoto, então

declare const window: any;
const { remoto } = window.require('electron');


Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/electron/electron/issues/7300#issuecomment-348801405 ,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/ARDyd4c3aOkMbb058xklujMMbnmaoxKGks5s8uGVgaJpZM4KDU6t
.

@solominh Obrigado por suas explicações aqui . No entanto, tenho uma configuração semelhante a @holgersindbaek , qual ambiente é um script de pré-carregamento em um webview?

Informações:

  • Minha entrada de elétron é mainWindow.loadURL(url) , onde url é um index.html local
  • Este index.html tem um <webview>
  • A webview tem um campo preload que carrega inject.js, e este script faz o window.require('electron').

Observações:

  • Se eu usar const electron = require('electron') , tenho o erro fs.readFileSync is not a function
  • Se eu usar const electron = window.require('electron') , tenho o erro window.require is not a function .
  • inject.js é empacotado através do webpack (pode colar a configuração se for relevante).

EDIT: Resolvido para mim usando <webview nodeintegration="true"> e window.require. Deixando nota aqui para referência futura.

window.require funcionou para mim! Obrigado rapazes!

https://imgur.com/a/ekWwD

mensagem de erro no navegador quando eu tentei isso

Esqueci de reverter nodeIntegration: false que desativa até window.require().. . erro estúpido. Espero que isso poupe alguém de uma hora de pesquisa.

@phil294 Obrigado cara! você realmente economizou uma hora de pesquisa.

Olá @micsel ,
Eu incluí declare const window: any;
mas está dando erro de sintaxe.
Alguma idéia por quê?

Sim, coloque declare const window: any; no topo, logo após onde estão as importações.

Se você obtiver window.require não for uma função e estiver usando Angular-CLI, use o seguinte para instanciar a interface Window:

./src/typings.d.ts

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

Então você pode usar isso para incluir o elétron:
const { ipcRenderer } = window.require('electron');

se você estiver usando angular 2+ no aplicativo de elétrons, importe a lib "ngx-electron" e use-a em any.componets.ts

import { ElectronService } from 'ngx-electron';

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

Estou usando react js com electron e quando executo esta linha no terminal yarn run start me fornece erro Uncaught Type Error: window.require não é uma função não estou usando typescript como declarar janela em React Js

Pessoas que ainda estão enfrentando o problema, de alguma forma fazer um window.require() estraga a consistência do uso de instruções import em toda a base de código. Uma alternativa fácil é configurar seu webpack target para electron-renderer . Se estiver usando Create React App , ejetar pode ser uma bagunça. Portanto, você pode usar este pacote que faz o engate do webpack para você e você pode usar, por exemplo, import fs from 'fs' em seus componentes React (ou qualquer outro módulo de nó), felizmente em sua vida :)

Em janelas com Vue CLI 3, window.require funcionará, mas exigirá um caminho completo em vez de um caminho relativo de "node_modules/".

Mas semelhante ao caso do React, o webpack pode ser configurado corretamente para o Vue editando vue.config.js. "require" funcionará conforme o esperado.

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 (este é apenas um exemplo, funcionaria em qualquer outro arquivo vue js)

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

_Eu quase não quero adicionar isso, mas teria me poupado uma ou duas horas de depuração._

Eu tive que rm -rf node_modules && npm install para corrigir esse problema. Consegui então remover o window de window.require e as coisas começaram a funcionar novamente. Espero que isso ajude outra pessoa.

@cperthuis Eu só quero dizer OBRIGADO!! Hahah eu nem estou usando Vue, mas o pensamento lógico me levou a descobrir que posso mudar meu webpack.config.js para ter uma propriedade de destino :)
image
FUNCIONOU COMO UM CHARME.

Oi,

window.require funciona em um ambiente de servidor local dev, mas não em um ambiente de produção depois de construir o aplicativo React para um arquivo HTML reduzido.

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

Funciona com localhost:3000 mas não com file://${path.join(__dirname, 'build/index.html')}

https://imgur.com/EE7jxZq

@cperthuis , sua correção funcionou para o aplicativo CRA não ejetado usando 'react-app-rewired'. obrigado.
image

Com Create-React-App 2, você pode usar o módulo craco npm:

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

Altere react-scripts por craco no seu package.json

craco.config.js

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

E em você terá acesso ao seu contexto Electron assim:

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

@ Maxou44 obrigado pela dica sobre craco e elétron. É exatamente o que eu precisava. Caso alguém esteja procurando um exemplo...

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

@wwlib Sem problemas, fico feliz em ver que te ajudou 🥳

Esqueci de reverter nodeIntegration: false que desativa até window.require().. . erro estúpido. Espero que isso poupe alguém de uma hora de pesquisa.

Muito obrigado.

Observe que, se você estiver carregando conteúdo remoto, é importante definir nodeIntegration como false: https://electronjs.org/docs/tutorial/security#2 -disable-nodejs-integration-for-remote -contente

Oi,
Estou com o mesmo erro. Ao usar window.require, o erro Uncaught TypeError: fs.readFileSync is not a function é corrigido, mas encontrei outro erro Uncaught TypeError: window.require is not a function .

Existe alguma sugestão sobre como corrigir isso. Estou usando o browserify no nó js.

Para quem ainda está preso nisso: você receberá o erro window.require is not a function , a menos que declare explicitamente nodeIntergation como true ao declarar seu BrowserWindow :

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

A única solução boa o suficiente que encontrei é a seguinte:

  1. instalar como pacote de dependência dev react-app-rewired
  2. Use este módulo para injetar a configuração personalizada do Webpack sem eject -ing o CRA:
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. e adicione o arquivo config-overrides.js com o conteúdo de acordo:
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

Obrigado a: @Lilanga comment , @agrublev e criadores de react -app-rewired .

Atualizada:
Na verdade, a 2ª versão de como fazer o mesmo: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Atualizado2:
@nukeop Eu removi algumas declarações enganosas devido à falta de tempo para acompanhar os debates sobre por que não usar o Browserify ou por que usá-lo e não posso escrever agora uma explicação detalhada do que eu quis dizer. Mas vou manter a opinião pessoal de que "basta usar window.require vai resolver o problema" parece muito pouco confiável.

Incorreto como?

É um aplicativo React que deve estar rodando dentro do ambiente Electron e não vice-versa

Que?

_Eu quase não quero adicionar isso, mas teria me poupado uma ou duas horas de depuração._

Eu tive que rm -rf node_modules && npm install para corrigir esse problema. Consegui então remover o window de window.require e as coisas começaram a funcionar novamente. Espero que isso ajude outra pessoa.

Uau .. Tentei TUDO neste tópico e perdi seu replay porque não há votos positivos .. Ainda tenho window is not a function ..
removido e reinstalado node_modules e está funcionando.

PS: você ainda precisa fazer todas as soluções, mas se você fez tudo
e ainda o mesmo reinstale node_modules

Você salvou meu dia @joshuapinter !

Usando react-create-app, encontrei os mesmos erros.
A solução até agora foi:
const electron = window.require("electron") na parte eletrônica BrowserWindow adicione nodeIntegration:true da seguinte maneira.
mainWindow = new BrowserWindow({ width: 900, height: 680, webPreferences: { webSecurity: false, nodeIntegration: true } });

A única solução boa o suficiente que encontrei é a seguinte:

  1. instalar como pacote de dependência dev react-app-rewired
  2. Use este módulo para injetar a configuração personalizada do Webpack sem eject -ing o CRA:
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. e adicione o arquivo config-overrides.js com o conteúdo de acordo:
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

Obrigado a: @Lilanga comment , @agrublev e criadores de react -app-rewired .

Atualizada:
Na verdade, a 2ª versão de como fazer o mesmo: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Atualizado2:
@nukeop Eu removi algumas declarações enganosas devido à falta de tempo para acompanhar os debates sobre por que não usar o Browserify ou por que usá-lo e não posso escrever agora uma explicação detalhada do que eu quis dizer. Mas vou manter a opinião pessoal de que "basta usar window.require vai resolver o problema" parece muito pouco confiável.

Isso funcionou para mim. Obrigada

O problema com window.require é que ele só funciona para o pacote de nível superior.
por exemplo, se estou usando fs diretamente, funciona. Mas se estou usando um pacote que tem uma dependência de fs , ainda recebo uma exceção.

window.require não está funcionando para mim quando chamo a função dentro do React App. Eu tenho "TypeError: window.require não é uma função".

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

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

função 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>
);

}

exportar aplicativo padrão;
````

Variável da janela principal em Main.js :
```javascript
// Cria a janela do navegador.
mainWindow = new BrowserWindow({
sempreOnTop: verdadeiro,
quadro: falso,
fullscreenable: falso,
transparente: verdadeiro,
titleBarStyle: 'customButtonsOnHover',
mostrar: falso,
largura: 300,
altura: 350,
webPreferences: {
nodeIntegration: true,
pré-carregamento: __dirname + '/preload.js'
}
});

``` ** Preload.js`**:

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

O que estou perdendo?

Então, questão resolvida. Eu mesmo respondo porque talvez alguém possa se beneficiar com isso (fiquei por horas). Se você tem um arquivo Preload.js , você não precisa chamar window.require('electron').ipcRenderer novamente do Àpp.js (renderer); você chama diretamente a variável como window.ipcRenderer assim:

App.js :

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

função 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>
);

}

exportar aplicativo padrão;
````

Variável da janela principal em 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;

Depois de executar o aplicativo a partir da linha de comando, a janela gerada pelo processo React gerará um erro (ipcRenderer é indefinido). Ignore isto. A janela gerada pelo processo Electron (aplicativo principal) funcionará bem.

Com Create-React-App 2, você pode usar o módulo craco npm:

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

Altere react-scripts por craco no seu package.json

craco.config.js

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

Eu tive os problemas enquanto require("fs") assim como window.require("fs") . Obrigado a @Maxou44 pela introdução do CRCO nesta discussão.

Para resolver o problema fiz 3 alterações no meu projeto:

  1. Usei CRCO como sugerido por @Maxou44.
  2. Em public/main.js (alguns podem ter nomeado este arquivo como electron.js), alterado
    new BrowserWindow({ width: 1200, height: 800 })
    para
    new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } })
  3. Substituído const fs = require("fs") para const fs = require("electron").remote.require("fs")

Consulte este repositório git por @wwlib para obter mais esclarecimentos https://github.com/wwlib/cra-craco-electron-example

Li o tópico inteiro de cima para baixo e nada funcionou.
EXCETO, o método de @Saroopashree acima. Obrigado @Saroopashree por compartilhar a solução.
Eu acho que como react e webpack mudaram um pouco desde o início do tópico, as soluções acima são obsoletas. Eu posso estar errado, claro, mas usando o método acima funcionou.
Isto é o que eu fiz:

  1. Correu npm install craco -D
  2. Crie o arquivo de configuração craco.config.js e cole o seguinte código
    module.exports = { webpack: { configure: { target: 'electron-renderer' } } };
  3. new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } }) atualizado em main.js. Claro com largura e altura diferentes.
  4. Executou npm start para iniciar o servidor de desenvolvimento para o aplicativo react criado usando create-react-app. Isso abriu uma guia com os mesmos erros. E me senti cansada novamente.
  5. Executou npm run electron para executar o aplicativo de elétrons.
    E Viola!!! Consegui ver a página.

Então, obrigado @Saroopashree.

Se você está tentando acessar 'electron' ou seu outro componente dentro de um componente/classe de reação, tente isto: #336757899

Obrigado a @tumbledwyer por postar o link para uma solução que funciona para mim:

Atualizada:
Na verdade, a 2ª versão de como fazer o mesmo: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

A solução de Randy Findley:
Agora, se você precisar acessar o módulo fs como eu fiz, você rapidamente atingirá o erro Module not found

Primeiro, instale o Rescripts .

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

Em seguida, altere as tags de scripts em package.json deste...

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

para isso

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

Agora adicione um novo arquivo chamado .rescriptsrc.js com o seguinte conteúdo:

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

Por fim, adicione outro novo arquivo chamado .webpack.config.js com o seguinte conteúdo:

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

Agora você pode usar o módulo fs , sem preocupações.

O que @ledleds apontou funcionou para mim, usando CRA com typscript e Electron. Então a coisa é que eu declarei webPreferences assim:

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

então parece estar substituindo/definindo nodeIntegration como false, então defini-lo como true e reiniciar o aplicativo resolveu o problema (você precisa reiniciar o aplicativo para carregar a janela Electron com essa configuração)

definindo nodeIntegration como true assim

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

Para quem ainda está preso nisso: você receberá o erro window.require is not a function , a menos que declare explicitamente nodeIntergation como true ao declarar seu BrowserWindow :

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

react-app-rewired

Essa foi a única boa solução que encontrei em termos de escalabilidade, acho que ninguém deveria confiar no window.require

Por que window.requir não seria escalável?

Para quem está lutando com este ou problemas semelhantes e está usando o Vue e o vue-electron-builder, veja aqui

Para quem ainda está lutando com isso, especialmente em relação a sair do aplicativo de elétrons através de um botão de reação, continue lendo.

O que me ajudou foi o seguinte:

  1. Quando você declarar sua janela, certifique-se de definir nodeIntegration: true , pois isso é atualmente por padrão false por motivos de segurança. Normalmente isso é feito em seu arquivo electron.js .

  2. Como o @packetstracer já mencionou: _você precisa reiniciar o aplicativo para carregar a janela do Electron com essa configuração_

mainWindow = new BrowserWindow({
//...
  webPreferences: {
    nodeIntegration: true,
  },
});
  1. Também no seu electron.js coloque a seguinte declaração perto do topo, isso garante que o ipcMain vai ouvir no evento _"close-me"_:
const { ipcMain } = require("electron");
ipcMain.on("close-me", (evt, arg) => {
  app.quit();
});
  1. No componente react onde seu botão _"close"_ está localizado, adicione a seguinte instrução window.require após suas importações. O require usual não funcionou:
const ipcRenderer = window.require("electron").ipcRenderer;
  1. E para fechar seu aplicativo, chame a seguinte instrução. Ele deve enviar o evento _"close-me"_ para o ipcMain:
<Button label="close" onClick={(e) => ipcRenderer.send("close-me")} />

Sinta-se à vontade para comentar e dar feedback Eu ainda sou novo no elétron.
Eu sei que o contexto com o botão sair não está relacionado, mas não consegui encontrar um tópico mais adequado. Por favor, sinta-se à vontade para me indicar outro tópico mais adequado, se houver um.

Minha configuração:

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

resolvido para mim!! Obrigado @nukeop

`
`

Alguém sabe como configurar o tipo adequado no texto datilografado?

tenho o seguinte no momento

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

gostaria de algo como

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

para que o IDE saiba como preencher automaticamente a API do elétron.

@timsamart funciona. Obrigado, me poupa dias de trabalho. 🤣

Depois de passar muitas horas tentando literalmente tudo acima, perdi a parte caso você use BrowserView , assim como BrowserWindow você precisa habilitar explicitamente o node.js:

     new BrowserView({ // is a BrowserView not a BrowserWindow
        webPreferences: {
          nodeIntegration: true,
        },
      })
Esta página foi útil?
0 / 5 - 0 avaliações