1

我正在使用一个由“核心”和多个“扩展”组成的外部库。每个扩展都依赖于核心。想想 jQuery 或 Rx。

我需要做的是将核心与一些扩展捆绑在一起,并将其作为单个模块提供。从表面上看,这样的事情似乎应该起作用:

// lib.js
define(
    "lib",
    ["./Lib/lib", "./Lib/ext1", "./Lib/ext2"], 
    function(lib) { return lib; }
);

然而,问题是扩展期望“核心”可以通过“lib”的模块 ID 获得。换句话说,“ext1”是这样定义的:

// Lib/ext1.js
define( ["lib"], function(lib) { lib.ext.someFunc = ... } );

可以在这里发现问题:因为名称“lib”指的是我的“捆绑”模块,而不仅仅是“核心”,它在 ext1 加载时还不可用,所以整个链变得循环并分崩离析。

当然,我可以将核心映射到“lib”,然后给我的捆绑模块一个不同的名称:

// main.js
require.config( { paths: { lib: "Lib/lib" } } );

// lib.js
define(
    "bundled-lib",
    ["./Lib/lib", "./Lib/ext1", "./Lib/ext2"], 
    function(lib) { return lib; }
);

但由于以下几个原因,这种方法非常不可取:

  1. 使用不同的名称很不方便。没有好的常识名称可以代替,“lib”几乎是唯一的选择,其他任何东西都会看起来很难看。

  2. 但更重要的是,这可能会导致难以捕获的错误。以后,当我忘记了这个小技巧时,我可能只是按照我的常识导入“lib”而不是“bundled-lib”,然后我的扩展将不会被加载。或者有时他们会。如果其他正确导入“bundled-lib”的模块恰好在新的“lib”导入模块之前加载,那么它将起作用。否则,它不会。这意味着我的应用程序是否会崩溃取决于是否使用了某些功能。

所以底线是,我想将核心与扩展捆绑在一起,将包称为“lib”,但以某种方式让扩展只导入核心,而不修改扩展本身。

有什么想法吗?

4

2 回答 2

1

这听起来与 jQuery 和 jQuery 插件非常相似。似乎您已经了解其中的含义,因此您只需要决定首选哪种方法。

我不会使用返回“lib”的模块,它已经具有这些扩展。如果您觉得您只需要引用扩展库的单个依赖项,请使用您的“捆绑库”方法。

为了坚持最佳实践并且不让自己在未来感到困惑,我相信最好不要捆绑,但对于那些依赖扩展的模块,包括对核心库和这些扩展的依赖:

  define(['lib', 'ext1'], function(lib){
    // module definition...
  });

这样就非常清楚该模块的依赖项是什么。我相信你已经考虑过了,我只是希望它能帮助你做出决定。

于 2013-06-04T15:45:13.240 回答
0

所以在提出这个问题几个小时后,我自己找到了答案。

答案是——RequireJS 的地图配置
基本上,事实证明,我可以定义每个模块单独看到的模块名称的映射。

特别是,问题中描述的我的问题将通过以下配置解决:

require.config( {
    map: {
        'ext1': { 'lib': 'Lib/lib' }
        'ext2': { 'lib': 'Lib/lib' }
    }
} );

这将使 ext1 和 ext2 都将模块 'Lib/lib' 视为 'lib',而不会影响所有其他模块。

于 2013-06-05T01:33:43.370 回答