如何扩展使用 AMD 定义的 Javascript 模块?

How can a Javascript module defined with AMD be extended?

首先介绍一下历史,我们有一个引擎,它由许多本质上是模块的 JavaScript 文件组成。这些模块返回分配给全局范围的单个类,尽管在指定的命名空间下。

引擎本身用于显示 eLearning 内容,每个不同的 eLearning 课程需要略有不同的需求,这就是我们根据必要的功能将 javascript 文件包含到页面中的地方。 (只有一个入口页面)。

我一直在权衡是否值得更改为 AMD、require.js 和 r.js,或者是否最好继续使用我们当前的系统,该系统包含页面上所需的所有内容并将其最小化到一个脚本中。

我去 AMD 的最大问题之一是,似乎很难轻松地扩展一个类。例如,有时我们必须稍微调整原始类的行为。因此,我们在页面上添加了另一个脚本包含,通过复制原始原型来扩展原始类,执行被 apply 覆盖的原始函数,然后执行所需的任何附加代码。

你能在不修改原始文件的情况下扩展 AMD 模块吗?还是我错过了重点,我们最好坚持目前正在做的事情?


我最近开始了一个使用RequireJS的项目,我用来扩展下划线的方法归结为这样的:

相关目录结构:

  • /脚本
  • /scripts/underscore.js
  • /scripts/base/underscore.js

真正的下划线库位于 /scripts/base/underscore.js。

我的扩展进入 /scripts/underscore.js.

/scripts/underscore.js 中的代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
define(['./base/underscore'], function (_) {
    'use strict';

    var exports = {};

    // add new underscore methods to exports

    _.mixin(exports); // underscore's method for adding methods to itself

    return _; // return the same object as returned from the underscore module
});

对于一个普通的扩展,它可能看起来更像这样:

1
2
3
4
5
6
7
8
9
10
11
define(['underscore', './base/SomeClass'], function (_, SomeClass) {
    'use strict';

    _.extend(SomeClass.prototype, {
        someMethod: function (someValue) {
            return this.somethingOrOther(someValue * 5);
        }
    });

    return SomeClass;
});

关于下划线的注意事项:在其他地方,我使用了 RequireJS shim-config 来获取下划线以作为 AMD 模块加载,但这对于非填充 AMD 模块的处理应该没有影响。


您可以拥有包含构造函数的模块。当这些模块被包含在内时,它们就可以使用了。然后你可以在之后用它们创建对象。

require 中的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//construction.js
define(function(){

    //expose a constructor function
    return function(){
        this....
    }
});

//then in foo.js
define([construction],function(Construction){
    var newObj = new Construction;  //one object using constructor
});

//then in bar.js
define([construction],function(Construction){

    //play with Construction's prototype here then use it

    var newObj = new Construction;
});