【问题标题】:Using Breeze with RequireJS, Angular is loaded使用 Breeze 和 RequireJS,加载 Angular
【发布时间】:2013-12-09 08:04:58
【问题描述】:

使用 TypeScript、AMD、“requirejs”、“breeze”而不是“angular”,我刚刚从 Breeze 1.4.0 升级到 1.4.6。现在,当“微风”被加载时,它也会尝试加载“角度”,但失败了......

Module name "angular" has not been loaded yet for context: _. 
Use require([]) http://requirejs.org/docs/errors.html#notloaded

问题似乎是由 Breeze 执行以下行引起的。

var ng = core.requireLib("angular");

我做错了什么,所以这段代码还是被执行了?为什么 Breeze 认为必须加载 Angular?

将上面的行替换为以下行时,一切正常。

var ng = undefined;

【问题讨论】:

    标签: angularjs requirejs typescript breeze amd


    【解决方案1】:

    我无法重现此内容。

    确实,由于 Breeze 代码的特殊性,即使 angular 不存在,Breeze 也会执行以下行

    var ng = core.requireLib("angular");
    

    ...这将失败

    Module name "angular" has not been loaded yet for context
    

    因为它找不到名为 angular.js 的库(我假设你没有它)

    但该故障发生在 try/catch 内的另一个函数 (__requireLibCore) 内

    function __requireLibCore(libName) {
        var lib;
        try {
            if (this.window) {
                ...
                if (window.require) {
                    lib = window.require(libName);
                }
                if (lib) return lib;
            }
        } catch(e) {
    
    }
    return lib;
    

    您是否看到引发此错误的其他代码路径?

    2013 年 12 月 11 日更新

    感谢@mgs,您的电子邮件解释了您是如何看到异常的。我为以后阅读本文的人总结一下。

    Breeze 在 v.1.4.6 中开始寻找 AngularJS。非常清楚,Breeze 不需要角度;它只是想知道角度是否可用。 Breeze 也不需要淘汰赛、jQuery 或 Q。但在不同的情况下,它可能会查找这些库并在找到它们时使用它们。

    AFAIK 在 requireJS 中没有其他方法可以检测模块是否已加载然后调用 require("angular")。不幸的是,require("angular") 在找不到该模块时会引发异常。

    Breeze 本身不会失败,因为该调用在 try/catch 中被捕获。许多(大多数?)开发者永远不会看到这个异常。

    但是@mgs 附加了一个requirejs.onError 事件处理程序 ...我赶紧补充一下是一个好习惯。当然,即使 Breeze 捕捉到它并继续前进,他的处理程序也会看到“未找到角度”异常。他写道:

    当 Breeze 尝试加载 Angular 时,会调用“requirejs.onError”函数。在实际程序中,这会导致进入日志,并且警钟正在响起。正是这篇文章让我在 StackOverflow 上提出了这个问题。

    怎么办?我不认为 Breeze 可以做任何事情,除非有人知道如何在不触发 requirejs.onError 事件的情况下检测加载的模块。我认为应该由开发者来补偿。

    我建议教您的处理程序忽略 Breeze 寻找角度的尝试。不要为这种特殊的失败敲响“警钟”。

    或者,您可以定义一个虚拟模块,如@mgs,这样做需要找到一个“角度”模块。我不喜欢这种方法,因为它使 Breeze 误以为 Angular 是可用的,而 Breeze 将来可能会针对这种误解采取行动。今天是无害的,但明天谁知道呢。

    无论如何,谜团已经得到解释,合适的解决方法现在已经知道了。感谢@mgs,让我们有机会探索这个主题。

    2013 年 12 月 12 日更新

    我们刚刚发布了 Breeze v.1.4.7,其中包括您推荐的更改...使用 require.defined 首先检查模块是否已加载。像魅力一样工作。

    我借此机会重写了Todo-Require sample,以便将所有内容都加载到一个 require 脚本行中:

    <!-- Require + main. All scripts retrieved async by requireJS -->
    <script data-main="Scripts/app/main" src="Scripts/require.js"></script>
    

    文档解释了它是如何工作的。

    感谢您的提问和反馈。

    【讨论】:

    • 我又做了一些调试。你说的对。错误在上述函数中引发。但是,对于此处使用的基本库,有一个活动的requirejs.onError 函数。它是报告错误的那个,这让我问了这个问题。如果 Breeze 仅在被告知这样做的情况下才需要 Angular,也许会更好。但是,我有一个解决方法,方法是定义一个虚拟模块 angular,它只返回 undefined
    • 我试过了。但这似乎没有必要。 我的问题...您是如何看到这个异常的?我无法得到它,因为 Breeze 将异常包装在 try/catch 中。你是怎么看到的?
    • P.s.:我有一个请求延迟寻找角度,直到有必要。但我仍然想知道你是如何得到这个错误的,因为寻找角度虽然浪费,但应该是无害的。
    • 我还不知道,为什么我的情况如此特别。但我会准备一些关于场景的信息。如有需要,我将发送一个演示项目。
    • 也许您可以使用 require.defined 和 require.specified 来了解某个模块是否已加载或已知。
    【解决方案2】:

    您可以通过添加以下 typescript 行来强制加载 angularjs:

    /// <amd-dependency path="angular"/>

    或者,您可以在 requirejs 配置中使 breeze 依赖于 angular

    更新如果您不使用 angularjs,您可以安全地将这个文件从您的项目中排除:https://github.com/IdeaBlade/Breeze/blob/master/Breeze.Client/Scripts/IBlade/b00_breeze.ajax.angular.js

    【讨论】:

    • 目前,我不使用角度。我也不想在未来使用 Angular。问题是 Breeze 执行了上面的core.requireLib("angular"),尽管我没有做任何与 Angular 相关的事情。所以问题是:是什么让 Breeze 认为必须加载 Angular?
    • 没有这样的文件。 Breeze Javascript 通过 Nuget Breeze.Client 添加到项目中。现在有breeze.debug.jsbreeze.min.js
    • 您可以安全地从breeze.debug.js 中删除代表该文件的整个部分,然后自己将其缩小
    • 正如我所说,编码var ng = undefined; 使其工作。还将"angular" 定义为返回undefined 的函数使其工作。但这不可能是问题的最终解决方案。 Breeze 不应该在没有任何技巧的情况下开箱即用吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    相关资源
    最近更新 更多