1

I am creating an ASP.NET single-page application, and have a require.js config file that runs on application start, referencing jQuery, Sammy.js, and knockout.js. I have created shims for the three third-party libraries to allow me to access them on a global level:

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");
});

I am able to instantiate my knockout viewmodel and bind it to the page. However, when I try to access the global variable "ko" for knockout to debug in the Chrome Developer console, nothing is defined.

How can I obtain the "ko" object for debugging in Chrome?

miguelarcilla
  • 1,426
  • 1
  • 20
  • 38

2 Answers2

3

First, the configuration you pass to RequireJS is wrong.

priority is a RequireJS 1.x option, not recognized by RequireJS 2.x. shim is a RequireJS 2.x option, not recognized by RequireJS 1.x. Most likely you are running 2.x and priority does nothing.

Also, neither jQuery nor Knockout require shim configurations. If you use a shim with a module that does need it you get undefined behavior. Undefined behavior is just that "undefined". Maybe it works today, maybe it doesn't. Maybe it works today but 3 weeks from now when you add a new library to your project it does not work anymore.

As for getting a global reference to a module goes, you can do what Anish Patel recommended. It will work but I almost never do that. If I'm in the midst of debugging something and I must get a reference to a module, then:

  1. If the module I want was already loaded, then I take advantage of the pseudo-synchronous require that RequireJS offers for CommonJS compatibility and this at the console:

    foo = require('foo')
    
  2. Otherwise, I do:

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

    This is an asynchronous call but I've never had to actually wait for it to complete. You can always add a console.log statement after the assignment if you want to have visual indication that the assignment was done.

I prefer not to go into my code and add a statement to leak the module into the global space, which I may forget to remove later. Even if I were sure I would not forget, it means going into the code, rebuilding the application and reloading the page.

Community
  • 1
  • 1
Louis
  • 146,715
  • 28
  • 274
  • 320
  • Thanks for your feedback Louis. I must admit this is my first time using RequireJS, and I've encountered so many tutorials that I was unable to properly identify the differences between 1.x and 2.x features. – miguelarcilla Jul 03 '15 at 05:45
  • ...At this point, a code review is just what I need :) I tried your suggestion and it solves my needs as well, but would SO allow me to add two correct answers? Technically, both are correct, although one may require "fixing up" before publishing. – miguelarcilla Jul 03 '15 at 05:58
1

You can expose the ko object as a global from your main function like this:

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");
});

Also you might want to check out the framework DurandalJS its a really nice framework that uses requirejs, KnockoutJS and JQuery. It has its own routing capabilities and a nice application lifecycle to work with.

Anish Patel
  • 4,332
  • 1
  • 30
  • 45