2

我正在创建一个基于 AngularJS、Breeze 和 RequireJS 的单页应用程序。在使用 requirejs 设置 AMD 以与 Angular 和 Breeze 一起使用时,我遇到了 Breeze 对“q”的依赖性的问题。如果“q”的配置规则是小写的,即使“shim”中没有明确的导出,Breeze 也会给出这个错误:

Uncaught Error: Unable to initialize Q. See https://github.com/kriskowal/q
"http://localhost:1498/Scripts/shared/breeze.js"breeze.js:1`

当 require config 将所有引用从“q”更改为“Q”时(即使没有导出),代码也可以工作。有谁知道为什么会这样?

这是工作需要配置:

require.config({
    baseUrl: '../Scripts',
    paths: {
        angular: 'shared/angular',
        bootstrap: 'shared/ui-bootstrap',
        dropdowns: 'app/directives/dropdowns',
        employeeApp: 'app/modules/employeeModule',
        controllers: 'app/controllers',
        dates: 'app/directives/dates',
        jquery: 'shared/jquery',
        Q: 'shared/q',
        breeze: 'shared/breeze',
        config: 'app/services/config',
        model: 'app/services/model',
        dataservice: 'app/services/dataservice',
        expenseInfo: 'app/services/expenseInfo'
    },
    shim: {
        'angular': { 'exports': 'angular' },
        'bootstrap': { deps: ['angular'] },
        //'q': { 'exports': 'q' },
        'breeze': { deps: ['Q', 'jquery'], 'exports': 'breeze' }
    },
    priority: [ 'angular', 'bootstrap', 'dropdowns', 'jquery',
                'Q', 'breeze', 'employeeSearch', 'dates' ]
});
4

2 回答 2

2

技术原因是微风明确寻找“Q”。要找到所有微风,需要在源代码中搜索“requireLib”(不是整个单词)。

Breeze 总是首先寻找全局,因为 q 的全局是 'Q',所以它是 breeze 搜索的

更多背景:( 是的,我最近一直在经历一些 Breeze + RequireJS 的痛苦)

幸运的是,您可以更改 require 路径。但是,对于淘汰赛 + Durandal,这是行不通的。Breeze 需要“ko”,但 Durandal 需要“knockout”。解决方法是使用 RequireJS 映射:

map: {
    //knockout used by Durandal, ko used by breeze  --> anytime ko is requested, substitute knockout
    '*': { 'ko': 'knockout' }
}

Breeze 的 RequireJS 依赖项确实存在一些问题,因为它没有预定义其依赖项(在其定义调用中没有列出依赖项)。这可能是因为它的一些依赖项是可配置的(你不想淘汰,但我愿意)。这就是为什么您需要 shim 以确保在 Breeze 请求它们之前加载它们。

jQuery 具有不寻常的 AMD 行为。大多数库在运行时都会查找 AMD 库。如果他们找到一个 AMD 库(例如 RequireJS),他们会将自己加载到其中(例如 define( ... )),并跳过将自己作为全局加载。如果可以的话, jQuery两者都做(有充分的理由)。这意味着 Breeze 始终可以查看并加载全局 jQuery,因此无需创建从 Breeze 的 'jQuery' 到 RequireJS 的 'jquery' 的映射。

顺便说一句,“即使没有出口”也是无关紧要的。垫片中的导出属性用于: 加载后,使用全局“微风”作为模块值。没有意义,因为轻风看到 RequireJS,将自己加载到其中而不是全局,并且 shim 忽略了导出。

于 2013-09-10T22:28:48.957 回答
0

虽然可以通过 requireJs 加载所有模块,但自从我第一次回答以来,我发现了一些困难,这对我来说太麻烦了。

如果你打算使用 requireJs optomize (rjs) 和 almond 来提供一个带有 almond 缩减的 AMD 加载器的组合 js 文件,那么你会发现一些库有错误。具体来说,我遇到了 Breeze 和 Toastr 的问题。

optomizer 需要显式定义语句,其中显式命名依赖项。Breeze 使用变量依赖名称,因为它发现它需要它们时加载它们 - 因为它的依赖关系是在运行时配置的。

另一个问题是使用 CDN 文件。Almond 不处理任何网络文件,因此必须预先加载它们。jQuery 是主要的 CDN 候选者,但它是许多模块(包括微风)的要求。并且 optomize shim 不能依赖任何 CDN 文件。

我的解决方案

我使用自己的补丁https://github.com/CodeSeven/toastr/issues/135修复了 Toastr 以进行优化。

但由于修复 Breeze 会很麻烦,我又回到通过捆绑预加载它。我还添加了任何我认为可以从 CDN 中受益的库。

我通过 ASP.Net 包加载了轻风(及其先决条件)和 CDN 文件然后在我的 main.js 中的 requirejs.config 之前为 requireJs 定义它们

为了在我的生产代码中使用这些预定义的预加载,我将我的 weyland-config.js 配置为 optomize 为空,例如

                'jquery':               'empty:',
                'knockout':             'empty:',
                'Q':                    'empty:',
                'breeze':               'empty:',

高温高压

于 2013-12-10T06:51:58.253 回答