Electron: jQuery no está configurado globalmente porque "módulo" está definido

Creado en 6 may. 2014  ·  71Comentarios  ·  Fuente: electron/electron

jQuery contiene algo como esto:

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

El módulo está definido, incluso en los scripts del lado del navegador. Esto hace que jQuery ignore el objeto window y use module , por lo que los otros scripts no encontrarán $ ni jQuery en el alcance global.

No estoy seguro de si se trata de un error de jQuery o atom-shell, pero quería poner esto en la web para que otros no busquen tanto tiempo como yo.

Comentario más útil

Simplemente desarme module .

Quería que mi página web funcionara tanto en el navegador como en electron.
Como se explica en este hilo, electron expone un module global cuando nodeIntegration: true , que jQuery ve y reacciona en consecuencia:

if ( typeof module === "object" && typeof module.exports === "object" ) {
    // bind to module
} else {
    // bind to window
}

Pude hacer que jQuery se vincule al objeto window y use nodeIntegration: true haciendo lo siguiente en mi archivo html:

<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="//code.highcharts.com/highcharts.js"></script>
<script>if (window.module) module = window.module;</script>

Espero que esto ayude a alguien.

Todos 71 comentarios

Esto no es realmente un error para ninguno de los sistemas, tiene el mismo problema cuando usa browserify. jQuery ve que se está ejecutando en un entorno CommonJS y espera ser utilizado como tal.

Sin embargo, la solución es relativamente sencilla. En lugar de cargar jQuery como una etiqueta de script, cárguelo a través de require:

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

Estoy de acuerdo con @ChiperSoft , este es el comportamiento esperado en el entorno CommonJS, así que lo marqué como wontfix . Y gracias por compartir tu hallazgo.

@ChiperSoft , ¿Dónde debería colocar el archivo jquery.js para que funcione require('jquery') ? Intenté ponerlo al mismo nivel que package.js y main.js pero el tiempo de ejecución no parece recogerlo.

Puede usar require('jquery.js') tenga en cuenta el .js al final, para cargar jquery en relación con su archivo HTML.

Lo siento, usé window.$ = window.jQuery = require('/path/to/jquery'); como se mencionó pero no funciona,
Uncaught Error: Cannot find module 'scripts/jquery-1.10.2.min.js' module.js:339

¡Lo uso todo el tiempo y funciona muy bien! Esto es lo que uso, tenga en cuenta el camino:

window.$ = window.jQuery = require('./scripts/jquery-2.1.1.min.js');

@frankhale oh, funcionó con ./ , ¡gracias!

¡Impresionante! La cosa del camino también me hizo tropezar.

Si su aplicación no necesita integración de nodos, agregue "node-integration": false a sus opciones de BrowserWindow. En este caso module.exports no está disponible, jQuery funciona como se esperaba.

@kabalage funcionó de maravilla, ¡gracias!

: +1:

Caminé hasta el mismo problema. Instale jQuery a través de NPM, luego lo requirió y funcionó.

¿Qué pasa si se necesita la integración de nodos y jquery sin el requisito?

Estoy tratando de darle sentido a esto, ya que parece ser algo que podría usar. Sin embargo, me pregunto cuándo puede estar seguro de que puede usar $. ¿Registrar $ justo después de esta línea resultará en require y no jquery ya que require es asincrónico?

ventana. $ = ventana.jQuery = require ('/ ruta / a / jquery');
console.log ($) // los registros 'requieren' no 'jQuery'

@dieroux intente instalarlo a través de npm:

npm install jquery

Esto funcionó para mí mientras intentaba lo mismo. Entonces no necesitas dar una ruta, solo di:

window.$ = window.jQuery = require('jquery');
console.log( [$, jQuery ]);

¿Qué pasa si necesitamos integración de nodos y no podemos usar require ('algo')?
Actualmente funciona haciendo "eliminar módulo"; antes de cargar cosas problemáticas.
¿Cuál es el impacto de hacer esto?

Tengo problemas similares en los que jquery se puede cargar correctamente la primera vez que lo necesito en un script de precarga en una vista web. Sin embargo, la segunda vez que se hace referencia a jquery desde una página externa, la línea para asignarlo a través de:

  try {
        module.exports = null;
        if (typeof require === 'function') {
          alert('window: ' + window);
          alert('jquery: ' + window.jQuery);
          alert('export: ' + module.exports);
          if ( !window.jQuery ) {
            alert('before load');
            window.jQuery = require('./node_modules/jquery/dist/jquery.js');
            alert('after load');
            window.$ = window.jQuery;
            alert('after assignment');
         }
          alert('jquery: ' + window.jQuery);
        }
    } catch(e) {
        alert('failed load.');
        console.log(e);
    }

