12

我有一个想要包含在 Require.js 链中的模块。(更具体地说:https ://github.com/component/emitter )

在浏览器上我得到: uncaught reference error: module is not defined

对于模块导出,它定义: module.exports = Emitter;

我猜这被称为 AMD / Node 方式。如有错误请指正。

无论如何,我希望 require.js 能够以某种方式在浏览器中进行模块。我认为 Require.js 的声明性填充选项可以帮助我,但我仍然看到上述错误。

如果不手动修补模块,如何解决这个问题?(因为我想保留我设置的自动构建过程)

4

1 回答 1

5

组件是 CommonJS 模块

Components 框架是一个以 CommonJS 模块格式编写的组件的集合。一个模块的预期值被简单地分配给一个名为 的“神奇属性” module.export,旨在由 JS 运行时提供。

这不是 Web JS 运行时的工作方式,因为 CommonJS 模块对特定的工作流程做出假设。如果无法同步保证文件已加载(或未加载时发生灾难性失败),浏览器将无法支持与独立环境相同的工作流程。因此,必须包装以 CommonJS 格式编写的任何内容以考虑到这一点。

为了将 CommonJS 模块与 AMD 样式的模块加载器(如 RequireJS)一起使用,您可以自己包装您需要的模块,也可以使用 r.js 构建工具。

手动包装 CommonJS 模块

define(function(require, exports, module) {
  //Put traditional CommonJS module content here
});

来自CommonJS 笔记

使用 r.js 自动包装

r.js -convert path/to/commonjs/modules path/to/converted/modules

鉴于您已经安装r.jsnpm -g i requirejs.

解决具体问题

然而,这一切只是解决了“如何在异步工作流中使用 CommonJS 模块?”这个更普遍的问题。看起来您实际上想要实现的只是能够在不自己编写事件系统的情况下获得它。

由于您是在客户端加载它,因此有很多客户端库已经提供了此功能。提供此功能的最受欢迎的库可能是Backbone.js 的 Events。使用 Backbone 事件的好处是 Backbone 得到了很好的支持,并且有据可查。缺点是 Backbone 是另一个必须加载的依赖项(包括它自己的依赖项,Underscore)。此外,Backbone 导出到全局变量,因此您需要声明一个 RequireJS shim 配置才能使用require()它。

真正的 AMD

圣杯将是一个小型且与 AMD 兼容的 EventEmitter 类型库。为此,您可以尝试使用pubsub.jsnbd.js 之类的微型库(披露:我是 nbd.js 的作者)。

如果您确实使用 nbd.js,它提供的不仅仅是 pubsub 功能。但是您可以专门require()只使用 pubsub 模块。

如果您使用 git 进行源代码控制,最简单的方法是将其用作子模块。

git submodule add git@github.com:behance/nbd.js.git path/to/nbd

然后,requirepubsub 模块,做你想做的事!

require(['nbd/trait/pubsub'], function(pubsub) { /* do whatever */ });
于 2013-07-28T19:54:40.643 回答