Электрон: jQuery не определен

315

Проблема: при разработке с использованием Electron, когда вы пытаетесь использовать любой плагин JS, требующий jQuery, плагин не находит jQuery, даже если вы загружаете по правильному пути с помощью тегов скрипта.

Например,

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

Выполнение этого кода выше не будет работать. На самом деле, откройте DevTools, перейдите в представление консоли и нажмите на <p>элемент. Вы должны увидеть это function $ is not definedили что-то на этот счет.

Бруно Ваз
источник
Почему бы просто не использовать requireфункцию Electron ?

Ответы:

762

Лучшее и более общее решение 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>

Преимущества

  • Работает как для браузера, так и для электронного с тем же кодом
  • Исправляет проблемы для ВСЕХ сторонних библиотек (не только jQuery) без необходимости указывать каждую
  • Script Build / Pack Friendly (т.е. Grunt / Gulp все скрипты в vendor.js)
  • НЕ требует node-integrationбыть ложным

источник здесь

Дейл Хардерс
источник
1
@fareednamrouti Да, но смысл этого решения состоял в том, что вам не нужно перечислять сторонние библиотеки (это просто работает!). Удобно, когда вы импортируете много библиотек (или самодостаточных скриптов)
Дейл Хардерс
2
Спасибо! в моем случае это решение также работает для более старых версий d3, таких как d3 v3 или ниже
встречный ветер
2
@DaleHarders Оказывается, window.moduleначинается с того же значения module, что и ваш код не работает так, как ожидалось. Правильный способ сделать это - сохранить moduleв какое-то другое (неиспользуемое) свойство окна, например window.tempModule. Чтобы подтвердить то, что я говорю, попробуйте console.log(module)после вашего последнего утверждения проверить это сейчас module === undefined.
Лучио Пайва
1
@Lucio Нет. Нам нужно сохранить в window.module, поскольку именно там его ожидают сторонние библиотеки (среда браузера). Я думаю, что вы путаете Node.js и среду браузера. Этот трюк должен помочь в разработке, чтобы ваш код мог работать в браузере И узле / электроне без какой-либо дополнительной настройки. Есть много других способов сделать это, но это самое простое ИМХО.
Дейл Хардерс
1
Это проблематично с CSP - без встроенных скриптов
Тревор
121

Как видно из https://github.com/atom/electron/issues/254, проблема вызвана этим кодом:

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

Код jQuery «видит», что работает в среде CommonJS, и игнорирует window.

Решение действительно простое , вместо загрузки через jQuery <script src="...">, вы должны загрузить так:

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

Примечание: точка перед путем обязательна , поскольку она указывает на то, что это текущий каталог. Также не забудьте загрузить jQuery перед загрузкой любого другого подключаемого модуля, который зависит от него .

Бруно Ваз
источник
1
Спасибо, но у меня есть система, созданная Yeoman с Angular. Grunt берет все мои зависимости и объединяет их в файл vendor.js. Как я могу загрузить jquery, исправить с вашей линией и продолжить с другими зависимостями bower, которые требуют jquery?
bluesky777
Я не понимаю, у vendor.js есть jquery внутри? Если это так, вы можете загрузить vendor.js с этим окном. $ Method, afaik.
Бруно Ваз
Некоторые комментарии позже в связанной проблеме есть даже лучшее решение: 'node-integration': falseкак вариант для BrowserWindow.
Болдевин
6
Разве это не влияет на другие вещи?
Бруно Ваз
53

Другой способ написания <script>window.$ = window.jQuery = require('./path/to/jquery');</script>:

<script src="./path/to/jquery" onload="window.$ = window.jQuery = module.exports;"></script>
Aaleks
источник
Я нашел это как лучший ответ, потому что я все еще могу использовать CDN с этим! И не нужно ничего перезаписывать.
Патотома
53

электронный FAQ ответ:

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

Я не могу использовать jQuery / RequireJS / Meteor / AngularJS в Electron.

Благодаря интеграции Electron с Node.js, в DOM-подобный модуль добавлены некоторые дополнительные символы, которые требуются для экспорта. Это создает проблемы для некоторых библиотек, так как они хотят вставить символы с одинаковыми именами.

Чтобы решить эту проблему, вы можете отключить интеграцию узлов в Electron:

// В основном процессе.

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

Но если вы хотите сохранить возможности использования Node.js и Electron API, вы должны переименовать символы на странице, прежде чем включать другие библиотеки:

