【发布时间】:2016-07-27 16:55:04
【问题描述】:
我正在尝试编写一些 JS 模块,它们应该可以在浏览器和 node.js 环境中使用。
为方便起见,我将这些模块编写为AMD modules,并使用requirejs in the Node.js environment 提供define() 函数以及加载这些模块的能力。
但是,我遇到了一些我不理解的行为。
我制作了一个 SSCCE 来说明问题:
├── bar.js
├── node_modules
│ └── foo
│ ├── foo.js
│ ├── index.js
│ ├── node_modules
│ │ └── requirejs
│ │ ├── bin
│ │ │ └── r.js
│ │ ├── package.json
│ │ ├── README.md
│ │ └── require.js
│ └── package.json
└── test.js
foo 是一个包含 AMD 模块 foo.js 的节点模块
node_modules/foo/foo.js
define([], function() {
return function() {
console.log("This is foo!");
};
});
node_modules/foo/index.js
var requirejs = require('requirejs');
requirejs.config({
baseUrl: __dirname,
nodeRequire: require
});
module.exports = requirejs('foo');
bar.js 是另一个 AMD 模块:
define([], function() {
return function() {
console.log("This is bar!");
};
});
test.js 是一个想要同时使用 foo 和 bar 的脚本:
var requirejs=require('requirejs');
requirejs.config(
{
baseUrl: __dirname,
nodeRequire: require
}
);
var foo=require("foo");
foo();
var bar=requirejs("bar");
console.log("bar is:",bar);
如果我运行 test.js,我会得到:
This is foo!
bar is: undefined
/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:393
throw err;
^
Error: Mismatched anonymous define() module: function () {
return function() {
console.log("This is bar!");
};
}
http://requirejs.org/docs/errors.html#mismatch
at makeError (/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:418:17)
at intakeDefines (/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:1501:36)
at null._onTimeout (/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:1699:25)
at Timer.listOnTimeout (timers.js:119:15)
这里有两件事对我来说没有意义。
在 test.js 中,对
requirejs("bar")的调用返回 undef。事实上它看起来 模块的加载被延迟,好像有一些循环 依赖继续存在,因为只有在它返回之后 正在执行 bar 的模块定义。为什么它认为这是一个匿名的
define()?我的用例没有出现 以满足给定 URL 中的条件。
为了抑制第二个问题,我尝试在 bar.js 中命名定义,如下所示:
define('bar', [], function() {
...
这在异常消失的意义上有效,但requirejs("bar") 仍然
返回 undef。
该示例是我正在尝试做的简化版本 - 基本上我会 有许多模块,其中将包含一些常见的组件,可以 在浏览器和节点中使用,以及一些特定于节点的组件,它们只会 在节点中使用。模块之间会有依赖关系。
如果有更好的方法,那么我也愿意。
【问题讨论】:
-
requirejs("foo") 正在请求已加载到内存中的模块。试试 requirejs(["foo", "bar"], (foo, bar) => { foo() + bar() });
-
@CoreyAlix 根据the requirejs node docs 表示,在节点下,您可以使用
requirejs("foo")同步请求模块。这在包装 AMD 模块以在 Node 中使用时几乎是一个要求,因为 Noderequire()是同步的。 -
bar.js相对于您的其他文件位于何处? -
@Louis 在项目根目录中,如第一张图所示。
-
啊,这对我来说很尴尬。因为当我回答完你的问题时,我一开始就忘记了这一点。
标签: javascript node.js requirejs amd