arroja un No se puede leer la propiedad createElement de undefined en la consola en la asignación a window.jQuery de require, lo que hace que jQuery no se cargue.

El mensaje de error en la consola es:
La página de invitado registró un mensaje: TypeError: No se puede leer la propiedad 'createElement' de la línea indefinida: 40

¿Alguna idea adicional sobre cómo cargar jquery con éxito en las páginas siguientes?

Gracias.

Esto fue lo primero con lo que me tropecé cuando ejecuté el inicio rápido de electrones e intenté ajustar una aplicación local; algo que funciona en Chrome de repente no funciona en las elecciones. Tener el error enterrado en las cargas fallidas del módulo angular no ayuda, por supuesto, así que asumí que había un problema con el orden de carga del script, que es como encontré este hilo. Quizás las palabras clave ayuden a otros.

La solución de @kabalage anterior funcionó perfectamente.

Hola a todos, solo quiero agregar algo de información con este problema, si pego el código de la biblioteca jquery en la consola electrónica $ y jQuery se agrega como una función en el objeto de la ventana. pude ejecutar jquery.

Se hace referencia a jQuery con etiqueta de script, mismo error. Tiene que "integración de nodos": falso en BrowserWindow ()

Hola chicos ... No estoy seguro de por qué este problema está cerrado, definitivamente todavía hay un problema aquí, déjenme explicarles. Si instalo jQuery localmente a través de NPM y cargo un archivo html local, entonces uso:

mainWindow. $ = require ('jQuery');
mainWindow.jQuery = require ('jQuery');