<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
источник
@ Fran6 что мне делать, если я загружаю внешнюю страницу? :(
georgiosd
Это работало, но после этого мое приложение Electron не закрывалось, то есть я не мог выйти с веб-страницы.
tale852150
34

Просто наткнулся на эту же проблему

npm install jquery --save

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

работал на меня

Давал Чаухан
источник
Это именно то, что говорит мой оригинальный ответ.
Бруно Ваз
Привет, как сделать то же самое с materialize.min.js cdnjs.cloudflare.com/ajax/libs/materialize/0.98.2/js/… . .. что-то вроде этого <script> window.Materialize = window.Materialize = require ('Materialize'); </ script> ??? может кто-нибудь помочь
Makjb lh
@BrunoVaz этот ответ чище :)
moeiscool
20

Вы можете поместить node-integration: falseвнутренние параметры в BrowserWindow.

например: window = new BrowserWindow({'node-integration': false});

Мурило Ферес
источник
4
Это хорошее решение для пользователей, которым не нужна интеграция узлов.
Адам Шмид,
Это потрясающе, отлично работает для меня. Спасибо @Murilo Feres. Любые способы, которые делают варианты интеграции узла?
Ахесанали Сутар
3
не работает @ 1.4, используйте: let win = new BrowserWindow ({webPreferences: {nodeIntegration: false}})
holly
14

Хорошее и чистое решение

  1. Установите jQuery, используя npm. ( npm install jquery --save)
  2. Используй это: <script> let $ = require("jquery") </script>
adgelbfish
источник
8

Я столкнулся с той же проблемой, и это сработало для меня!

Установите jQuery с помощью npm

$ npm install jquery

Затем включите jQuery одним из следующих способов.

Использование тега script

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

Используя Вавилон

import $ from 'jquery';

Использование Webpack

const $ = require('jquery');
Авраам Эрнандес
источник
5

Я думаю, я понимаю вашу борьбу, я решил ее немного по-другому. Я использовал загрузчик сценариев для моего js-файла, который включает jquery. Загрузчик сценариев берет ваш js-файл и прикрепляет его к вершине вашего файла vendor.js, он сделал для меня чудо.

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

после установки загрузчика скриптов добавьте это в свой загрузочный файл или файл приложения.

импортировать 'script! path / your-file.js';

Мерткан Дикен
источник
4

хорошо, вот еще один вариант, если вы хотите, чтобы относительное включение ...

<script> window.$ = window.jQuery = require('./assets/scripts/jquery-3.2.1.min.js') </script>
aestrro
источник
3

Если вы используете Angular2, вы можете создать новый файл js с этим кодом:

// jquery-electron.js

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

и поместите его сразу после пути jquery, в .angular-cli.json:

"scripts": [
    "../node_modules/jquery/dist/jquery.js",
    "assets/js/jquery-electron.js",
    ...
    ...
]
Максимум
источник
3

Я строю и Angular App с электроном, мое решение было следующее:

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

Таким образом, Jquery загружается из angular.json, если в браузере, в противном случае, если это приложение, созданное с помощью электронов, для него потребуется модуль.

Если вы хотите импортировать jquery в index.html вместо импорта из angular.json, используйте следующее решение:

<script src="path/to/jquery"></script>
<script>
    if ( typeof module === "object" && typeof module.exports === "object" ) {
      window.$ = window.jQuery = require('jquery');
    }
</script>
Могила куза
источник
2

работал для меня, используя следующий код

var $ = require('jquery')
Адехо Эммануэль IMM
источник
2

1. Установите jQuery, используя 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>
Алексей Колоцей
источник
2

Это работает для меня.

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

Что нужно учитывать:

1) Поместите это в раздел прямо перед </head>

2) Включите Jquery.min.js или Jquery.js прямо перед </body>тегом

Вишал Гоял
источник
0

Вы можете попробовать следующий код:

mainWindow = new BrowserWindow({
        webPreferences: {
            nodeIntegration:false,
        }
});
shuoGG
источник
0

Для этой проблемы используйте JQuery и другие файлы js, которые вы используете на веб-странице. Однако у Electron есть интеграция узлов, поэтому он не найдет ваши объекты js. Вы должны установить, module = undefinedпока ваши объекты js не будут загружены правильно. См. Пример ниже

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

После импорта, как дано, вы сможете использовать JQueryи другие вещи в электронном виде.

Киран Мания
источник
0

Просто установите Jquery с помощью следующей команды.

npm install --save jquery

После этого, пожалуйста, поместите строку в файл js, который вы хотите использовать Jquery.

let $ = require('jquery')
Милан Хирпара
источник