Electrón: jQuery no está definido

315

Problema: mientras desarrolla usando Electron, cuando intenta usar cualquier complemento JS que requiera jQuery, el complemento no encuentra jQuery, incluso si carga en la ruta correcta usando etiquetas de script.

Por ejemplo,

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

Ejecutar este código anterior no funcionaría. De hecho, abra DevTools, vaya a la vista Consola y haga clic en el <p>elemento. Deberías ver eso function $ is not definedo algo por el estilo.

Bruno Vaz
fuente
¿Por qué no solo usar la requirefunción Electron ?

Respuestas:

762

Una solución mejor y más 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>

Beneficios

  • Funciona tanto para el navegador como para el electrón con el mismo código.
  • Soluciona problemas para TODAS las bibliotecas de terceros (no solo jQuery) sin tener que especificar cada una
  • Script Build / Pack Friendly (es decir, Grunt / Gulp todos los scripts en vendor.js)
  • NO requiere node-integrationser falso

fuente aquí

Dale Harders
fuente
1
@fareednamrouti Sí, pero el objetivo de esta solución es que no tiene que enumerar las bibliotecas de terceros (¡simplemente funciona!). Práctico cuando está importando muchas bibliotecas (o scripts auto empaquetados)
Dale Harders
2
¡Gracias! en mi caso, esta solución también funciona para versiones anteriores de d3 como d3 v3 o inferior
vientos en contra el
2
@DaleHarders Resulta que window.modulecomienza con el mismo valor que module, por lo que su código no funciona como se esperaba. La forma correcta de hacerlo es guardar moduleen alguna otra propiedad de ventana (no utilizada), como window.tempModule. Para confirmar lo que digo, intente console.log(module)después de su última declaración para verificar eso ahora module === undefined.
Lucio Paiva
1
@Lucio Nope. Necesitamos guardar en window.module ya que aquí es donde lo esperan las bibliotecas de terceros (entorno del navegador). Creo que estás confundiendo Node.js y los entornos del navegador. Este truco es ayudar en el desarrollo para que su código pueda ejecutarse en el navegador Y nodo / electrón sin ninguna configuración adicional. Hay muchas otras formas de hacerlo, pero esta es la más simple en mi humilde opinión.
Dale Harders
1
Esto es problemático con CSP-no scripts en línea
Trevor
121

Como se ve en https://github.com/atom/electron/issues/254, el problema se debe a este código:

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

El código jQuery "ve" que se está ejecutando en un entorno CommonJS e ignora window.

La solución es realmente fácil , en lugar de cargar jQuery <script src="...">, debe cargar así:

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

Nota: el punto antes de la ruta es obligatorio , ya que indica que es el directorio actual. Además, recuerde cargar jQuery antes de cargar cualquier otro complemento que dependa de él .

Bruno Vaz
fuente
1
Gracias, pero tengo un sistema creado por yeoman con angular. Grunt toma todas mis dependencias de Bower y las construye en un archivo vendor.js. ¿Cómo puedo cargar jquery, arreglarlo con su línea y continuar con las otras dependencias de bower que necesitan jquery?
bluesky777
No entiendo, el vendor.js tiene jquery adentro? Si es así, puede cargar el vendor.js con esta ventana. $ Método, afaik.
Bruno Vaz
Algunos comentarios más adelante en el tema vinculado hay una solución aún mejor: 'node-integration': falsecomo opción para BrowserWindow.
Boldewyn
66
¿No afecta esto a otras cosas?
Bruno Vaz
53

Otra forma de escribir <script>window.$ = window.jQuery = require('./path/to/jquery');</script>es:

<script src="./path/to/jquery" onload="window.$ = window.jQuery = module.exports;"></script>
Aaleks
fuente
¡Encontré esto como la mejor respuesta porque todavía puedo usar CDN con él! Y no es necesario sobrescribir nada.
patotoma 01 de
53

Preguntas frecuentes sobre electron:

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

No puedo usar jQuery / RequireJS / Meteor / AngularJS en Electron.

Debido a la integración de Node.js de Electron, hay algunos símbolos adicionales insertados en el módulo similar al DOM, se requieren exportaciones. Esto causa problemas a algunas bibliotecas ya que desean insertar los símbolos con los mismos nombres.

