Javascript BreezeJS和RequireJS未按预期工作

Javascript BreezeJS和RequireJS未按预期工作,javascript,knockout.js,requirejs,amd,breeze,Javascript,Knockout.js,Requirejs,Amd,Breeze,我正在将breezeJS集成到一个已经使用knockoutJS的现有requireJS项目中。我遇到了几个问题 首先,breeze无法加载Q库,除非我将其作为标记包含在html包装中,而不是作为加载的AMD依赖项。在我的项目中,我试图将代码压缩到一个脚本标记,所以这并不理想 第二个问题是breezeJS无法加载淘汰。在我的main.js中,我定义了一个敲除路径: knockout:'../libs/knockout/knockout-2.2.0', (我这样做是因为我喜欢确信我没有访问全局ko)

我正在将breezeJS集成到一个已经使用knockoutJS的现有requireJS项目中。我遇到了几个问题

首先,breeze无法加载Q库,除非我将其作为
标记包含在html包装中,而不是作为加载的AMD依赖项。在我的项目中,我试图将代码压缩到一个脚本标记,所以这并不理想

第二个问题是breezeJS无法加载淘汰。在我的main.js中,我定义了一个敲除路径:

knockout:'../libs/knockout/knockout-2.2.0',

(我这样做是因为我喜欢确信我没有访问全局
ko

然而,当我将breeze添加到我的项目中时,breeze无法加载我的淘汰库。查看breeze代码,我可以看到它已经被硬编码为加载淘汰库
ko

由于不想更改我所有的代码,我发现我可以将AMD加载的敲除库作为
window['ko']
添加到全局窗口对象中。但这感觉像是一个预兆。同样奇怪的是,以这种方式添加Q并删除
标记也不起作用,因为我认为在应用程序生命周期的早期就需要Q,甚至在我污染全局之前——我确实在main.js中嵌套了我的
require()
调用,但这将我的大部分应用程序文件隐藏在构建过程中,所以我放弃了这种方法

我如何在我的项目中包括Q和击倒和微风,并且仍然使用一行
标记,目前我不得不将Q作为一个单独的
标记,并污染全球,以使微风和击倒发挥良好

我在我的项目中使用了很多其他库,其中没有一个像这样难以集成

非常感谢您的帮助

干杯

Gav

编辑:这是我的完整配置:

require.config({
    /**
    * shims are for 3rd party libraries that have not been written in AMD format.
    * shims define AMD modules definitions that get created at runtime.
    */
    shim: {
        'jqueryUI': { deps: ['jquery'] },
        'jqueryAnimateEnhanced': { deps: ['jqueryUI'] },
        'jqueryScrollTo': { deps: ['jquery'] },
        'touchPunch': { deps: ['jquery'] },
        //'Q': { exports: 'Q' },
        //'breeze': { deps: ['Q', 'knockout'], exports: 'breeze' },
        'path': { exports: 'Path' },
        //'signalR': { deps: ['jquery'] },
    },

    paths: {
        //jquery
        jquery: '../libs/jquery/jquery-1.7.2.min',
        'jquery.adapter': '../libs/jquery/jquery.adapter',

        //jquery plugins
        horizontalNav: '../libs/jquery/plugins/horizontalNav/jquery.horizontalNav',
        jqueryUI: '../libs/jquery/plugins/jquery-ui/jquery-ui-1.9.2.custom',
        jqueryAnimateEnhanced: '../libs/jquery/plugins/animate-enhanced/jquery.animate-enhanced',
        touchPunch: '../libs/jquery/plugins/touch-punch/jquery.ui.touch-punch.min',
        //jqueryScrollTo: '../libs/jquery/plugins/jquery-scrollTo/jquery.scrollTo.min',
        //reveal: '../libs/jquery/plugins/reveal/jquery.reveal',
        //opentip: '../libs/jquery/plugins/opentip/opentip-jquery',

        //RequireJS
        domReady: '../libs/require/plugins/domReady',
        text: '../libs/require/plugins/text',
        async: '../libs/require/plugins/async',
        depend: '../libs/require/plugins/depend',
        json: '../libs/require/plugins/json',
        noext: '../libs/require/plugins/noext',

        //coffee-script
        'coffee-script': '../libs/coffee/coffee-script',
        cs: '../libs/require/plugins/cs',

        //Path
        path: '../libs/path/path.min',

        //Knockout
        knockout: '../libs/knockout/knockout-2.2.0',
        knockoutTemplateSource: '../libs/knockout/ko.templateSource',
        knockoutValidation: '../libs/knockout/ko.validation',

        //breeze
        Q: '../libs/breeze/q',
        breeze: '../libs/breeze/breeze.debug',

        //Signals (Observer pattern)
        signals: '../libs/signals/signals',

        //SignalR - Push notifications
        signalR: '../libs/signalR/jquery.signalR-0.5.2.min',

        //utils
        logger: 'common/logging/logger',
        tinycolor: '../libs/tinycolor/tinycolor',
        composing: 'common/composition/composing',

        //app specific
        BaseWidgetViewModel: 'app/view/core/BaseWidgetViewModel',

    }
});

听起来你的require配置不对。你能发布你的require配置的代码吗? 我很好奇:

keep my code down to a single script tag
为什么

编辑:现在我明白了。听起来好像require配置是错误的。

很抱歉(假日)延迟了您的提问

我理解并赞赏您消除除RequireJS之外的所有脚本标记的目标。根据我的经验,这个目标不容易实现

您确实发现了微风缺陷。Breeze内部引用的“require”函数与应用程序的“require”函数不同。它不知道应用程序“require”函数或其配置。因此,当您省略Q脚本标记时,Breeze无法找到Q。。。无论您如何配置应用程序“require”

我们必须解决这个问题。我会在这里添加一条评论

同时,您必须为'Q'和'KO'使用脚本标记,并且必须将这些标记放在RequireJs的脚本标记上方。请继续对应用程序脚本使用require

不幸的是,您还有其他与双需求函数问题无关的问题

首先,我认为将KO排除在全局名称空间之外总是有困难的。。。这和微风无关

在KO的AMD实现中(至少在我上次查看时),KO要么在全局名称空间中,要么在require容器中;决不能两者兼而有之不幸的是,许多有用的插件(bindingHandler、debug.helpers)都假定它位于全局命名空间中;如果使用require加载KO,则无法使用它们

您可以在Require之前加载脚本标记中的Knockout,然后在配置期间将KO填充到Require容器中。您的配置可能如下所示:

define('knockout', [], function () { return window.ko; }); 再次。。。这将是有效的,只有在我们修复我们的错误


约翰·帕帕不得不解决许多类似的问题;你可以看看他在那里做了什么,尤其是在
main.js

这应该在Breeze v1.2.4中修复。我们不再使用“require”的内部实现

我已经添加了我的require配置——其他一切对我来说都很好,但也许我做了一些奇怪的事情?顺便说一句:我想把我的代码压缩到一个标签
,并用RequireJS管理所有脚本间的依赖关系,因为这是它的工作。答案就在后面。我有大部分。缺了一块。敬请关注。感谢您的全面回复。我从来没有意识到requirejspath必须是特定的值,我喜欢将我的路径设置为globals以外的值,以确保我只使用注入的模块,而不使用globals。出于这个原因,我将jquery作为“jquery”而不是“$”,所以我也使用了knockout,选择不将其作为“ko”注入。我在RequireJS google group上问了一个关于AMD和globals的问题,并得到了答案,这与我自己的想法一致,就是手动包装库。我从未遇到过使用requireJS的第三方库以这种方式出现的任何其他问题。我尝试了两个填隙片进行敲除,require.config.shim,并按照您的建议手动填隙到“ko.shim.js”,但都不起作用,因此我已返回将其添加到全局,在breeze之前,我在我的(大型)项目中使用非全局淘汰没有问题。我期待着Q修复,但目前我可以接受在我的html包装中有两个脚本标记。遗憾的是,我不得不实施两种变通方法来使用Breeze,但这将为我的项目增加很多内容,我愿意做出这些妥协。我们听到了。我们会解决这个问题。老实说,这不是一个巨大的优先事项,但我们将在不远的将来实现这一目标。很高兴听到微风价值胜过头痛。我建议你。。。“让breeze与require.js等AMD装载机配合使用”: define('ko', ['knockout'], function (ko) { return ko; });