0

Ok, I apologize that this question is a duplicate, as I found my exact question asked and answered here: Electron: jQuery is not defined. Unfortunately, I'm too much of a noob to wrap my head around the answer.

I've been programming desktop apps for a long time(TM), so I'm not new to programming or development, but Electron, Node.js, JavaScript, Angular, et al. are a new domain for me and I'm still pretty green.

I was able to install node and get the basics of npm figured out. After that, I used npm to install electron, jQuery, and a treeview package called FancyTree (specifically version 2.24 as 2.26 seems to have an unrelated issue).

Now, following along with some basic Electron tutorials, my index.js looks like this:

const electron = require('electron');
const url = require('url');
const path = require('path');
const fs = require('fs');
const { app, BrowserWindow } = electron;

let mainWindow;

app.on('ready', function() {

    mainWindow = new BrowserWindow({ });

    mainWindow.loadURL(url.format({
        pathname: path.join(__dirname, 'mainWindow.html'),
        protocol: 'file:',
        slashes: true
    }));

});

I grasp that this is simply creating my main browser window during the 'ready' event handler, and navigating to my corresponding html, which looks like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Getting my Feet Wet</title>
</head>
<body>
    <h1>My feet are wet.  Weird.</h1>
</body>
</html>

Nothing exciting so far.

But now I install jQuery and Fancytree using npm and I try to 'require' fancytree (just after the line for fs) like this:

const fancytree = require('jquery.fancytree');

which doesn't work. After some googling, it appears that (for reasons I don't completely understand) it is better to 'require' fancytree like this:

const fancytree = require('jquery.fancytree/dist/jquery.fancytree.js');

For now, I'm willing to accept that without fully understanding the 'why'.

But I'm still throwing an error:

App threw an error during load ReferenceError: jQuery is not defined at Object. (C:\Scratch\QuickStart\node_modules\jquery.fancytree\dist\jquery.fancytree.js:5249:3) etc.

This seems to stem from the fact that Electron's use of Node.js defines some 'global-ish' references that conflict with various packages expectations. Electron seems to outline one solution as passing the nodeIntegration: parameter as false when constructing the new browser window, which I tried without any joy.

The other answers all deal with various script blocks in the html, which makes no sense to me at all because it creates an order-of-operation problem. For example, the statement to 'require' Fancytree will execute before my 'ready' event, which means it would happen well before the browser window is constructed, which would be long before any script blocks are run in the html; so that can't possibly work.

Thinking procedurally for a moment, I would expect my index.js to look more like this (presented in pseudo-code):

const electron = require('electron');
const url = require('url');
const path = require('path');
const fs = require('fs');

const fancytree; //this obviously isn't valid

const { app, BrowserWindow } = electron;

let mainWindow;

app.on('ready', function() {

    mainWindow = new BrowserWindow({ });

    //I hijacked this from the original Q/A on stack but don't
    //completely understand what it's doing, or if it's even
    //legit, but the idea is to fix the mainWindow / jQuery
    //reference now that the window is constructed but before
    //I try to require the FancyTree.
    //
    mainWindow.$ = mainWindow.jQuery = require('jquery');

    //And now that jQuery is sorted out it's marbles, let's get back 
    //to business...
    //
    fancytree = require('jquery.fancytree/dist/jquery.fancytree.js');

    mainWindow.loadURL(url.format({
        pathname: path.join(__dirname, 'mainWindow.html'),
        protocol: 'file:',
        slashes: true
    }));

});

Obviously this is wrong, and I'm displaying my lack of depth of understanding with these technologies, but what should this look like? How do I structure my initialization logic to properly 'fix' jQuery after my browser window is constructed and still execute the 'require' for Fancytree?

If it is helpful, what I am driving at is simply getting a basic tree visible in my UI in Electron. Preferably without sacrificing Node.js to any 'workarounds' as my hope is to learn more about Node, Angular, and jQuery as part of this experiment. Generally, I like to avoid hacks/shims/workarounds when learning new technologies. It feels like you are already 'doing it wrong'.

As always, any help is most appreciated!

Geo...
  • 307
  • 2
  • 14
  • 1
    Did you solve the problem? I would be glad if you share the solution here. – Özgür Can Karagöz Dec 08 '17 at 09:53
  • 1
    I have not been able to solve this problem. – Geo... Dec 08 '17 at 15:45
  • There is a similar issue on GitHub, where this can be discussed further https://github.com/mar10/fancytree/issues/796 – mar10 Jan 16 '18 at 17:51
  • Your question is exactly what happens to me and is very well explained. This is what explains my upvote. I found a workaround by putting all the js code inside `window.addEventListener('DOMContentLoaded', () => {` in the current package of Electron – w3spi Dec 29 '21 at 16:31

1 Answers1

2

If your app does not need node-integration, add "node-integration": false to your BrowserWindow options. In this case module.exports is not available, jQuery works like expected.

And try installing it via npm:

npm install jquery

This worked for me while trying the same. Then you don't need to give a path, you just say:

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

fancytree = require('jquery.fancytree');
Özgür Can Karagöz
  • 1,039
  • 1
  • 13
  • 32
  • Thanks for the reply. I did try installing jquery using npm, which did not help. I did try the node-integration as false, which also did not help, but I am trying to avoid going down that road anyway. - I also tried your snippet without success. If I simply require 'jquery.fancytree' it fails with "Cannot find module jquery.fancytree" and if I require "jquery.fancytree/dist/jquery.fancytree.js" it fails with "Reference error jquery not defined". – Geo... Dec 08 '17 at 00:35
  • Also, just doing this: mainWindow.$ = mainWindow.jQuery = require('jquery'); and console.log( [$, jQuery ]); is enough to throw "ReferenceError: $ is not defined" – Geo... Dec 08 '17 at 00:38