I am trying to understand how require js works by building knockout components.I have built 2 separate knockout components for testing. My directory structure is as follows:
- App
|_ Components
|_ Like-Widget
|_like-widget.js
|_like-widget.html
|_ sign-in
|_sign-in.js
|_sing-in.html
|_ startup.js
- Scripts
|_ knockout.js
|_ knockout-es5.js
|_ app.js
I have configured require.js as follows in app.js file
require.config({
paths: {
ko: "/Scripts/knockout-3.4.0",
kox: "/Scripts/knockout-es5",
jquery: "/Scripts/jquery-1.10.2.min",
text: "/Scripts/text"
},
shim: {
"kox": {
deps:["ko"]
}
},
baseUrl: "/App/Components"
});
require(["/App/Components/startup.js"]);
Here is my startup.js file
define(['ko'], function (ko) {
ko.components.register('like-widget', { require: 'like-widget/like-widget' });
ko.components.register('sign-in', { require: 'sign-in/sign-in' });
ko.applyBindings();
});
my like-widget.js and sign-in.js files are almost identical for testing purpose
define(["kox", "text!like-widget/like-widget.html"], function (ko, template) {
function myViewModel(params) {
var self = this;
self.personName = 'Bob';
self.personAge = 23;
ko.track(this);
};
return {
viewModel: myViewModel,
template: template
};
});
define(["kox", "text!sign-in/sign-in.html"], function (ko, template) {
function signInViewModel(params) {
var self = this;
self.userName = 'User 1';
ko.track(this);
};
return {
viewModel: signInViewModel,
template: template
};
});
this is how I am referring to require.js in my html page
<script type='text/javascript' data-main="/Scripts/app.js" src="~/Scripts/require.js"></script>
The problem is that my like-widget component is working fine but as soon as I try to use my sign-in component, I am getting an error
Uncaught Error: Script error for "knockout", needed by: kox http://requirejs.org/docs/errors.html#scripterror
From the error it seems that requirejs is trying to load knockout from incorrect location, my knockout.js is not in components directory but in scripts directory. What I can't understand is how it is correctly loading the like-widget component?
I am new to requirejs so I am assuming I am making some naive mistake, can you please point it out?
If you look at the source code for knockout-es5 plugin you will see that it requires the knockout path to be set to 'knockout', not 'ko'.
} else if (typeof define === 'function' && define.amd) {
define(['knockout'], function(koModule) {
ko = koModule;
attachToKo(koModule);
weakMapFactory = function() { return new global.WeakMap(); };
return koModule;
});
}
If you change your require config path for knockout
require.config({
paths: {
knockout: "/Scripts/knockout-3.4.0",
// instead of ko: "/Scripts/knockout-3.4.0"
}
it should work. You can also remove the shim for knockout-es5 (kox in your example) since it shouldn't be needed.