RequireJS:绑定插件模块

RequireJS: bundling module with plugins

本文关键字:模块 插件 绑定 RequireJS      更新时间:2023-09-26

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

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

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

然而,问题是扩展期望"core"通过"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. 但更重要的是,这可能会导致难以捕获的bug。以后,当我完全忘记了这个小技巧时,我可能只是遵循我的常识,导入"lib"而不是"bundle -lib",然后我的扩展将无法加载。或者有时他们会。如果正确导入"bundle -lib"的其他模块恰好在新的导入"lib"的模块之前加载,那么它将工作。否则,它不会。这意味着我的应用程序要么崩溃,要么不取决于某些功能是否被使用。

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

有什么想法吗?

这听起来很像jQuery和jQuery插件。看来你已经理解了其中的含义,所以你只需要决定哪种方法是首选。

我不会使用返回'lib'的模块,它已经具有这些扩展名。如果你觉得在引用扩展库时只需要一个依赖,那就使用你的"bundle -lib"方法。

为了坚持最佳实践,在将来不要混淆自己,我认为最好不要捆绑,但对于那些依赖扩展的模块,包括对核心库和那些扩展的依赖:

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

这样就非常清楚这个模块的依赖关系是什么。我相信你想过了,我只是希望它能帮助你做决定。

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

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

具体来说,问题中描述的我的问题可以通过以下配置来解决:

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

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