如何加载定义全局的JS库并使用RquireJS依赖于另一个第三方库?

时间:2013-04-26 01:04:23

标签: javascript knockout.js requirejs

我正在尝试使用RequireJS加载KnockoutFire,一个KnockoutJS插件。它只有一个文件:https://github.com/hiroshi/knockoutFire/blob/master/knockoutFire.js

插件做了​​两件事:

  1. 定义全局var“KnockoutFire”
  2. 扩展核心KnockoutJS(“ko”)lib
  3. 因此,要正确加载此lib,它需要能够通过全局var“ko”访问KnockoutJS。问题是我正在使用适当的AMD加载KnockoutJS,并且KnockoutFire没有全局“ko”可供参考。我试过填充libs和各种其他技巧来让它工作,但我很难过。一切都会产生错误:

    ReferenceError: ko is not defined
    

    以下是我的工作内容:

    require.config({
        enforceDefine: false,
        baseUrl: 'assets/js/',
        paths: {
            'knockout': '//ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1'
        },
        shim: {
            'knockout': { exports: 'ko' },
            'knockoutfire': { exports: 'KnockoutFire', deps: ['knockout'] }
        },
        waitSeconds : 15
    });
    
    
    require(['knockoutfire'], function() {
        log(KnockoutFire);
    });
    

    我尝试过做奇怪的事情:

    require(['knockout'], function(ko) {
        require(['knockoutfire'], function(kofire, ko) {
            log(KnockoutFire);
        });
    });
    

    或者:

    define(['knockout'], function(ko) {
        require(['knockoutfire'], function(ko) {
            log(KnockoutFire);
        });
    });
    

    如果我下载第三方库并将其添加到其中:

    define(['knockout'], function(ko) {
        <!--- third party lib --->
    });
    
    一切正常。

    有没有办法在不修改第三方库的情况下获得相同的结果?

4 个答案:

答案 0 :(得分:2)

当您需要这些脚本时,请使用订单!插件http://requirejs.org/docs/1.0/docs/api.html#order以确保您在knockoutfire之前加载淘汰赛。即在 您的 文件中:

define('require','exports','order!knockout','order!knockoutfire',
         function(req,exp,knockout,knockoutfire){
            //trimmed 

答案 1 :(得分:2)

我认为仔细研究http://knockoutjs.com/downloads/knockout-2.2.1.debug.js可能会揭示答案。有特殊的AMD处理,我不确定它是否与我尝试过的东西(使用填充和导出)相得益彰。

这个黑客虽然有效。我们基本上用bootstrap模块来控制全局分配。

require.config({
    enforceDefine: false,
    baseUrl: 'assets/js/',
    paths: {
        'jquery': 'http://code.jquery.com/jquery-1.9.1',
        'knockout': 'http://knockoutjs.com/downloads/knockout-2.2.1.debug',
        'knockoutfire': 'https://raw.github.com/hiroshi/knockoutFire/master/knockoutFire'
    },
    waitSeconds: 15
});

define("bootstrap", ['jquery', 'knockout'], function ($, ko) {
    console.log("bootstrap", "jQuery " + $.fn.jquery, ko);
    window.ko = ko;
    var dfd = $.Deferred();
    require(['knockoutfire'], function (kof) {
        dfd.resolve(KnockoutFire);
    });
    return dfd.promise();
});

require(['bootstrap'], function (bootstrap) {
    bootstrap.then(function () {
        console.log("ko", ko, "KnockoutFire", KnockoutFire);
    });
});

输出:

bootstrap jQuery 1.9.1  Object {exportSymbol: function, exportProperty: function, version: "2.2.1", utils: Object, cleanNode: function…}
ko  Object {exportSymbol: function, exportProperty: function, version: "2.2.1", utils: Object, cleanNode: function…}
KnockoutFire  Object {version: "0.0.3", utils: Object, observable: function, mapObservable: function}

Example here

答案 2 :(得分:1)

这个答案的灵感来自@Paul的回答:

define("globalko", ['knockout'], function (ko) {
    window.ko = ko;
});

require(['knockoutfire', 'globalko'], function (kofire) {
    console.log(kofire);
});

这会加载两个lib而不会出错。

有人对KO或KOFire有什么建议让他们的lib更容易与AMD合作吗?

答案 3 :(得分:0)

假设你在knockoufire中有类似的内容

define('require','exports','ko',function(req,exp,ko){
//trimmed 

在knockoutfire之上尝试以下一行:

var ko = ko.ko