我遇到了 RequireJS 的问题。从本质上讲,我无法访问另一个文件中定义的函数。
我需要这样做,因为我想导出一个给定的函数子集,如
define('submodule', [], function() {
let myFunction1 = function(){ return "Hello"; }
let myFunction2 = function(){ return " From"; }
let myFunction3 = function(){ return " Submodule!"; }
return {
myFunction1 : myFunction1,
myFunction2 : myFunction2,
myFunction3 : myFunction3,
};
});
从其他文件访问它们
define('main', ['config', 'sub1', 'sub2', 'submodule'],
function(config, sub1, sub2, submodule) {
//Config
alert(config.conf);
//Submodule
let callSubmodule = function() {
alert(submodule.myFunction1() +
submodule.myFunction2() +
submodule.myFunction3());
}
//sub1
let callSub1 = function() {
alert(sub1.myFunction1());
}
//sub2
let callSub2 = function() {
alert(sub2.myFunction1());
}
});
事实上,我通常可以使用 sub1 和 sub2 ,但是,使用子模块,我根本无法做到。我认为这是由 require.config.js 中的依赖项引起的。
我的 require.config.js :
require(['common'], function () { //contains vendors
require(['config'], function () { //contains a js config file
require(['main'], function () { //main file
require(['sub1', 'sub2'], function () { //some subfiles
require(['submodule']);
});
});
});
});
对于 submodule.myFunction1()以及我得到的两个相关函数:
Uncaught(承诺)TypeError:无法读取未定义的属性'myFunction1'
这很奇怪,因为我能够在其他情况下这样做,我真的不明白为什么会这样。例如,我可以从主文件和其他文件调用 sub1 和 sub2 函数,但特别是子模块。
的index.html
//Taken from Plunker
. . .
<script data-main="common" data-require="require.js@2.1.20" data-semver="2.1.20" src="http://requirejs.org/docs/release/2.1.20/minified/require.js"></script>
<script src="require.config.js"></script>
. . .
<button onclick = "callSubmodule()">Call Submodule</button>
<button onclick = "callSub1()">Call Sub1</button>
<button onclick = "callSub2()">Call Sub2</button>
common.js 包含供应商,这里只是一个例子
requirejs.config({
baseUrl : "",
paths : {
"jquery" : "http://code.jquery.com/jquery-latest.min.js"
}
});
sub1.js
define('sub1', ['submodule'], function(submodule) {
let myFunction1 = function(){ return "called sub1"; }
return {
myFunction1 : myFunction1
};
});
sub2.js
define('sub2', ['submodule'], function(submodule) {
let myFunction1 = function(){ return "called sub2"; }
return {
myFunction1 : myFunction1
};
});
我设置了Plunker with @SergGr help尝试复制应用程序的结构,但所有模块在点击时都未定义。在实际应用中,这不会发生。
我该如何解决这个问题?
答案 0 :(得分:2)
这是你的代码:
define('main', ['submodule'], function(submod) {
console.log(submodule.myFunction());
});
参数列表中有submod
。但是,您然后尝试访问submodule
。请注意,您直接从模块返回函数(return myFunction
),因此您的模块具有函数myFunction
的值,因此模块就是您应该调用的模块。代码应该是:
define('main', ['submodule'], function(submod) {
console.log(submod());
});
答案 1 :(得分:2)
我管理来解决这个问题。本质上,它是由模块之间的循环依赖引起的。因此, a 需要 b 和 b 需要 a 导致其中一个在依赖项解析中未定义。< / p>
我在requirejs module is undefined的@jgillich提供的答案中找到了解决方法。
所以,我设法在主
中解决使用问题define('main', ['config', 'sub1', 'sub2', 'require'],
function(config, sub1, sub2, submodule, require) {
//Config
alert(config.conf);
//Submodule
let callSubmodule = function() {
alert(require('submodule').myFunction1() +
require('submodule').myFunction2() +
require('submodule').myFunction3());
}
});
正如@jgillich所说:
如果你定义一个循环依赖(“a”需要“b”而“b”需要“a”),那么在这种情况下,当调用“b”的模块函数时,它将获得一个未定义的值“一个”。 “b”可以在使用require()方法定义模块之后获取“a”(确保将require指定为依赖项,以便使用正确的上下文查找“a”):
//Inside b.js:
define(["require", "a"],
function(require, a) {
//"a" in this case will be null if "a" also asked for "b",
//a circular dependency.
return function(title) {
return require("a").doSomething();
}
}
);
答案 2 :(得分:2)
您为模块命名的方式我希望它们都来自require配置文件。我不希望requirejs知道如何在没有某种显式编译过程的情况下加载这些文件。我还怀疑你的服务器正在返回一些东西,因为404几乎能够解释而不会爆炸。
您的设置似乎和命名方案似乎很奇怪。如果你有能力从头开始,我的建议就是。
index.html
<script src="/js/config.js" />
<script src="http://requirejs.org/docs/release/2.1.20/minified/require.js" />
<script>
require('/js/main', function(main) {
main({});
});
</script>
/js/config.js
// setting requirejs to an object before its loaded will cause requirejs to use it as the config
window.requirejs = {
baseUrl : "/",
paths : {
"jquery" : "http://code.jquery.com/jquery-latest.min.js"
}
};
/js/main.js
define(function(require) {
const sum = require('./sum');
return (a, b) => sum(a, b);
});
/js/sum.js
define(function(require) {
return (a, b) => a + b;
});
答案 3 :(得分:1)
更新(2017年3月2日)
您的plunker显然无法正常工作,因为您可以直接从HTML调用模块函数。
<button onclick = "callSubmodule()">Call Submodule</button>
<button onclick = "callSub1()">Call Sub1</button>
<button onclick = "callSub2()">Call Sub2</button>
RequireJS无法正常工作。 RequireJS的一个关键目的是提供模块隔离,因此它无法以这种方式工作:想象一下,如果几个不同的模块具有函数callSubmodule
。
据我所知,无法将来自HTML的调用绑定到RequireJS模块中的代码,它应该是另一种方式:模块绑定到HTML。如果您解决了这些问题,那么一切正常,我可以看到fork of your plunker。
<小时/> 旧答案
该错误发生在 subModule.js
中define('submodule', [], function() {
let myFunction = function(){ return "Hello"; }
//return myFunction; // old, wrong
return { myFunction: myFunction };
});
即使您只想返回1个函数,也不应该按原样返回它,您应该将它包装到一个对象中并给它一个明确的名称。
P.S。如果这不是您真正的问题,请提供真实的Minimal, Complete, and Verifiable example