节点上的客户端:未捕获ReferenceError:需求未定义


320

因此,我正在使用node / express + jade组合编写应用程序。

我有client.js,已在客户端上加载。在该文件中,我有调用其他JavaScript文件中的函数的代码。我的尝试是使用

var m = require('./messages');

为了加载内容messages.js(就像我在服务器端一样),然后再加载该文件的调用函数。但是,require未在客户端定义,并且引发形式的错误Uncaught ReferenceError: require is not defined

这些其他JS文件也会在运行时在客户端上加载,因为我将链接放在网页的标题上。因此,客户端知道从这些其他文件导出的所有功能。

如何从打开服务器套接字messages.js的主client.js文件中的其他JS文件(如)调用这些函数?


4
你为什么不随便<script src="messages.js"></script>打电话给他们呢?
斯特林阿彻2013年

1
也许这可以解决,但还有另一件事与我有关。我还有一个名为“ representation.js”的文件,用于抽象化客户端和服务器通用的表示形式。在该文件中,我还具有require语句,并且在服务器端应该没问题,因为我正在运行节点。但是,在客户端,这将是一个问题。你怎么看?
MightyMouse

2
对于像我这样的新手(一周前甚至无法拼写“ npm”!:-),了解浏览器--require选项的原因require()是在客户端定义的,这可能会有所帮助。参见:lincolnloop.com/blog/speedy-browserifying-multiple-bundles
Hephaestus

2
@Sterling Archer ...如果有100个此类文件...我们将无法继续以HTML格式正确加载.........
Baradwaj Aryasomayajula

Answers:


436

这是因为require()浏览器/客户端JavaScript中不存在。

现在,您将不得不对客户端JavaScript脚本管理做出一些选择。

您有三种选择:

  1. 使用<script>标签。
  2. 使用CommonJS实现。同步依赖项,例如Node.js
  3. 使用AMD实施。

CommonJS客户端实现包括:

(大多数部署之前都需要一个构建步骤)

  1. Browserify-您可以在浏览器中使用大多数Node.js模块。这是我个人的最爱。
  2. Webpack-做所有事情(捆绑JS,CSS等)。由于React.js的激增而流行。因学习曲线困难而臭名昭著。
  3. 汇总 -新竞争者。利用ES6模块。包括摇树能力(删除未使用的代码)。

您可以阅读有关我的Browserify与(不推荐使用)Component比较的更多信息。

AMD的实现包括:

  1. RequireJS-在客户端JavaScript开发人员中非常受欢迎。因为它的异步特性,所以不是我的口味。

请注意,在搜索选择搭配哪一款时,您会了解到Bower。Bower仅用于程序包依赖性,并且在CommonJS和AMD等模块定义上不受质疑。

希望这会有所帮助。


1
非常感谢你。我分别进行了一次迷你测试,这就是为什么我花了一段时间才做出答复。我可能会在几分钟后再提出一些问题,以确保我了解此魔术的工作原理。我只想把所有东西放在一起。再次感谢。Browserify似乎很摇滚!:)
MightyMouse

6
我认为JSPM应该添加到列表中。
Martijn'2

19
我能否得到一个使用<script>标签导入React类而不使用nodeJs包管理器的示例?
Louie Bertoncin '16

2
SystemJS和JSPM是非常明显的遗漏。
阿兰·哈达德

4

43

我来自电子环境,我需要渲染器进程与主进程之间的IPC通信。渲染器进程位于脚本标记之间的HTML文件中,并生成相同的错误。线

const {ipcRenderer} = require('electron')

引发Uncaught ReferenceError:未定义require

当最初在主流程中创建浏览器窗口(嵌入此HTML文件的窗口)时,我可以通过将节点集成指定为true来解决此问题。

function createAddItemWindow() {
//Create new window
addItemWindown = new BrowserWindow({
    width: 300,
    height: 200,
    title: 'Add Item',

    //The lines below solved the issue
    webPreferences: {
        nodeIntegration: true
    }
})}

那为我解决了这个问题。在这里提出解决方案。希望这对其他人有帮助。干杯。


非常感谢你。我想我来自YouTube的同一购物清单应用视频hahaha
Luiscri

出色-很高兴找到这样的答案,而不是依靠入门者神奇地将它们全都整合在一起。
GhostBytes

给电子用户一个很好的答案!
thoni56

惊人。对我来说很好。另外,我也来自购物清单应用视频o
adahox_

25

ES6:在html中使用属性包含主要js文件type="module"浏览器支持):

<script type="module" src="script.js"></script>

script.js文件中包含另一个文件,例如:

import { hello } from './module.js';
...
// alert(hello());

在包含的文件(module.js)中,您必须导出要导入的函数/类

export function hello() {
    return "Hello World";
}

这里的工作示例


1
@Curse这里stackoverflow.com/a/44591205/860099写道:“模块创建作用域以避免名称冲突。” 因此,您可以“手动”放置 val到窗口对象window.val = val。这是个笨蛋:笨蛋:plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p= preview-此解决方案有效
KamilKiełczewski18年

1

就我而言,我使用了另一种解决方案。

由于项目不需要CommonJs,并且必须具有ES3兼容性(不支持模块),因此您所需要做的就是从代码中删除所有exportimport语句,因为tsconfig不包含

"module": "commonjs"

但是在引用的文件中使用导入和导出语句

import { Utils } from "./utils"
export interface Actions {}

最终生成的代码将始终具有(至少对于打字稿3.0而言)这样的行

"use strict";
exports.__esModule = true;
var utils_1 = require("./utils");
....
utils_1.Utils.doSomething();

1

即使使用此方法也不起作用,我认为最好的解决方案是browserify:

module.exports = {
  func1: function () {
   console.log("I am function 1");
  },
  func2: function () {
    console.log("I am function 2");
  }
};

-getFunc1.js-
var common = require('./common');
common.func1();

0

这对我有用

  1. 保存此文件https://requirejs.org/docs/release/2.3.5/minified/require.js
  2. 加载到您的HTML中,如下所示
    <script data-main="your-Scrpt.js" src="require.js"></script>

    使用:->“ your-script.js”中的require(['moudle-name'])
    不需要('moudle-name')
    const {ipcRenderer} = require(['electron'])
    不是:const {ipcRenderer} = require('electron')

2
绝对不要推荐“单击此处”。最好的情况是RickRoll,但我们不知道该链接末尾正在等待着什么。
ggdx
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.