62

I am using Electron to make a desktop app. In my app I am loading a an external site (outside Atom app) lets say http://mydummysite/index.html page.

Here is the structure of my app in Atom Editor:

enter image description here

i.e it is having following parts:

  1. main.js
  2. package.json
  3. nodemodules>jquery (to load jquery)

Source code:

main.js:

   'use strict';

    var app = require('app');

    app.on('ready', function() {
      var BrowserWindow = require('browser-window');

      var win = 
      new BrowserWindow({ width: 800, height: 600, show: false, 
               'node-integration':true });
      win.on('closed', function() {
        win = null;
      });

      win.loadUrl('http://mydummysite/index.html ');
      win.show();
    });

package.json:

{
  "name": "my-mac-app",
  "version": "5.2.0",
  "description": "My Mac Desktop App",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "author": "Me",
  "license": "ISC",
  "dependencies": {
    "jquery": "^2.1.4"
  }
}

External page - http://mydummysite/index.html page code:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <h1>Hello World!</h1>

  </body>
<script>

   var jqr=require('jquery');

</script>
</html>

When I run the above app (by dragging the application folder to Electron) the external page (http://mydummysite/index.html) loads in Electron shell but with the error

Uncaught Error: Cannot find module 'jquery'

enter image description here

Can you help me finding the cause of this issue?

As you can see in my screenshot of directory structure I have alread installed jquery module to my folder and I did it via npm install jquery command.

Note: To play with require command in JS I tried adding require("ipc") in my external page http://mydummysite/index.html page and it was working so what could be the reason with require("jquery").

Did I add external module (jquery) in correct way in Electron?

Am I missing some dependency in package.json?

What I have already tried:

  • npm cache clean, npm install jquery (to my app folder)
  • npm install --save jquery
  • npm install jquery -g
  • npm rebuild
  • sudo npm install jquery -g
  • sudo npm install jquery
  • export NODE_PATH=/usr/local/lib/node_modules

Here is the screenshot of the location from where the error is thrown in module.js

enter image description here

Can someone suggest why require("ipc") is working and require("jquery") not?

My goal is to use jQuery with electron app with node-integration true.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Raghav
  • 8,772
  • 6
  • 82
  • 106
  • https://github.com/UncoolAJ86/node-jquery/issues/35 not sure whether this link will solve but it will get you started. – Akki619 Aug 28 '15 at 07:30
  • possible duplicate of [How to use node\_modules within electron (formerly atom-shell)](http://stackoverflow.com/questions/30664111/how-to-use-node-modules-within-electron-formerly-atom-shell) – Yan Foto Aug 29 '15 at 17:42
  • Yan, The one you mention is the case when we are using a page inside of atom shell application. I am loading a page from an external url. – Raghav Aug 29 '15 at 18:43
  • can you show package.json for jquery package ?? – Daredzik Sep 03 '15 at 14:01

6 Answers6

46

tl;dr

In contrast to a normal nodejs app, where you have access to global modules (e.g. located in /usr/bin/node), electron doesn't automatically set the NODE_PATH environment variables. You have to set it manually to all the paths containing your desired modules.


Update:

The answer to the question

why require("ipc") is working and require("jquery") not?

is to be found in this issue, stating that system/user modules should not be included in the global path of the module

since they could contain modules not shipped with the app and possibly compiled with the wrong v8 headers.

And if you take a look at electron's source you can see that internal modules are added to the module.globalPaths:

# Add common/api/lib to module search paths.
globalPaths.push path.resolve(__dirname, '..', 'api', 'lib')

thats why you have access to ipc, app, etc. but not the modules that you have installed globally using npm install -g.


I just tried it out with the latest electron-prebuilt version with a local server serving exactly the same HTML file that you provided and I think I know what the problem is: If you don't append the path to your app node_modules directory under your app root to the NODE_PATH variable it is not going to work. So you need to do something like this:

export NODE_PATH=/PATH/TO/APP/node_modules
electron /PATH/TO/APP

When exporting NODE_PATH make sure that you provide an absolute path.


**Update 2:**

The answer to the comment:

I get jQuery not found errors

Is to be found in this ticket. Basically if you use the jQuery's npm package or do something like the following in your HTML files inside electron:

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

What you get is a factory and not the actual jQuery object attached to the global context (e.g window). As I mentioned in a previous answer (containing also jQuery's source code)

When you require jQuery inside a CommonJS or similar environment which provides module and module.exports, what you get is a factory and not the actual jQuery object.

Now to use that factory (either by importing the code from the CDN or if you have the npm module available locally) you would need something as the following:

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

I have written an article that explains the combination of Node + jQuery.

Yan Foto
  • 10,850
  • 6
  • 57
  • 88
  • @AleksandrM I suppose because it is an internal module provided by the electron. Other internal modules (e.g. `app`) also work with no problem. – Yan Foto Sep 02 '15 at 12:22
  • @AleksandrM @raj I referenced the issue and source code showing why `ipc` is available and why global nodules not! – Yan Foto Sep 03 '15 at 15:01
  • @AleksandrM it makes sense now for me as well :) – Yan Foto Sep 03 '15 at 19:39
  • Really good follow up, was going to add on, but you covered it. – J-Boss Sep 04 '15 at 09:00
  • @J-Boss thanks! it was one of those questions that I thought I knew the answer before I found out that I dont! – Yan Foto Sep 04 '15 at 09:02
  • If I refer then I get jQuery not found errors in electron. If I comment if ( typeof module === "object" && typeof module.exports === "object" ) { in core jquery file only then jQuery is availaible. – Raghav Sep 05 '15 at 07:06
  • @raj The answer might have been confusing, but please read the mentioned article and jQuery's source code to have a better understanding of how it works within CommonJS environments. Nonetheless I updated my answer to contain all necessary info. – Yan Foto Sep 05 '15 at 08:38
  • 1
    @YanFoto. I used require('gulp'), it reminds me an error: cannot load module "gulp". How should I do? I am not clear about where should I put those code `export NODE_PATH=/PATH/TO/APP/node_modules electron /PATH/TO/APP` – Ng2-Fun Mar 23 '16 at 04:10
  • me neither, @YanFoto, can you describe step-by-step where we need to place that code? – lukaszkups Jan 13 '20 at 22:19
8

Install jquery with npm isn't enough :

npm install --save jquery

It recovers the source files of jQuery in your project. But you have to include the script in your html file :

<!DOCTYPE html>
<html>
  <head></head>

  <body>
      <h1>Hello World!</h1>
  </body>

  <!-- Try to load from cdn to exclude path issues. -->
  <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

  <script>
     window.jQuery = window.$ = jQuery;

     $(document).ready(function() {
         console.log( "jQuery is loaded" );
     });
  </script>

</html>
Damien
  • 3,915
  • 1
  • 17
  • 18
  • "node_modules/jquery/dist/jquery.min.js" path will result to "http://mydummysite/node_modules/jquery/dist/jquery.min.js" which will give 404. I have jquery module installed in my Electron app instead of remote application (http://mydummysite/) – Raghav Aug 28 '15 at 11:37
  • Yes but if you want to use jquery in your dummy site, you have to load jquery in your dummy site. To test you can include a script from the jquery CDN, like that no path problem : – Damien Aug 28 '15 at 13:11
  • If I use script tag then jQuery namespace is not exposed. Seems issue with modules with node integration. – Raghav Aug 31 '15 at 10:53
  • 1
    The jQuery namespace isn't exposed, but $ is exposed normally. – Damien Sep 01 '15 at 08:55
  • I need jQuery namespace because it is being referred at many places in my website. – Raghav Sep 05 '15 at 07:12
  • Add window.jQuery = window.$ = jQuery; – Damien Sep 07 '15 at 12:02
6

I have the same issue when using jQuery with electron, and find out a solution for these case:

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

Source: https://discuss.atom.io/t/electron-app-to-host-external-site/16390/9

dunklesToast
  • 344
  • 3
  • 16
gunivan
  • 71
  • 2
  • 2
4
# assuming you have installed jquery locally instead of globally like in as
npm install jquery -s         # without -g flag

instead of require("jquery"), give relative path from source directory
require("./node_modules/jquery/dist/jquery.min.js");

Try the following:

<script>window.$ = window.jQuery = require('./node_modules/jquery/dist/jquery.min.js');</script>

OR

<script>var $ = jQuery = require('./node_modules/jquery/dist/jquery.min.js');</script>
VanagaS
  • 3,130
  • 3
  • 27
  • 41
1

I hope below link will put some light on your doubt for

why require("ipc") is working and require("jquery") not?

https://github.com/atom/electron/issues/254

https://discuss.atom.io/t/electron-app-to-host-external-site/16390/7

Akki619
  • 2,386
  • 6
  • 26
  • 56
0

The same issue happened to me , a simple solution is to add this to your index.js file :

app.on('ready', function() {
      var mainWindow = new BrowserWindow({
        "node-integration": false
      })
//rest of your initialization code here.
})

the issue is caused by node , for more information please refer to this post

Setting node-integration to false will disable node.js in the renderer process - i.e. your app can only do what a web browser will do.

Community
  • 1
  • 1
ProllyGeek
  • 15,517
  • 9
  • 53
  • 72