将JavaScript文件与依赖项连接并将其作为模块输出的最佳方法?

时间:2012-06-07 12:28:24

标签: module concatenation requirejs

我知道这个问题经常出现在类似的变化中,但没有任何解决方案似乎完全符合我的需求。我有以下问题:

在开发中,我使用多个JS文件(每个“对象”一个文件)。这些JS文件在彼此之间有几个依赖关系 - 有些依赖于其他文件,我需要先加载它们。目前我使用RequireJS以正确的顺序加载每个JS文件,因此我为每个文件定义了一个模块。好又花花公子。 但是现在我想把我所有的JS文件连接成一个大的JS文件,它应该是一个模块本身。我使用RequireJS优化器r.js来做到这一点。 我的问题:每个JS文件都连接到一个大的JS文件,但每个对象的模块定义都包含在内。我在一个大文件中没有一个大模块,但在一个大文件中没有多个模块。

之后我尝试使用grunt进行连接,但是它可以正常工作,但忽略了文件的依赖性。它只是按字母顺序连接每个文件,或者我必须在我的gruntfile中硬编码顺序。

我该如何解决这个问题?

正如我的问题的一个例子: 我有以下文件(伪代码):

FileA
- define FileA module
- depends on FileB
- FileA Logic

FileB
- define FileB module
- FileB Logic

我想要这个输出:

LibFile
- define LibFile module
- FileB Logic, FileA Logic

但是我用r.js得到了这个(FileA的模块定义和FileB被复制):

LibFile
- define FileB module
- FileB Logic
- define FileA module
- depends on FileB
- FileA Logic

我用咕噜声(错误的顺序)得到了这个:

LibFile
- FileA Logic
- FileB Logic

也许这些问题有点愚蠢,但我无法用每个人似乎都使用的工具来解决这个问题...... 我也试过了grunt-requirejs插件。但它抛出了几个我无法解决的错误。

谢谢你, PIPO

1 个答案:

答案 0 :(得分:7)

我将把它转移到答案中。这样代码就更清晰了。

我正在通过记忆来做这些事情(因为我现在无法测试),所以有些小事情可能并不完全准确。

当然,这取决于您如何打包模块,但一种方法是将所有较小的模块注册到更大的模块中:

档案A.js

define([], function() {
    // do something
    return A;
});

档案B.js

define(['path/to/A'], function(A){
    // do something with A and more
    return B;
});

然后,将它们打包在一起:

文件mylib.js

define(['path/to/A', 'path/to/B'], function(A, B){
    return {
        A : A,
        B : B
    }
}

然后,您可以将您的构建配置文件指向mylib.js,然后将其合并到一起 一个大文件。它不会是一个全封装模块,但它会有一个条目 引用其他所有内容的模块。然后你可以这样使用它:

require.config({
    paths : {
        'path/to/mylib' : 'real/path/to/mylib/on/server'
    }
});
require(['path/to/mylib'], function(Lib) {
    // do something using Lib.A or Lib.B
}

要注意的一件事是大模块文件的ID。默认情况下 RequireJS build提供的ID与物理路径(来自appDir IIRC)和您相匹配 在加载依赖项时必须匹配。简单地说,如果你的结果 mylib.js文件有一个名为'path/to/mylib'的主模块,你会的 必须匹配并使用相同的ID加载(使用require.config.paths)或玩 地图等(其中一些需要RequireJS 2.0)。

以下是我问你为什么要做“大模块”事情的原因

另外值得注意的是,所有内部较小的模块也会收到与其匹配的ID 物理路径,您可以在使用大包模块时使用这些ID(这样您不仅可以通过Lib.A访问它们)如果已加载mylib.js

require(['path/to/A'], function(A) {
    // do something using A
}