未捕获的错误:无法找到模块“jquery”。

62

我正在使用 Electron 来制作一个桌面应用程序。在我的应用程序中,我正在加载一个外部网站(Atom应用程序之外)比如说http://mydummysite/index.html页面。

这是在 Atom编辑器 中的我的应用程序结构:

enter image description here

即它包含以下部分:

  1. main.js
  2. package.json
  3. nodemodules>jquery (用于加载jquery)

源代码:

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

外部页面 - http://mydummysite/index.html 页面代码:

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

  </body>
<script>

   var jqr=require('jquery');

</script>
</html>
当我运行上述应用程序(将应用程序文件夹拖到Electron中)时,外部页面(http://mydummysite/index.html)在Electron shell中加载,但是出现以下错误:

Uncaught Error: Cannot find module 'jquery'

enter image description here 你能帮我找出这个问题的原因吗?
如您在目录结构的截图中所见,我已经通过npm install jquery命令将jquery模块安装到我的文件夹中。
注意:为了操作JS的require命令,我尝试在我的外部页面http://mydummysite/index.html中添加了require("ipc"),它可以正常工作,那么require("jquery")的原因是什么呢?
我是否以正确的方式在Electron中添加了外部模块(jquery)?
我是否在package.json中缺少某些依赖项?
这是我已经尝试过的:
- npm cache cleannpm install jquery(到我的应用程序文件夹) - 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 这是module.js中抛出错误的位置的截图: enter image description here 有人能建议为什么require("ipc")能工作而require("jquery")不能吗?
我的目标是在启用node-integration的情况下在Electron应用程序中使用jQuery。

https://github.com/UncoolAJ86/node-jquery/issues/35 不确定这个链接是否能解决问题,但它可以让你开始。 - Akki619
Yan,你提到的是在Atom Shell应用程序内部使用页面的情况。我正在从外部URL加载页面。 - Raghav
你能展示一下jQuery包的package.json吗? - Daredzik
6个回答

46

简而言之

与普通的Node.js应用程序不同,您可以访问全局模块(例如位于/usr/bin/node中的模块),Electron不会自动设置NODE_PATH环境变量。您需要手动设置包含所需模块的所有路径。


更新:

问题的答案是为什么require("ipc")可以工作而require("jquery")不能?在这个问题中找到,指出系统/用户模块不应该包含在模块的全局路径中,因为它们可能包含未随应用程序一起提供并可能使用错误的v8头文件编译的模块。

如果你看一下electron源代码,你会发现内部模块被添加到了module.globalPaths中:

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

这就是为什么你可以访问ipcapp等内容,但无法访问使用npm install -g全局安装的模块。


我刚刚使用最新的electron-prebuilt版本,使用一个本地服务器提供与您提供的完全相同的HTML文件进行了测试,我认为我知道问题所在:如果您不将应用程序根目录下的node_modules目录路径附加到NODE_PATH变量中,它将无法工作。因此,您需要执行以下操作:
export NODE_PATH=/PATH/TO/APP/node_modules
electron /PATH/TO/APP

在导出NODE_PATH时,请确保提供绝对路径。


这条评论的答案是:

我遇到了 jQuery 未找到的错误。

可以在这张票中找到答案。基本上,如果您使用jQuery的npm包或在electron内部的HTML文件中执行以下操作:

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

您得到的是一个工厂,而不是附加到全局上下文(例如window)的实际jQuery对象。正如我在之前的答案中提到的(还包含了jQuery的源代码)

当您在CommonJS或类似环境中需要jQuery时,该环境提供modulemodule.exports,您得到的是一个工厂,而不是实际的jQuery对象。

现在,要使用该工厂(无论是通过从CDN导入代码还是如果您在本地可用npm模块),您需要像以下内容一样:
<script>
  window.jQuery = window.$ = require('jquery');
</script>

我写了一篇文章,讲解了Node和jQuery的结合。


@AleksandrM 我认为这是因为它是由Electron提供的内部模块。其他内部模块(例如app)也可以无问题地工作。 - Yan Foto
@AleksandrM @raj 我参考了问题和源代码,展示了为什么 ipc 可用而全局模块不可用! - Yan Foto
@AleksandrM 现在对我来说也有意义了 :) - Yan Foto
非常好的跟进,我本来想补充一下,但你已经涵盖了。 - J-Boss
1
@YanFoto。我使用了require('gulp'),但是它提醒我一个错误:无法加载模块“gulp”。我该怎么办?我不清楚应该把这些代码放在哪里export NODE_PATH=/PATH/TO/APP/node_modules electron /PATH/TO/APP - Ng2-Fun
显示剩余4条评论

8
使用npm安装jquery是不够的:
npm install --save jquery

它可以恢复你项目中使用的jQuery源文件。但你需要在你的HTML文件中包含这个脚本:
<!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>

是的,但如果你想在你的虚拟网站中使用jQuery,你必须加载jQuery。为了测试,你可以在页面中包含一个来自jQuery CDN的脚本,这样就不会出现路径问题:<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> - Damien
如果我使用脚本标签,那么jQuery命名空间就不会被公开。这似乎与具有节点集成的模块有关。 - Raghav
1
jQuery的命名空间没有暴露出来,但$通常是暴露出来的。 - Damien
我需要jQuery命名空间,因为它在我的网站上被多处引用。 - Raghav
添加 window.jQuery = window.$ = jQuery; - Damien

6

当我在electron中使用jQuery时,遇到了同样的问题,并找到了解决方案:

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

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

这是一个有关使用Electron应用程序托管外部网站的帖子。如果您想要将网站包装成桌面应用程序,可以使用Electron。您只需要在主进程中创建一个窗口并加载您的网站即可。此外,您还可以使用Electron提供的API来访问本地文件系统和其他操作系统功能。

4
# assuming you have installed jquery locally instead of globally like in as
npm install jquery -s         # without -g flag

不要使用 require("jquery"),而是从源目录给出相对路径
require("./node_modules/jquery/dist/jquery.min.js");

请尝试以下方法:

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

或者

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

1

我需要开启node-interation。第二个链接说要关闭它。 - Raghav

0
相同的问题也发生在我身上,一个简单的解决方法是将以下内容添加到你的 index.js 文件中:
app.on('ready', function() {
      var mainWindow = new BrowserWindow({
        "node-integration": false
      })
//rest of your initialization code here.
})

问题是由node引起的,更多信息请参考这个post

将node-integration设置为false将禁用渲染进程中的node.js - 也就是说,您的应用程序只能执行Web浏览器可以执行的操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接