requirejs 模块包含模块

requirejs module containing modules

我有一个内部使用 AMD 模块 (requirejs) 的库。我想 return 这些模块中的一些方法作为 public API。目前我正在使用同步要求调用来执行此操作。

例如:

// library
define("a", function(){
    define("b", ['somedep','anotherdep'], function(dep, dep2){
        return { something: "x"};
    });

    return {
        b: require('b').something
    };
});



// then to use it.
require(['a'], function(a){
});

然而这给出了错误。 错误:尚未为上下文加载模块名称 "b":_。使用 require([])

我不想在外部公开内部定义调用(通过展平所有定义),因为我不希望库使用者能够使用这些内部模块。

您不能嵌套模块定义。试试这个:

define("b", ['somedep','anotherdep'], function(dep, dep2){
    return { something: "x"};
});

define("a", ['b'], function(b){
    return {
        b: b.something
    };
});

// then to use it.
require(['a'], function(a){
});
// Defined module "b"
define("b", ['somedep','anotherdep'], function(dep, dep2){
    return { something: "x"};
});

// Defined module "a"
define("a", ["b"], function(b){

    return {
        b: b.something
    };
});



// then to use it.
require(['a'], function(a){
});

你可以这样做

I don't want to expose the internal define calls externally (by flattening out all the defines) since i don't want library consumers to be able to use those internal modules.

我不知道有什么简单的方法可以向 RequireJS 声明一个模块,同时防止模块被任何可以调用 RequireJS 的代码使用 require。假设您显示的代码可以工作。然后,一旦模块 a 被加载,模块 b 就可以被任何代码访问。 (这里的"Loaded"表示工厂函数已经执行。)因此,虽然访问b将依赖于首先加载a,但b不会被隐藏。

您的代码不起作用的原因是 RequireJS 的 "synchronous" require 是伪同步的...或者更好的说法是它是伪 require 其中 确实 同步运行,但如果您想要的模块未加载,则会立即退出。同样,这里的 "loaded" 意味着 不仅 对模块的 define 调用已经执行,而且模块自身的依赖项 已经加载 并且模块的工厂函数 已经执行 。在您的代码中,模块 b 的依赖项尚未加载并且 b 的工厂函数尚未执行,因此您的 require 调用失败。

您可以使用 require(['b']) 加载 b,但随后您必须 return 来自 a 的某种承诺。

您基本上可以通过使用作用域但不使 b 成为模块来隐藏模块 b 中的内容:

define("a", ['somedep', 'anotherdep'], function(dep, dep2){
    var b = (function (foo, bar) {
        return { something: "x" };
    })(dep, dep2);

    return {
        b: b.something
    };
});

我们最终更改了项目以使用 es6 模块、bable 和 browserify。这使得一切都同步而不是异步。