Elektron: jQuery nie jest zdefiniowany

315

Problem: podczas programowania za pomocą Electron, gdy próbujesz użyć dowolnej wtyczki JS, która wymaga jQuery, wtyczka nie znajduje jQuery, nawet jeśli załadujesz właściwą ścieżkę za pomocą znaczników skryptu.

Na przykład,

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

Uruchomienie powyższego kodu nie zadziałałoby. W rzeczywistości otwórz DevTools, przejdź do widoku konsoli i kliknij <p>element. Powinieneś to zobaczyć function $ is not definedlub coś w tym celu.

Bruno Vaz
źródło
Dlaczego nie skorzystać z requirefunkcji elektronowej ?

Odpowiedzi:

759

Lepsze i bardziej ogólne rozwiązanie 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>

Korzyści

  • Działa zarówno z przeglądarką, jak i elektronem z tym samym kodem
  • Naprawiono problemy z WSZYSTKIMI bibliotekami innych firm (nie tylko jQuery) bez konieczności ich określania
  • Script Build / Pack Friendly (tj. Grunt / Gulp wszystkie skrypty do vendor.js)
  • NIE wymaga node-integrationfałszu

źródło tutaj

Dale Harders
źródło
1
@fareednamrouti Tak, ale chodziło o to, że nie musisz wymieniać bibliotek stron trzecich (to po prostu działa!). Przydaje się, gdy importujesz wiele bibliotek (lub skryptów w pakiecie)
Dale Harders
2
dzięki! w moim przypadku to rozwiązanie działa również w starszych wersjach d3, takich jak d3 v3 lub poniżej
wiatry
2
@DaleHarders Okazuje się, że window.modulezaczyna się od tej samej wartości co module, więc twój kod nie działa tak jak powinien. Właściwy sposób to zrobić module, zamiast tego zapisać w innej (nieużywanej) właściwości okna, takiej jak window.tempModule. Aby potwierdzić to, co mówię, spróbuj console.log(module)po ostatnim stwierdzeniu, aby to teraz zweryfikować module === undefined.
Lucio Paiva,
1
@Lucio Nope. Musimy zapisać w module window.module, ponieważ tam oczekują tego biblioteki innych producentów (środowisko przeglądarki). Myślę, że mylisz Node.js i środowiska przeglądarki. Ta sztuczka ma pomóc w rozwoju, aby Twój kod mógł działać w przeglądarce ORAZ węzeł / elektron bez dodatkowej konfiguracji. Istnieje wiele innych sposobów, ale jest to najprostszy IMHO.
Dale Harders,
1
Jest to problematyczne w przypadku CSP - brak wbudowanych skryptów
Trevor
121

Jak widać na https://github.com/atom/electron/issues/254 problem jest spowodowany przez ten kod:

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

Kod jQuery „widzi”, że działa w środowisku CommonJS i ignoruje window.

Rozwiązanie jest naprawdę łatwe , zamiast ładować jQuery <script src="...">, powinieneś załadować w następujący sposób:

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

Uwaga: kropka przed ścieżką jest wymagana , ponieważ wskazuje, że jest to katalog bieżący. Pamiętaj również, aby załadować jQuery przed załadowaniem jakiejkolwiek innej wtyczki zależnej od tego .

Bruno Vaz
źródło
1
Dzięki, ale mam system stworzony przez Yeoman z kątownikiem. Grunt bierze wszystkie moje zależności od altany i wbudowuje je w plik vendor.js. Jak mogę załadować jquery, naprawić z twoją linią i kontynuować z innymi zależnościami altana, które wymagają jquery?
bluesky777,
Nie rozumiem, czy w vendor.js jest jquery? Jeśli tak, możesz załadować vendor.js za pomocą tego okna. Metoda $ afaik.
Bruno Vaz,
Niektóre komentarze w dalszej części powiązanego rozwiązania są jeszcze lepsze: 'node-integration': falsejako opcja dla BrowserWindow.
Boldewyn
6
Czy to nie wpływa na inne rzeczy?
Bruno Vaz,
53

Innym sposobem pisania <script>window.$ = window.jQuery = require('./path/to/jquery');</script>jest:

<script src="./path/to/jquery" onload="window.$ = window.jQuery = module.exports;"></script>
Aaleks
źródło
Uznałem to za najlepszą odpowiedź, ponieważ nadal mogę używać CDN! I nie trzeba niczego nadpisywać.
patotoma
53

odpowiedź na najczęściej zadawane pytania dotyczące elektronów:

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

Nie mogę używać jQuery / RequireJS / Meteor / AngularJS w Electron.

Ze względu na integrację Node.js z Electronem, do modułu DOM wstawiono kilka dodatkowych symboli, takich jak eksport, wymagają. Powoduje to problemy dla niektórych bibliotek, ponieważ chcą wstawić symbole o tych samych nazwach.

Aby rozwiązać ten problem, możesz wyłączyć integrację węzłów w Electron:

// W głównym procesie.

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

