SteveSanderson/knockout — pull request #206 by neonstalwart (2011-11-17 19:52:18+00:00)
Title: amd: register knockout with amd id "ko" if amd loader available

this is in relation to #200

i've made it so that the built version of ko is wrapped in some code that will conditionally register knockout with the module id of `"ko"` if an amd loader is present.

in doing this, i made a few decisions about how to approach this and so here's an overview of what happened and why:

- changed namespace.js to not define `window['ko']` so that this can be done conditionally based on whether or not an amd loader is present. i made the decision not to expose the `ko` global for amd but that's not a requirement for it to work.

- changed `ko.exportSymbol` to export to the ko namespace. when used from source (without the amd wrapper) the namespace is the variable `ko` defined in namespace.js. when built, then the namespace is going to be the `koExports` object defined in the wrapper. for amd, the `koExports` object is the module's `exports` and without amd, `koExports` is `window.ko`. since `ko.exportSymbol` is not part of ko's "public" API i figured that this change was alright since it also made the code a little more DRY and reduced the size.

- i intentionally left out support for CommonJS environments like nodejs. currently, knockout has many references to `window`, `document`, `navigator` which are browser specific globals. i don't know of a compelling reason to have knockout support CommonJS in the browser but if needed, it should be simple enough to change amd-pre.js to something like this:

```js
!function(id, factory){
typeof define === 'function' && define['amd'] ? define(id, ['exports'], factory) :
typeof exports !== 'undefined' ? factory(exports) : factory(window[id] = {});
}('ko', function(koExports){
```

i'm open to any feedback and i'd be happy to try any different approaches you might like to consider.

as a side note, ultimately i'd like to see all js source files in knockout authored as amd modules so that knockout users can be more specific about which parts of knockout they want to use and then they can use their preferred amd build tool to build their app with only the parts of knockout that they have dependencies on.

this would also mean that an effort to make a clearer distinction between which modules need a browser and which don't would be of greater benefit. my hope is that this would make "headless" testing very simple to achieve and allow for testing models and view models (without views) using nodejs.