entonces funciona como se esperaba. Sin embargo, si hago mainWindow.loadUrl ('http://external.site.com ");

Recibo los errores mencionados donde $ y jQuery no están definidos. Desactivar la integración de nodos realmente no es una respuesta aceptable; es la razón por la que estoy usando Electron en primer lugar, lo necesito.

Me gustaría entrar en la fuente y solucionar el problema yo mismo, pero pensé que vería si alguien tenía información adicional sobre esto para indicarme la dirección correcta antes de ir allí. ¿Alguien ha podido hacer que esto funcione _con_ integración de nodo, contra sitios externos?

Gracias ... y gran trabajo por cierto. Todo lo nuevo y hermoso, así, comenzará con algunas arrugas.

Saludos cordiales

/ W

Lo hice funcionar con la integración de nodos.

  1. Instálelo con npm, por lo que está definido en package.json
  2. Utilice require con el nombre del módulo <script>window.$ = window.jQuery = require('jquery');</script>
  3. No use la ruta en el parámetro requerido.
  4. No instale la glorieta del canal, le hará utilizar la ruta en el parámetro requerido.
  5. Si usa bootstrap, primero debe cargar jQuery.

Todo lo anterior respaldado solo por mi experiencia.

Trabajará

    <script>window.$ = window.jQuery = require('jquery');</script>
    <script src="path_to/bootstrap.js"></script>

No

    <script>window.$ = window.jQuery = require('./path/to/jquery.js');</script>
    // or
    <script src="path_to/jquery.js"></script>
    <script src="path_to/bootstrap.js"></script>

Hola dilmdeep, gracias por la rápida respuesta. ¿Su solución depende de tener control sobre el sitio externo? Estoy intentando cargar un sitio al que no tengo acceso a la fuente. Sin embargo, lo que dijiste sobre packages.json es interesante. Instalé jQuery a través de npm (y usé la reconstrucción documentada para electron) y, como dije, puedo usar jQuery con un archivo HTML local, pero jQuery no está definido en mi package.json ..... Ah, y probé con la desactivación de la integración de nodos y, aunque funciona, no es lo que necesito. Gracias.

Solo quería actualizar esto en caso de que alguien más se meta en el mismo problema. La forma en que solucioné esto (después de descargar 10 GB de fuente de Electron) estaba en realidad en la documentación para empezar. En lugar de llamar a la URL del sitio externo, cargué un archivo HTML local y usé una vista web de ese archivo html para cargar el sitio externo. Se carga perfectamente con la integración de nodos habilitada. Solo mire en los documentos para Webview, es bastante sencillo. También mi agradecimiento a Paul en la sala de chat por ayudarme a comenzar con la fuente. Si alguien se pregunta, usan Atom (por supuesto) para codificar Electron, WinDbg en Windows para depurar y Ninja para compilar. Para su información, compilar las fuentes fue muy fácil y sorprendentemente rápido, primero compiló usando sus scripts y la documentación proporcionada. Una vez más, ¡buen trabajo, chicos!

@WolfieWerewolf ¡Bravo! Tengo que decir que el ejemplo es un poco engañoso si se considera la seguridad.

@ Shufeng01 Saludos amigo, vengo con este frío de .Net land, así que me siento como un completo n00b. Tiene razón en que la seguridad era un problema, sin embargo, el uso de la bandera disablewebsecurity en la vista web resolvió la mayor parte. Creo que la seguridad, en general, es el mayor desafío para llevar la web al escritorio ... pero vale la pena el esfuerzo. Rocas de electrones.

@diimdeep gracias, tu solución funciona para mí (¡no es lo que quiere @WolfieWerewolf !)

Esto es un pequeño problema para nosotros. Empaquetamos jquery con nuestra aplicación js, y este JS concatenado se usa en la compilación para las versiones web y de escritorio (hemos estado usando NWJS). La instalación de NPM puede ser una opción para nosotros, pero no es ideal en nuestra situación por un par de razones.

¿No existe una forma teórica de hacer que funcione utilizando etiquetas de secuencia de comandos?

@bgSosh , ¿por qué no deshabilitar la integración de nodos (lea sobre la clave node-integration aquí )? Si lo hace, las etiquetas de secuencia de comandos deberían funcionar correctamente. Si necesita algunas cosas relacionadas con el nodo, puede hacerlo en un script preload (siempre tienen integración de nodo).

@etiktin , ¿puede explicar cómo hacer esto en la precarga? Soy nuevo en electron y no he logrado ejecutar un script de precarga (al menos parece no ejecutarse, console.log no funciona, cambiando window.myExposedIPC = require ('ipc') por ejemplo, no está disponible más adelante, etc.

Lo tengo funcionando en caso de que alguien tenga el mismo problema: https://github.com/atom/electron/issues/1753#issuecomment -157409572

@matthiasg me alegro de que lo hayas hecho funcionar. Agregué algunos comentarios a tu ejemplo.

Cuando la integración de nodos está deshabilitada y desea hacer algunas cosas de nodos en su script de precarga, es importante tener una referencia a cualquier nodo global que necesite. Debe hacer esto, porque en la siguiente marca las referencias globales se eliminan (así es como se implementa la desactivación de la integración de nodos), por lo que si no tenía una referencia y luego intenta requerir algo en una llamada de función o un temporizador , fallaría.

@etiktin gracias. Por supuesto, eso era parte de eso, pero lo que me faltaba es la documentación de process.once('loaded', ... ) una vez que estaba en su lugar, puedo exponer las apis que quería.

Hola tios,

Como nada de lo anterior funcionó para mí (usando w2ui y JQuery tanto con electron como con una página HTML independiente, dejemos que w2ui use también jQuery), sentí la necesidad de publicar mi solución de trabajo aquí:

<html>
<head>
    <title>MyApp</title>
    <link rel="stylesheet" type="text/css" href="./lib/w2ui-1.4.3.css"/>
    <script type="text/javascript" src="./lib/require.js"></script>
    <script type="text/javascript" src="./lib/jquery-2.1.4.js" onload="$ = jQuery = module.exports;"></script>
    <script type="text/javascript" src="./lib/w2ui-1.4.3.js"></script>
</head>
<body>
<script type="text/javascript">
    // use global $ and w2ui here... 
    ...

Soy un novato en JS y estoy realizando un estudio de tecnología y ahora estoy un poco preocupado por este oscuro módulo de carga. Puede ser una pregunta tonta, pero ¿por qué electron carga los módulos JS de manera tan diferente a los navegadores habituales al cargar una página HTML?

@forman , ¿deshabilitó la integración de nodos y usó un script de precarga para la interacción de nodos? Vea los comentarios anteriores por mí y @matthiasg. Si lo hace, jquery y el resto funcionarán exactamente como lo hacen en el navegador.

Trabajará

requirejs(['require', '../require.config'], function (requirejs, config) {
        //fixed jQuery isn't set globally
        requirejs(['jquery'],function(jquery){
            window.$ = window.jQuery =jquery;
        });
        // update global require config
        window.requirejs.config(config);
        // load app
        requirejs(['main'],function(main){
        });
    });

@forman ¡¡ Gracias !! Ninguno de los anteriores funcionó a excepción de su solución. (usando 0.35.5 preconstruido con electrones)
@etiktin Esto funcionó para mí sin tener que cambiar nada en el lado mainProcess

Pensé que debería agregar nuestro problema y solución a este hilo para referencia futura.

Estamos cargando una URL externa en una vista web y necesitamos ejecutar nuestro propio Javascript que puede usar electron / Node. Habilitar la integración de nodos en la vista web no es una opción, ya que esto romperá jQuery que está siendo utilizado por la URL externa.

Lo que terminamos haciendo fue agregar un script de precarga a la vista web donde colocamos los módulos que necesitamos en el alcance global. Esto los hace accesibles más adelante cuando ejecutemos nuestro Javascript.

preload.js:

global.ipcRenderer = require('electron').ipcRenderer;

Y luego podemos acceder al ipcRenderer como:

webview.executeJavaScript("ipcRenderer.sendToHost('hello');");

Uncaught Error: Cannot find module 'jquery' y nada ayuda de este hilo = /

Simplemente desarme module .

Quería que mi página web funcionara tanto en el navegador como en electron.
Como se explica en este hilo, electron expone un module global cuando nodeIntegration: true , que jQuery ve y reacciona en consecuencia:

if ( typeof module === "object" && typeof module.exports === "object" ) {
    // bind to module
} else {
    // bind to window
}

Pude hacer que jQuery se vincule al objeto window y use nodeIntegration: true haciendo lo siguiente en mi archivo html:

<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="//code.highcharts.com/highcharts.js"></script>
<script>if (window.module) module = window.module;</script>

Espero que esto ayude a alguien.

@tomkel aquí hay otra solución:

<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script>window.jQuery = window.$ = module.exports;</script>

En mi caso, necesito poder iniciar mi aplicación como sitio web y como aplicación Electron. Aquí está mi solución:

<!-- Launched with Electron -->
<script>
    if ('require' in window) {
        window.$ = window.jQuery = require('jquery');
    }
</script>

<!-- From CDN, Bower, etc... -->
<script src="https://code.jquery.com/jquery-2.2.0.js"></script>

<!-- Others libraries depending on jQuery -->
<script src="..."></script>

@dkfiresky Sí, eso parece funcionar también. Sin embargo, estoy usando Highcharts junto con jQuery. Highcharts hace algo similar, ubicándose en module si existe. Por alguna razón no pude conseguir

<script>window.Highcharts = module.exports;</script>

trabajar. Actualicé mi comentario anterior para reflejar eso.

@tomkel, su solución con la ocultación temporal de module funciona muy bien para mí. Mi problema fue durante la migración de nw.js con ngDialog suponiendo que está en el entorno CommonJS fallando en require('angular') y registrarse como módulo angular.

En Electron 0.36.7 encuentro que no puedo hacer un window.$ = require('jquery'); simple ya que no podría encontrar el módulo. El renderizador no parece tener la misma ruta de resolución del módulo que el proceso principal

En realidad, eso no funciona porque jQuery se estaría ejecutando en el proceso principal que no tiene document . Y require('jquery') no funcionó para mí porque estoy sirviendo la página a través de HTTP como # 4243. Para solucionar esto, he intentado agregar rutas de módulo desde el proceso principal al proceso del renderizador de la siguiente manera:

require('electron').remote.process.mainModule.paths.forEach(function(path) {
    require('module').globalPaths.push(path);
});

Después de eso, puedo hacer require('jquery') sin problemas. Sin embargo, no estoy seguro de qué otro impacto puede tener esto

Y require ('jquery') no funcionó para mí porque estoy sirviendo la página a través de HTTP como # 4243.

Si permite que el contenido remoto acceda a node.js, su aplicación es muy, muy insegura, debe deshabilitar la integración de nodos cuando ejecuta contenido remoto y usar un script de precarga

¿Incluso si el "contenido remoto" es localhost? Estoy usando el nodo para construir y servirme la página en lugar de leer desde un archivo local, eso es todo

Ampliando @dkfiresky , es posible que obtenga un Uncaught ReferenceError: module is not defined en la versión del navegador.

Si es así, intente esto:

<script src="./bower_components/jquery/dist/jquery.min.js"></script>
<script>window.jQuery = window.$ = typeof module === 'object' ? module.exports : jQuery</script> 

@dspint module no estará definido solo en caso de que la integración de nodos esté deshabilitada, por lo que probablemente debería usar mi ejemplo solo con la integración de nodos habilitada.

Si está utilizando window.open , puede pasar nodeIntegration=0 con sus opciones de ventana.

window.open('https://your.cool/url', 'title', 'nodeIntegration=0');

Estoy haciendo:

<script>
  var saveModule = module;
  delete module;
</script>
  <script src="jquery.js"></script>
  <script src="jquery-ui.js"></script>
<script>
  module = saveModule;
</script>

Tuve el mismo problema que @gnail. Tenía un servidor de nodos ejecutando un proyecto angular. Su código me lo arregló.

require('electron').remote.process.mainModule.paths.forEach(function(path) {
  require('module').globalPaths.push(path);
});

Me está funcionando 😄

<script>
    window['old_module'] = window['module'];
    delete window.module;
</script>

<script src="any_lib_like_jquery.js" />

<script>
    window['module'] = window['old_module'];
    delete window.old_module;
</script>

Tengo este problema, ya probé todo este hilo. pero nada funciona, estoy atrapado al principio
de todo.
estoy usando el representante de iniciador de electrones

@PauloGaldo básicamente cualquier solución en este hilo debería estar funcionando. Publique el extracto relevante de su código y todos los mensajes de error que encuentre.

@ChiperSoft ¿Puede decirme dónde debo usar su código?

@tomkel ¡ Muy bonito!
¡Finalmente conseguí que la Masonería funcionara dentro de Electron!

Por alguna razón, todavía no puedo hacer que jQuery funcione tanto en el navegador como en la aplicación Electron.
Mi aplicación web funciona bien en el navegador, mientras que cuando intento cargar la misma URL a través de la aplicación electron, arroja:

image

Webapp - https://github.com/zulip/zulip
Aplicación de electrones: https://github.com/zulip/zulip-electron

La aplicación web está utilizando la versión jquery 1.12.1 a través de npm.
No puedo usar la integración de nodos porque la necesito en mi proceso de renderizado.
Estoy teniendo dificultades para resolver esto. ¿Alguien sabe cómo hacerlo funcionar?
cc @aaaaahaaaaa @maykefreitas @paulcbetts @tomkel @dkfiresky

@englishextra sin suerte. Intenté incluir su código en preload.js de mi aplicación, pero

@englishextra No, no necesito jquery en mi aplicación. Vea el código de actualización aquí . No puedo incluir su código en la lógica de mi aplicación ya que lo estoy usando solo para cargar la URL especificada, vea esto .

Resolví este problema con esto

<script type="text/javascript" src="js/jquery.min.js" onload="window.$ = window.jQuery;"></script>

y establecer

webPreferences: {
            nodeIntegration: false, 
        }

si con nodeIntegration: true, imorot jQuery así

<script type="text/javascript" src="js/jquery.min.js" onload="window.$ = window.jQuery = module.exports;"></script>

referencia a
https://github.com/electron/electron/issues/345

Quiero decir, parece ser un problema grave, entonces, ¿por qué no incluirlo en Electron real? ¿Quizás integrar las principales bibliotecas de JavaScript en Electron?

Lo más probable es que, si está utilizando jQuery en una aplicación de Electron, esté haciendo algo muy mal o al menos ineficiente.

<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script>if (typeof module === 'object') {window.jQuery = window.$ = module.exports;};</script>

@drowlands Incluir librerías de
@amhoho Eso es porque necesita require jQuery, o modificar su código de inicio en la función superior, dejando solo factory( global );

Aquí:

( function( global, factory ) {

    "use strict";

    if ( typeof module === "object" && typeof module.exports === "object" ) {

        // For CommonJS and CommonJS-like environments where a proper `window`
        // is present, execute the factory and get jQuery.
        // For environments that do not have a `window` with a `document`
        // (such as Node.js), expose a factory as module.exports.
        // This accentuates the need for the creation of a real `window`.
        // e.g. var jQuery = require("jquery")(window);
        // See ticket #14549 for more info.
        module.exports = global.document ?
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }

En mi caso, cargo bibliotecas a través de fetch / Promise o xhr, por lo que tengo esta rutina para eliminar las verificaciones de módulos en las bibliotecas de los proveedores.
@RRorg raro lo que estás diciendo

Marcos

@kabalage Creo que la configuración en su publicación anterior está desactualizada. Parece que debería ser así ahora:

const window = new BrowserWindow({
  webPreferences: {
    nodeIntegration: false, 
  },
});

En documentos oficiales:
https://electronjs.org/docs/faq#i -can-not-use-jqueryrequirejsmeteorangularjs-in-electron
''