2013-06-04 72 views
1

我正在使用由“核心”和多个“扩展”组成的外部库。每个扩展都取决于核心。认为jQuery或Rx。RequireJS:带插件的捆绑模块

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

// 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”,但不知何故,有扩展只导入为核心,而不是修改扩展自己。

任何想法的人?

回答

0

因此,在提问后几小时,我自己找到了答案。

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

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

这将使EXT1和EXT2见模块“库/ lib目录”为“LIB”:

特别,因为它的问题是描述我的问题,将通过以下结构解决,而不会影响所有其他模块。

1

这听起来非常类似于jQuery和jQuery插件。似乎你对这些含义有所了解,所以你只需要决定哪种方法是首选。

我不会去一个返回'lib'的模块,它已经有了这些扩展。如果您觉得您只需要引用扩展库的单一依赖关系,那么就使用“捆绑库”方法即可。

坚持使用最佳实践,而不是混淆自己在将来,我相信这将是最好不要捆绑,但对于那些你依靠的扩展,包括依赖于自己的核心的lib模块和这些扩展:

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

这样很清楚这个模块的依赖关系是什么。我相信你会想到它,我只希望它能帮助你做出决定。

+0

如果我忘记在路上的某个模块中忘记包含“ext”依赖项,会发生什么?这些代码有时会起作用,有时甚至不起作用 - 这取决于确切的使用场景,而且很难赶上。我非常想保护这一点。 –

+0

如何忘记在模块中包含依赖项?当你开发它时它必须工作。其他相关代码将加载它自己的依赖关系。 –

+0

我可以忘记包含它,因为它实际上并未在我的代码中引用。考虑这个:'require(['jQuery','jQueryUI'],函数($,jqui){...})'。虽然我可以使用jQueryUI提供的扩展,但我从不参考'jqui'参数本身。因此,如果我忘记包含它,我的代码仍然有效,浏览器不会投诉,也不会有类似JSLint或TypeScript的工具。当我在浏览器中加载它进行测试时,它很可能会正常工作,因为其他一些模块可能已经加载了jQueryUI。 –