javascript 中命名空间对象如何与 AMD 一起使用?

How are namespace objects used alongside AMD in javascript?

为了使我的库更具可移植性,我一直在阅读 AMD 和 CommonJS。我首先注意到的一件事是他们使用目录结构的方式,并且旨在每个文件有一个模块。据我所知,它们的 'namespaces' 与目录树一致。

但是,我自己的代码使用一个全局对象作为命名空间,那么在我的各种文件中,无论目录如何,我都将类添加到这个对象中。

(function (Twifty) {
    // Add objects to the Twifty namespace
    return Twifty;
}(Twifty || {}));

在升级工作中,我试图支持 AMD 和 CommonJs。有很多关于如何做到这一点的文章,但我无法理解 AMD define 函数。下面是我如何转换上面的代码:

(function (root, factory) {

    // Define the namespace if it doesn't exist
    var Twifty = root.Twifty || {};

    'use strict';
    if (typeof define === 'function' && define.amd) {
        // AMD is used - Register as an anonymous module.
        define([], factory);
    } else if (typeof exports === 'object') {
        // CommonJS is used - Twifty is a namespace and doesn't need to be required
        factory(Twifty);
    } else {
        // Neither AMD nor CommonJS used. Use global variables.
        if (!document) {
            throw 'twifty-map requires a DOM object';
        }
        root.Twifty = factory(Twifty);
    }

}(this, function(Twifty) {
    // Add objects to the Twifty namespace
    return Twifty;
}));

问题出在 AMD define 上。工厂需要一个 Twifty 对象,但由于它不是模块,我无法将其添加为依赖项。我该如何处理?

删除命名空间并不可行,因为这会破坏依赖它的任何代码。

如果这是一个微不足道的问题,请提前致歉。

在 AMD 或 CommonJS 上下文中,您的模块不应将变量泄漏到全局 space。

因此必须使用一个策略来拥有一个公共对象(名称space),各种模块可以添加到该公共对象。

你可以有这样一个 twifty.base 模块:

(function (root) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        // AMD 
        define([], {});
    }
    else if (typeof module === "object" && module.exports) {
        // CommonJS
        module.exports = {};
    } 
    else {
        root.Twifty = root.Twifty || {};
    }
}(this));

所有其他模块将取决于 twifty.base:

(function (root, factory) {

    'use strict';
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['twifty.base'], factory);
    }
    else if (typeof module === "object" && module.exports) {
        // CommonJS
        module.exports = factory(require('twifty.base'));
    } 
    else {
        root.Twifty = factory(root.Twifty || {});
    }

}(this, function(Twifty) {
    Twifty.foo = 1;

    Twifty.bar = function () {};

    return Twifty;
}));

在不使用模块的环境中,script 元素可以按任何顺序加载脚本,twifty.base 实际上 不需要 。 (因为 factory(root.Twifty || {})。)在 AMD 或 CommonJS 环境中,由于所有模块都依赖于 twifty.base,并且由于 AMD 和 CommonJS 环境中的模块是单例,因此所有模块都扩展相同的 JavaScript对象。