This is my main.aspx
<%--RequireJS--%>
<script data-main="coopjs/app" src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.js"></script>
This is in my app.js
requirejs.config({
"app_name": "coop",
"baseUrl": "coopjs",
"paths": {
"jquery_ui" : "http://code.jquery.com/ui/1.10.2/jquery-ui",
"jquery": "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery",
"coopDragDrop": "../Scripts/coop/coopDragDrop",
"qTip2 ": "http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.js"
}
});
This is again in my main.aspx
(function () {
require(["qTip2"], function () {
alert('hi');
});
})();
It tries to load locally instead of the CDN, throwing the error
GET http://localhost:43122/coopjs/qTip2.js 404 (Not Found)
Any idea?
There's a space in your paths setup for qTip:
"qTip2 ": "http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.js"
Change "qTip2 " to "qTip2". You could even remove the quotes. When do you require you use "qTip2" which does not match "qTip2 ".
There is another problem. RequireJS loads the file pointed to by data-main asynchronously so there is no guarantee that your requirejs.config call will happen before you require qTip2. So move this piece of code into your coopjs/app.js file, after your requirejs.config call:
require(["qTip2"], function () {
alert('hi');
});
Related
I have the following simple structure:
index.html
...
<script src="static/js/lib/require.js" data-main="static/js/main"></script>
</head>
...
static/js/main.js
requirejs.config({
baseUrl: 'static/js',
paths: {
m: 'modules'
}
});
require(['m/test01'], function(test01) {
console.log(test01.print());
});
static/js/modules/test01.js
define(['m/test02'], function(test02){
return {
print: function() {
return 'test01 and '+ test02;
}
};
});
static/js/modules/test02.js
define(function() {
return 'test02';
});
Now when I open index.html directly (file:///index.html) all goes well. The script loading works and "test01 and test02" is logged in the console.
However, if I'm opening via xampp (localhost/requiretest/index.html) the loading of test01.js goes well, but for test02.js I get this error in the console (Firefox):
NetworkError: 404 Not Found - localhost/01-test-grunt/static/js/test02.js
(removed "http://" before localhost for stackoverflow)
As you can see the 'modules/' part is missing in the URL.
Anyone got any idea what might be going on?
NOTE: It does work when I change baseUrl to 'static/js/modules', but I can't do this because of my grunt buildprocess. Anyway, I assume other paths won't be loaded either, so is this a bug or am I doing something wrong?
I am following the tutorial at:
http://javascriptplayground.com/blog/2012/07/requirejs-amd-tutorial-introduction
I am basically making a simple template module that requires "jquery" and "underscore"
Here is my app.js
require.config({
paths: {
"jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min",
"underscore": "http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.3/underscore-min"
}
});
require(['template'], function(template) {
//Template is undefined
console.log(template);
});
Here is my template.js
define(['underscore', 'jquery'], function()
{
var showName = function(n)
{
var temp = _.template("Hello <%= name %>");
$("body").html(temp({name: n}));
};
return
{
showName: showName
};
});
I have verifed that all the scripts are pulling in via google chrome's network tab, but the template callback is NOT defined.
EDIT:
It seems the error is caused by return with { on another line. I have never run into this before with javascript...Is there a rule for this?
EDIT: It seems the error is caused by return with { on another line. I have never run into this before with javascript...Is there a rule for this?
Despite best efforts of certain luminaries to convince gullible newcomers otherwise, semicolons are optional in JavaScript. This has some implication to how return keyword is handled. See the link.
One of the issues with people thinking that semicolons are required is - they think that the parser will continue parsing until it encounters a semi... Gotcha!
I have the following code.
<script src="js/libs/require.js"></script>
<script>
requirejs.config({
baseUrl:'js/modules/',
paths:{
'bbn':'../libs/backbone',
'underscore':'../libs/underscore'
},
shim:{
'bbn':{
exports:'B',
deps:['underscore']
}
}
})
requirejs(['bbn'], function(B){
console.log(B)
});
</script>
The function parameter B is not pointing to Backbone. Instead its getting logged as undefined.
I followed the following post and arrived to this point:
Loading Highcharts via shim using RequireJS and maintaining jQuery dependency
I see both underscore and backbone JavaScript files getting downloaded in firebug.
Underscore is not AMD compat either, so make sure you shim that too:
requirejs.config({
baseUrl:'js/modules/',
paths:{
'bbn':'../libs/backbone',
'underscore':'../libs/underscore'
},
shim:{
'bbn':{
exports:'Backbone',
deps:['underscore']
},
'underscore': {
exports: '_'
}
}
})
requirejs(['bbn'], function(Backbone){
console.log(Backbone)
});
You will see Underscore being downloaded but because it not defined as a proper module RequireJS just treats it as a normal JS file and doesn't get a return value
The latest version of Underscore (~1.6.0 as of writing this) is AMD-compatible. Do not use it as a shim or you may run into issues.
I'm having trouble getting a route to match using crossroads with requirejs. Well, it probably has nothing to do with requirejs, just thought I'd mention it.
This is what my code looks like:
require.config({
shim: {
/* use shims to define dependencies for modules. e.g.,
'jquery.colorize': ['jquery'],
'jquery.scroll': ['jquery'],
*/
'crossroads': ['signals', 'can']
},
paths: {
"jquery": "http://code.jquery.com/jquery-1.8.2",
"can": "/scripts/can/amd/can",
"can.fixture": "/scripts/can/amd/can/util/fixture",
"signals": "/scripts/signals/signals",
"crossroads": "/scripts/crossroads/crossroads"
}
});
require(['jquery', 'crossroads', 'controllers/project'], function ($, crossroads, projectController) {
var projectRoute = crossroads.addRoute('projects', function () {
$(document).ready(function () {
console.log('projects ready');
$.when(ProjectModel.findAll()).then(function (projectResponse) {
var projects = new SortList(projectResponse);
console.log('doc ready projects=', projects);
new ProjectsControl('#projects', {
projects: projects,
defaultSort: 'priority'
});
});
});
})
console.log('matched: ', projectRoute.match(window.location.href));
});
The url that it's trying to match is http://localhost:34382/projects and the output of console.log is "matched: false"
Any suggestions?
I figured out that I need to change what I'm matching on. I've changed this line
console.log('matched: ', projectRoute.match(window.location.href));
to this
console.log('matched: ', projectRoute.match(window.location.pathname + window.location.search));
and now it works.
Also realized that you have to explicitly call crossroads.parse() somewhere for it to work (or am I missing something?)
so at the end of my require function I call this and my route is found
crossroads.parse(window.location.pathname + window.location.search);
Also, in case anyone is wondering, I'm using CanJS as the client-side MVC framework and ASP.NET MVC4 as the server-side.
My project includes the following files:
./index.html
./js/main.js
./js/vendor/require.js
./js/viewmodel/vm.js
The index.html has the following relevant snippet:
<script data-main="js/main.js" src="js/vendor/require.js"></script>
<script type="text/javascript">
require(['viewmodel/vm', 'ko'],
function(viewmodel, ko) {
ko.applyBindings(viewmodel);
}
);
</script>
The js/main.js file is as follows:
var root = this;
define('jquery', ['http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.js'], function () { return root.$; });
define('ko', ['http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.1.0.js'], function (ko) { return ko; });
The js/viewmodel/vm.js file...
define(['jquery', 'ko'],
function($, ko) {
return {
subject: 'world',
greeting: 'hello'
}
}
);
When you open a browser to index.html, then the browser tries to load a file called js/ko.js instead of using the module defined in main.js. It seems like the js file pointed to by the data-main attribute is not guaranteed to run before dependency resolution. This does not seem correct to me since one purpose of the data-main js file is to define require configuration (i.e. path, shim, etc). I am using require v2.1.2.
This works perfectly fine if I copy the contents of my main.js file into the script block in index.html. By "perfectly fine" I mean that it resolved ko to be a module and finds the appropriate CDN link to resolve ko instead of trying to download ./js/ko.js.
to use the data-main attribute for configuring your whole application, it is necessary that it is the single entry point for all your code.
your 2nd script block breaks this requirement by providing a 2nd entry point. since these entry points will resolve independently of each other (and asynchronously), you cannot rely on one to affect the other.
to resolve it, refactor your code in a way that provides a single entry point to your application and do your configuration via this entry point.
That's because requirejs sets the async. Attribute on the script.
The boolean async attribute on script elements allows the external
JavaScript file to run when it's available, without delaying page load
first.
This means that both scripts are loaded and evaluated parallel, so none of the two scripts can access methods or functions from the other one.
If you want to define requirejs variables in one script you mustn't load that script with require js.
For me there are three possibilities how you can solve that problem:
Add the content of main.js to your page (as you mention)
Load the main.js file without requirejs as normal script
Define the require config before loading the scripts (link to requirejs docu )
I had the same problem. The architecture of the site that i was working was components that was loading asynchronous at each part of the page.
Each component has its own html, css, and js code.
So, my solution is to keep a guard function for all the required dependency code, to protect them from running before the main javascript file:
index.html
<head>
<script type="text/javascript">
window.BeforeMainGuard = {
beforeMainLoadedFunctions: [],
hasMainLoaded: false,
guard: function( func ) {
console.assert( typeof func === 'function' );
if( this.hasMainLoaded ) {
func();
}else {
this.beforeMainLoadedFunctions.push( func );
}
},
onMainLoaded: function() {
for( var i = 0; i<this.beforeMainLoadedFunctions.length; ++i ) {
var beforeMainLoadedFunction = this.beforeMainLoadedFunctions[i];
beforeMainLoadedFunction();
}
this.beforeMainLoadedFunctions = null;
this.hasMainLoaded = true;
}
};
</script>
<script data-main="js/main.js" src="js/vendor/require.js"></script>
<script type="text/javascript">
window.BeforeMainGuard.guard( function() {
require(['viewmodel/vm', 'ko'],
function(viewmodel, ko) {
ko.applyBindings(viewmodel);
}
);
});
</script>
</head>
js/main.js
require.config({
// your config
});
require( [ 'AppLogic' ], function( AppLogic ){
AppLogic.Init();
window.BeforeMainGuard.onMainLoaded();
} );