Ale jeśli chcesz zachować możliwości korzystania z Node.js i interfejsów API Electron, musisz zmienić nazwy symboli na stronie przed dołączeniem innych bibliotek:

<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
źródło
@ Fran6 co mogę zrobić, jeśli ładuję stronę zewnętrzną? :(
georgiosd,
To działało, ale po wykonaniu tej czynności moja aplikacja Electron nie chciała się zamknąć - to znaczy nie mogłam opuścić strony internetowej.
tale852150,
34

Właśnie natknąłem się na ten sam problem

npm install jquery --save

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

pracował dla mnie

Dhaval Chauhan
źródło
Dokładnie tak mówi moja pierwotna odpowiedź.
Bruno Vaz,
Cześć, jak to zrobić z materialize.min.js cdnjs.cloudflare.com/ajax/libs/materialize/0.98.2/js/… . .. coś takiego jak to <skrypt> okno.Materialize = window.Materialize = wymaga ('Materialize'); </script> ??? może ktoś pomóc
Makjb lh 24.04.17
@BrunoVaz ta odpowiedź jest czystsza :)
moeiscool
20

Możesz umieścić node-integration: falseopcje wewnątrz BrowserWindow.

na przykład: window = new BrowserWindow({'node-integration': false});

Murilo Feres
źródło
4
To dobre rozwiązanie dla użytkowników, którzy nie potrzebują integracji węzłów.
Adam Szmyd
To jest niesamowite, idealnie dla mnie działa. Dzięki @Murilo Feres. Jakieś sposoby, jakie są opcje integracji węzłów?
Ahesanali Suthar
3
nie działa @ 1.4, użyj: let win = new BrowserWindow ({webPreferences: {nodeIntegration: false}})
holly
14

Ładne i czyste rozwiązanie

  1. Zainstaluj jQuery przy użyciu npm. ( npm install jquery --save)
  2. Użyj tego: <script> let $ = require("jquery") </script>
adgelbfish
źródło
8

Mam ten sam problem i to zadziałało dla mnie!

Zainstaluj jQuery przy użyciu npm

$ npm install jquery

Następnie dołącz jQuery na jeden z poniższych sposobów.

Korzystanie ze znacznika skryptu

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

Korzystanie z Babel

import $ from 'jquery';

Korzystanie z pakietu Webpack

const $ = require('jquery');
Abraham Hernandez
źródło
5

Myślę, że rozumiem twoją walkę, rozwiązałem ją trochę inaczej. Użyłem programu ładującego skrypty dla mojego pliku js, który zawiera jquery. Program ładujący skrypt bierze twój plik js i dołączając go do górnej części pliku vendor.js zrobił mi magię.

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

po zainstalowaniu modułu ładującego skrypt dodaj go do pliku rozruchowego lub aplikacji.

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

Mertcan Diken
źródło
4

ok, oto inna opcja, jeśli chcesz krewnego to ...

<script> window.$ = window.jQuery = require('./assets/scripts/jquery-3.2.1.min.js') </script>
aestrro
źródło
3

Jeśli używasz Angular2, możesz utworzyć nowy plik js z tym kodem:

// jquery-electron.js

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

i umieść go zaraz za ścieżką jquery, w .angular-cli.json:

"scripts": [
    "../node_modules/jquery/dist/jquery.js",
    "assets/js/jquery-electron.js",
    ...
    ...
]
Max
źródło
3

im building i Angular App z elektronem, moje rozwiązanie było następujące:

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

Więc Jquery jest ładowany z angular.json, jeśli jest w przeglądarce, w przeciwnym razie, jeśli jest to aplikacja zbudowana na elektronach, będzie wymagać modułu.

Jeśli chcesz zaimportować jquery do index.html zamiast importować z angular.json, skorzystaj z następującego rozwiązania:

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

pracował dla mnie przy użyciu następującego kodu

var $ = require('jquery')
Adeojo Emmanuel IMM
źródło
2

1. Zainstaluj jQuery za pomocą 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
źródło
2

To działa dla mnie.

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

Rzeczy do rozważenia:

1) Umieść to w sekcji tuż przed </head>

2) Dołącz Jquery.min.js lub Jquery.js tuż przed </body>tagiem

Vishal Goyal
źródło
0

możesz wypróbować następujący kod:

mainWindow = new BrowserWindow({
        webPreferences: {
            nodeIntegration:false,
        }
});
shuoGG
źródło
0

W przypadku tego problemu użyj JQuery i innych js tak samo, jak na stronie sieci Web. Jednak Electron ma integrację węzłów, więc nie znajdzie obiektów js. Musisz ustawić, module = undefinedaż obiekty js zostaną poprawnie załadowane. Zobacz poniższy przykład

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

Po zaimportowaniu, tak jak podano, będziesz mógł używać JQueryinnych rzeczy w elektronie.

Kiran Maniya
źródło
0

Wystarczy zainstalować Jquery za pomocą następującego polecenia.

npm install --save jquery

Następnie proszę wstawić linię do pliku js, którego chcesz użyć Jquery

let $ = require('jquery')
Milan Hirpara
źródło