7

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

首先是微风无法加载 Q 库,除非我将它作为<script>标签包含在我的 html 包装器中,而不是作为加载的 AMD 依赖项。在我的项目中,我试图将我的代码保留为单个脚本标记,所以这并不理想。

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

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

(我这样做是因为我喜欢确定我没有访问 global ko

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

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

我怎样才能在我的项目中包含 Q 和淘汰赛和微风,并且仍然使用单行<script>标签,目前我不得不将 Q 作为单独的<script>标签包含并污染全局以使微风和淘汰赛能够很好地发挥作用。

我在我的项目中使用了很多其他库,但没有一个库那么难集成。

任何帮助深表感谢

干杯

加夫

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

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',

    }
});
4

3 回答 3

3

抱歉(假期)延迟解决您的问题。

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

您确实发现了 Breeze 缺陷。Breeze 在内部引用了与应用程序的“require”函数不同的“require”函数。它不知道应用程序的“需要”功能或其配置。因此,当您省略 Q 脚本标签时,无论您如何配置应用程序 'require',Breeze 都找不到 Q ...。

我们必须解决这个问题。当我们这样做时,我会在这里添加评论。

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

不幸的是,您还有其他与双重需求功能问题无关的问题。

首先,我认为你总是很难将 KO 排除在全局命名空间之外……这与 Breeze 无关。

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

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

define('knockout', [], function () { return window.ko; });

jQuery开发人员意识到这将是一个问题。太多优秀的插件假定 jQuery 位于全局命名空间中。jQuery 维护者(在我看来是正确的)不是纯粹主义者,而是将 jQuery 放在Require 容器全局命名空间中。

其次,许多其他有用的库不支持 Require。您的代码可以像这些脚本是为 require 设计的一样编写。我仍然认为最简单、最清晰的处理方法是在脚本标签中指定它们。define然后,您可以通过使用如上所示的调用定义它们来将它们添加到容器中。通过这种填充,您自己的模块可以一致地依赖 Require 来进行这些库的服务定位和依赖注入。

第三,我认为您的配置中有错误。出于我无法理解的原因,您决定在您的 Require 世界中将 Knockout 模块称为“ knockout ”。

很好......但是当我们修复它以使用应用程序的 require 容器时,您不应该期望 Breeze 会预期该模块名称。Breeze 将在其标准名称“ko”下寻找 KnockoutJs。Breeze 不会在您的首选名称“knockout”下找到它。

这没什么大不了的。如果您喜欢“淘汰”名称,则可以在两个名称下提供相同的实例。我很确定以下 shim 行在添加到您的配置代码时会起作用:

define('ko', ['knockout'], function (ko) { return ko; });

再次......这只有在我们修复了我们的 Breeze 需要错误之后才会有效。

John Papa 必须在 Code Camper中解决许多类似的问题;你可以看看他在那里做了什么,尤其是在main.js.

于 2012-12-29T06:42:52.343 回答
2

这应该从 Breeze v 1.2.4 开始修复。我们不再使用“require”的内部实现。

于 2013-03-18T22:33:34.890 回答
0

听起来您的要求配置不正确。你能发布你需要配置的代码吗?我好奇:

keep my code down to a single script tag

为什么?

编辑:现在我明白了。仍然听起来需要配置是错误的。

于 2012-12-18T17:51:16.077 回答