Para resolver esto, puede desactivar la integración de nodos en Electron:

// En el proceso principal.

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

Pero si desea mantener las capacidades de uso de Node.js y Electron API, debe cambiar el nombre de los símbolos en la página antes de incluir otras 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
fuente
@ Fran6 ¿qué puedo hacer si estoy cargando una página externa? :(
georgiosd
Esto funcionó, pero después de hacer esto, mi aplicación Electron no se cerró, es decir, no pude salir de la página web.
tale852150
34

Acabo de encontrar este mismo problema

npm install jquery --save

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

trabajó para mi

Dhaval Chauhan
fuente
Esto es exactamente lo que dice mi respuesta original.
Bruno Vaz
Hola, cómo hacer lo mismo con materialize.min.js cdnjs.cloudflare.com/ajax/libs/materialize/0.98.2/js/… . .. algo como esto <script> window.Materialize = window.Materialize = require ('Materialize'); </script> ??? alguien puede ayudar
Makjb lh
@BrunoVaz esta respuesta es más limpia :)
moeiscool
20

Puede poner node-integration: falseopciones internas en BrowserWindow.

p.ej: window = new BrowserWindow({'node-integration': false});

Murilo Feres
fuente
44
Esta es una buena solución para usuarios que no necesitan integración de nodos.
Adam Szmyd
Esto es increíble, funciona perfectamente para mí. Gracias @Murilo Feres. ¿De qué manera lo hacen las opciones de integración de nodos?
Ahesanali Suthar
3
no funciona @ 1.4, utilice: let win = new BrowserWindow ({webPreferences: {nodeIntegration: false}})
holly
14

Una solución agradable y limpia.

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

¡Me enfrento al mismo problema y esto funcionó para mí!

Instale jQuery usando npm

$ npm install jquery

Luego incluya jQuery de una de las siguientes maneras.

Usando la etiqueta de script

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

Usando Babel

import $ from 'jquery';

Usando Webpack

const $ = require('jquery');
Abraham Hernández
fuente
5

Creo que entiendo su lucha, lo resolví un poco diferente. Utilicé el cargador de scripts para mi archivo js, ​​que incluye jquery. El cargador de scripts toma su archivo js y lo adjunta a la parte superior de su archivo vendor.js.

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

después de instalar el cargador de secuencias de comandos, agréguelo a su archivo de inicio o aplicación.

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

Mertcan Diken
fuente
4

ok, aquí hay otra opción, si quieres que un pariente incluya ...

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

Si está utilizando Angular2, puede crear un nuevo archivo js con este código:

// jquery-electron.js

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

y colóquelo justo después de jquery path, en .angular-cli.json:

"scripts": [
    "../node_modules/jquery/dist/jquery.js",
    "assets/js/jquery-electron.js",
    ...
    ...
]
Max
fuente
3

Im building y Angular App con electron, mi solución fue la siguiente:

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"
            ]

Entonces, Jquery se carga desde angular.json si está en el navegador, de lo contrario, si se trata de una aplicación construida con electrones, necesitará un módulo.

Si desea importar jquery en index.html en lugar de importar desde angular.json, use la siguiente solución:

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

funcionó para mí usando el siguiente código

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

1.Instale jQuery usando 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
fuente
2

Esto funciona para mi.

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

Cosas para considerar:

1) Ponga esto en la sección justo antes </head>

2) Incluya Jquery.min.js o Jquery.js justo antes de la </body>etiqueta

Vishal Goyal
fuente
0

puedes probar el siguiente código:

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

Para este problema, use JQuery y otros js igual que está usando en la página web. Sin embargo, Electron tiene integración de nodos, por lo que no encontrará sus objetos js. Tienes que configurar module = undefinedhasta que tus objetos js se carguen correctamente. Ver ejemplo a continuación

<!-- 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>

Después de importar como se indica, podrá utilizar el JQueryy otras cosas en electrón.

Kiran Maniya
fuente
0

Simplemente instale Jquery con el siguiente comando.

npm install --save jquery

Después de eso, coloque la línea de belew en el archivo js que desea usar Jquery

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