Elétron: jQuery não está definido

315

Problema: ao desenvolver o uso do Electron, quando você tenta usar qualquer plug-in JS que exija jQuery, o plug-in não encontra o jQuery, mesmo se você carregar o caminho correto usando tags de script.

Por exemplo,

<body>
<p id="click-me">Click me!</p>
...
<script src="node_modules/jquery/dist/jquery.min.js"></script> //jQuery should be loaded now
<script>$("#click-me").click(() => {alert("Clicked")});</script>
</body>

A execução desse código acima não funcionaria. De fato, abra o DevTools, acesse a visualização Console e clique no <p>elemento Você deve ver isso function $ is not definedou algo nesse sentido.

Bruno Vaz
fonte
Por que não usar apenas a requirefunção Electron ?

Respostas:

762

Uma solução melhor e mais genérica IMO:

<!-- Insert this line above script imports  -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>

<!-- normal script imports etc  -->
<script src="scripts/jquery.min.js"></script>    
<script src="scripts/vendor.js"></script>    

<!-- Insert this line after script imports -->
<script>if (window.module) module = window.module;</script>

Benefícios

  • Funciona para navegador e elétron com o mesmo código
  • Corrige problemas para TODAS as bibliotecas de terceiros (não apenas jQuery) sem precisar especificar cada uma
  • Compatível com a criação / compactação de scripts (ou seja, Grunt / Gulp todos os scripts em vendor.js)
  • NÃO requer node-integrationser falso

fonte aqui

Dale Harders
fonte
1
@fareednamrouti Sim, mas o objetivo desta solução é que você não precisa listar as bibliotecas de terceiros (simplesmente funciona!). Calhar quando você está importando muitas bibliotecas (ou scripts de auto empacotado)
Dale Harders
2
obrigado! no meu caso, esta solução também funciona para versões mais antigas do d3 como v3 d3 ou abaixo
ventos contrários
2
@DaleHarders Acontece que window.modulecomeça com o mesmo valor que module, para que seu código não funcione conforme o esperado. A maneira correta de fazer isso é salvar moduleem alguma outra propriedade da janela (não usada), como window.tempModule. Para confirmar o que eu digo, tente console.log(module)após sua última declaração para verificar isso agora module === undefined.
Lucio Paiva
1
@Lucio Nope. Precisamos salvar em window.module, pois é nesse local que as bibliotecas de terceiros o esperam (ambiente do navegador). Eu acho que você está confundindo Node.js e ambientes de navegador. Esse truque é auxiliar no desenvolvimento para que seu código possa ser executado no navegador E no nó / elétron sem nenhuma configuração adicional. Existem muitas outras maneiras de fazer isso, mas esse é o IMHO mais simples.
Dale Harders
1
Isso é problemático com CSP-sem scripts em linha
Trevor
121

Como visto em https://github.com/atom/electron/issues/254, o problema é causado por causa deste código:

if ( typeof module === "object" && typeof module.exports === "object" ) {
  // set jQuery in `module`
} else {
  // set jQuery in `window`
}

O código jQuery "vê" que está sendo executado em um ambiente CommonJS e ignora window.

A solução é realmente fácil , em vez de carregar o jQuery <script src="...">, você deve carregar assim:

<script>window.$ = window.jQuery = require('./path/to/jquery');</script>

Nota: o ponto antes do caminho é obrigatório , pois indica que é o diretório atual. Além disso, lembre-se de carregar o jQuery antes de carregar qualquer outro plugin que dependa dele .

Bruno Vaz
fonte
1
Obrigado, mas eu tenho um sistema criado por yeoman com angular. O Grunt pega todas as minhas dependências do caramanchão e as transforma em um arquivo vendor.js. Como carregar o jquery, corrigir com sua linha e continuar com as outras dependências do bower que precisam do jquery?
precisa saber é o seguinte
Eu não entendo, o vendor.js tem jquery dentro? Nesse caso, você pode carregar o vendor.js com esta janela. $ Method, afaik.
Bruno Vaz
Alguns comentários mais adiante na questão vinculada há uma solução ainda melhor: 'node-integration': falsecomo opção BrowserWindow.
Boldewyn
6
Isso não afeta outras coisas?
Bruno Vaz
53

Outra maneira de escrever <script>window.$ = window.jQuery = require('./path/to/jquery');</script>é:

<script src="./path/to/jquery" onload="window.$ = window.jQuery = module.exports;"></script>
Aaleks
fonte
Achei isso como a melhor resposta, porque ainda posso usar a CDN! E não há necessidade de substituir nada.
Patotoma 01/06/19
53

resposta eletrônica do FAQ:

http://electron.atom.io/docs/faq/

Não posso usar jQuery / RequireJS / Meteor / AngularJS no Electron.

Devido à integração do Electron no Node.js., existem alguns símbolos extras inseridos no módulo DOM, como as exportações exigem. Isso causa problemas para algumas bibliotecas, pois elas desejam inserir os símbolos com os mesmos nomes.

Para resolver isso, você pode desativar a integração de nós no Electron:

// No processo principal.

let win = new BrowserWindow({  
 webPreferences: {
 nodeIntegration: false   } });

Mas se você quiser manter as habilidades de usar APIs Node.js e Electron, precisará renomear os símbolos na página antes de incluir outras bibliotecas:

