在 Chrome 开发者控制台中从 Require.js 访问全局变量

Access global variables from Require.js in the Chrome Developer Console

我正在创建一个 ASP.NET 单页应用程序,并且有一个在应用程序启动时运行的 require.js 配置文件,引用 jQuery、Sammy.js 和 knockout.js。我已经为三个第三方库创建了垫片以允许我在全球范围内访问它们:

require.config({
    paths: {
        "jquery": "/Scripts/jquery-2.1.4.min",
        "sammy": "/Scripts/sammy-0.7.5.min",
        "knockout": "/Scripts/knockout-3.3.0",
        "text": "/Scripts/text",
        "appVm": "/Scripts/app/appViewModel"
    },
    shim: {
        "jquery": {
            exports: "$"
        },
        "sammy": {
            deps: ["jquery"],
            exports: "Sammy"
        },
        "knockout": {
            deps: ["jquery"],
            exports: "ko"
        }
    },
    priority: ["text", "app"],
});

define(["knockout", "appVm", "sammy"], function(ko, appVm, sammy) {
    var vm = new appVm();
    ko.applyBindings(vm);

    var app = sammy(function() {
        this.get("#Dashboard", function() {
            //Dashboard-related logic here
        });
    });
    app.run("#Dashboard");
});

我能够实例化我的 knockout viewmodel 并将其绑定到页面。但是,当我尝试访问全局变量 "ko" 以在 Chrome 开发人员控制台中进行调试时,没有任何定义。

如何获取 "ko" 对象以在 Chrome 中进行调试?

您可以像这样在主函数中将 ko 对象公开为全局对象:

define(["knockout", "appVm", "sammy"], function(ko, appVm, sammy) {
    // expose ko as global
    window.ko = ko;

    var vm = new appVm();
    ko.applyBindings(vm);

    var app = sammy(function() {
        this.get("#Dashboard", function() {
            //Dashboard-related logic here
        });
    });
    app.run("#Dashboard");
});

您可能还想查看框架 DurandalJS 它是一个使用 requirejs、KnockoutJS 和 JQuery 的非常好的框架。它有自己的路由功能和良好的应用程序生命周期。

首先,你传给RequireJS的配置是错误的。

priority 是 RequireJS 1.x 选项,RequireJS 2.x 无法识别。 shim 是一个 RequireJS 2.x 选项,RequireJS 1.x 无法识别。很可能你是 运行 2.x 而 priority 什么都不做。

此外,jQuery 和 Knockout 都不需要 shim 配置。如果将 shim 与确实需要它的模块一起使用,则会出现未定义的行为。未定义的行为就是 "undefined"。也许今天有效,也许无效。也许它今天可以工作,但 3 周后当您将新库添加到您的项目时它就不再工作了。

至于获取模块的全局引用,您可以按照 的建议进行操作。它 工作,但我几乎从不这样做。如果我正在调试某些东西并且我必须获得对模块的引用,那么:

  1. 如果我想要的模块已经加载,那么我会利用 RequireJS 为 CommonJS 兼容性提供的伪同步 require 以及控制台上的这个:

    foo = require('foo')
    
  2. 否则,我做:

    require(['foo'], function (foo_) { foo = foo_; });
    

    这是一个异步调用,但我从来没有真正等待它完成。如果您希望视觉指示作业已完成,您始终可以在作业后添加 console.log 语句。

我不想进入我的代码并添加一条语句将模块泄漏到全局 space,我可能会忘记稍后删除。即使我确定我不会忘记,这也意味着进入代码,重建应用程序并重新加载页面。