17

我只是尝试包装我们的一个模块,该模块旨在通过<script>某个样板中的标签包含,以允许使用 requirejs 进行可选的 AMD 加载。

这很痛苦,我能想到的最好的办法是:

(function(){
var exports, jQuery;
if (typeof window.define === 'function' && typeof window.requirejs === 'function') {
    exports     = {};
    define(['jquery'], function (jq) {
        jQuery = jq;
        return thisModule();
    });
} else {
    exports     = window;
    jQuery      = window.jQuery;
    thisModule();
}


function thisModule() {
}

})();

请注意,这是

  • 很多样板
  • 要求您在变量中声明依赖项(幸好在这种情况下只有 jQuery)和 amd
  • 如果我想获得 CommonJs 支持,还需要更多代码。

我主要关心第二点,因为当我超越包装我们的核心文件时,它会变得很糟糕。我确定那里有一些整洁的(呃)包装器实现,但我找不到。

有人有任何提示吗?

4

3 回答 3

8

您试图重新创建已经存在的东西,我做了完全相同的事情,在我的 StackOverflow 问题中提出了一个稍微不同的解决方案。

长话短说,您需要知道的名称是“通用模块定义”,并且有一个位于https://github.com/umdjs/umd的 GitHub,其中包含各种不同的实现。

于 2013-06-28T12:20:42.220 回答
0

在对此进行破解之后,我设法提出了以下内容,这似乎要好得多,甚至可以作为 shim 包含在常规脚本标签中:

几个注意事项和缺点。

  • 您必须将窗口对象上的任何显式设置替换为导出对象
  • 它假定任何依赖项都作为 window 对象上类似命名的属性存在(尽管它也确保将该属性放置在那里)。在我的情况下,这通常足够安全,但您可以轻松破解诸如 requirejs 路径配置之类的东西。
  • 实际上,我不相信整个出口概念是特别必要的,或者至少在所有情况下都不是必要的。
(function () {
    var define, exports = {};
    if (window.define && window.define.amd) {
        define = window.define;
    } else {
        exports = window;
        define = function (name, dependencies, fn) {
            var deps = [];
            for (var i = 0; i < dependencies.length; i++)
                deps.push(window[dependencies[i]]);
            var module = fn.apply(undefined, deps);
            if (!window[name]) window[name] = module;
        };
    }

    define('mylib.interaction', ['jQuery', 'mylib.core', 'jQuery.UI'], function($, mylib) {
        return /*....blah...*/;
    })
})()
于 2013-02-15T19:06:16.067 回答
0

您是要为内部模块还是外部模块执行此操作?

如果您不需要额外的模块,是否可以假设 AMD 构建您的模块,然后在代码中的其他位置填充 define() 函数(如果它不存在)?当然,您必须使用命名模块,但无论如何您基本上都必须这样做......

如果您的模块都从 define() 函数返回它们的导出,那么它会相对简单,并且您的填充定义函数可能看起来像这样:

//Whatever additional guards you want could be added, of course...
if (typeof(window.define) === undefined){
  window.define = function(name, deps, callback){
    window.myNamespace[name] = callback();
  };
}

至少这样你就不必将样板添加到每个模块......

如果您有一个包含许多相互依赖的子模块的大型库,您可能只需要一直使用 Require 或不使用,然后使用您的整个库周围的包装代码来处理 AMD 支持, Jquery 和 Knockout JS 的方式。

于 2013-02-14T16:37:26.647 回答