<head> 
<script> 
window.nodeRequire = require; 
delete window.require;
delete window.exports; delete window.module; 
</script> 
<script type="text/javascript" src="jquery.js"></script> 
</head>
Fran6
fonte
@ Fran6 o que posso fazer se estiver carregando uma página externa? :(
georgiosd
Isso funcionou, mas depois disso, meu aplicativo Electron não foi fechado - ou seja, não consegui sair da página da web.
precisa saber é o seguinte
34

Acabei de encontrar este mesmo problema

npm install jquery --save

<script>window.$ = window.jQuery = require('jquery');</script>

trabalhou para mim

Dhaval Chauhan
fonte
É exatamente isso que minha resposta original diz.
Bruno Vaz
Olá, como fazer o mesmo com materialize.min.js cdnjs.cloudflare.com/ajax/libs/materialize/0.98.2/js/… . .. algo como isto <script> window.Materialize = window.Materialize = require ('Materialize'); </script> ??? alguém pode me ajudar
Makjb lh
@BrunoVaz esta resposta é mais limpo :)
moeiscool
20

Você pode colocar node-integration: falseopções internas no BrowserWindow.

por exemplo: window = new BrowserWindow({'node-integration': false});

Murilo Feres
fonte
4
Essa é uma boa solução para usuários que não precisam de integração de nós.
Adam Szmyd
Isso é incrível, funciona perfeitamente para mim. Obrigado @Murilo Feres. De que maneira as opções de integração de nós fazem?
Ahesanali Suthar
3
não trabalho @ 1.4, por favor, use: Vamos ganhar = new BrowserWindow ({WebPreferences: {nodeIntegration: false}})
holly
14

Uma solução agradável e limpa

  1. Instale o jQuery usando o npm. ( npm install jquery --save)
  2. Use-o: <script> let $ = require("jquery") </script>
adgelbfish
fonte
8

Eu enfrento o mesmo problema e isso funcionou para mim!

Instale o jQuery usando o npm

$ npm install jquery

Em seguida, inclua o jQuery de uma das seguintes maneiras.

Usando tag de script

<script>window.$ = window.jQuery = require('jquery');</script>

Usando Babel

import $ from 'jquery';

Usando o Webpack

const $ = require('jquery');
Abraham Hernandez
fonte
5

Eu acho que entendi sua luta, resolvi um pouco diferente. Usei o script loader para o meu arquivo js, ​​que está incluindo o jquery.Script loader pega o seu arquivo js e o anexa ao topo do seu arquivo vendor.js, ele fez a mágica para mim.

https://www.npmjs.com/package/script-loader

Depois de instalar o carregador de scripts, adicione-o ao arquivo de inicialização ou aplicativo.

import 'script! path / your-file.js';

Mertcan Diken
fonte
4

ok, aqui está outra opção, se você quiser um parente incluir ...

<script> window.$ = window.jQuery = require('./assets/scripts/jquery-3.2.1.min.js') </script>
aestrro
fonte
3

Se você estiver usando Angular2, poderá criar um novo arquivo js com este código:

// jquery-electron.js

if ((!window.jQuery || !window.$) && (!!module && !!module.exports)) {
      window.jQuery = window.$ = module.exports;
}

e coloque-o logo após o caminho do jquery, em .angular-cli.json:

"scripts": [
    "../node_modules/jquery/dist/jquery.js",
    "assets/js/jquery-electron.js",
    ...
    ...
]
Máx.
fonte
3

im construção e Angular App com elétron, minha solução foi a seguinte:

index.html

<script>
    if ( typeof module === "object" && typeof module.exports === "object" ) {
      window.$ = window.jQuery = require('jquery');
    }
</script>

angular.json

"scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/popper.js/dist/umd/popper.min.js",
              "node_modules/bootstrap/dist/js/bootstrap.min.js"
            ]

Portanto, o Jquery é carregado a partir do angular.json se estiver no navegador, caso contrário, se for um aplicativo construído por elétrons, será necessário um módulo.

Se você deseja importar o jquery em index.html, em vez de importar do angular.json, use a seguinte solução:

<script src="path/to/jquery"></script>
<script>
    if ( typeof module === "object" && typeof module.exports === "object" ) {
      window.$ = window.jQuery = require('jquery');
    }
</script>
Kuza Grave
fonte
2

trabalhou para mim usando o seguinte código

var $ = require('jquery')
Adeojo Emmanuel IMM
fonte
2

1. Instale o jQuery usando o npm.

npm install jquery --save

2)

<!--firstly try to load jquery as browser-->
<script src="./jquery-3.3.1.min.js"></script>
<!--if first not work. load using require()-->
<script>
  if (typeof jQuery == "undefined"){window.$ = window.jQuery = require('jquery');}
</script>
Alexey Kolotsey
fonte
2

Isso funciona para mim.

<script languange="JavaScript">
     if (typeof module === 'object') {window.module = module; module = undefined;}
</script>

Coisas a considerar:

1) Coloque isso na seção logo antes </head>

2) Inclua Jquery.min.js ou Jquery.js antes da </body>tag

Vishal Goyal
fonte
0

você pode tentar o seguinte código:

mainWindow = new BrowserWindow({
        webPreferences: {
            nodeIntegration:false,
        }
});
shuoGG
fonte
0

Para esse problema, use JQuery e outros js iguais aos usados ​​na página da Web. No entanto, o Electron possui integração de nós, portanto, não encontrará seus objetos js. Você deve definir module = undefinedaté que seus objetos js sejam carregados corretamente. Veja o exemplo abaixo

<!-- Insert this line above local script tags  -->
<script>if (typeof module === 'object') {window.module = module; module = 
undefined;}</script>

<!-- normal script imports etc  -->
<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>    

<!-- Insert this line after script tags -->
<script>if (window.module) module = window.module;</script>

Depois de importar como indicado, você poderá usar o JQuerye outras coisas em elétrons.

Kiran Maniya
fonte
0

Basta instalar o Jquery com o seguinte comando.

npm install --save jquery

Depois disso, por favor, coloque uma nova linha no arquivo js que você deseja usar o Jquery

let $ = require('jquery')
Milan Hirpara
fonte