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

Pip*_*ipo 9 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
Run Code Online (Sandbox Code Playgroud)

我想要这个输出:

LibFile
- define LibFile module
- FileB Logic, FileA Logic
Run Code Online (Sandbox Code Playgroud)

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

LibFile
- define FileB module
- FileB Logic
- define FileA module
- depends on FileB
- FileA Logic
Run Code Online (Sandbox Code Playgroud)

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

LibFile
- FileA Logic
- FileB Logic
Run Code Online (Sandbox Code Playgroud)

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

谢谢,Pipo

Zen*_*ter 7

我将把它转化为答案.这样代码就更清晰了.

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

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

档案A.js

define([], function() {
    // do something
    return A;
});
Run Code Online (Sandbox Code Playgroud)

档案B.js

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

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

文件mylib.js

define(['path/to/A', 'path/to/B'], function(A, B){
    return {
        A : A,
        B : B
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将构建配置文件指向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
}
Run Code Online (Sandbox Code Playgroud)

要注意的一件事是你的大模块文件的ID.默认情况下,RequireJS构建提供与物理路径匹配的ID(来自appDirIIRC),您必须在加载依赖项时匹配该ID .简单地说,如果您生成的 mylib.js文件有一个接收名称的主模块'path/to/mylib',您将必须匹配它并使用相同的ID(使用require.config.paths)加载它或使用地图等(其中一些需要RequireJS 2.0).

以下是我问你为什么要做"大模块"的原因

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

require(['path/to/A'], function(A) {
    // do something using A
}
Run Code Online (Sandbox Code Playgroud)