RequireJS undefined alias variable - javascript

Because I need important settings from the serverside I am required to put the main file in the HTML file. But my problem now is that the alias files still load, but are not available as variable. (Also not in the app.js file or in other defined files.) So when I do this: (See bottom of the HTML page)
require([
'jquery'
'app'
], function($, App) {
alert($);
App.initialize();
});
The alert will show a undefined variable, but when I look at my loaded files. The jQuery file is loaded. (The same problem with the underscore and backbone variable, but not the app variable, it is a problem with only the aliases.)
Do you know how to solve this problem?
<html>
<head>
<title>Domain.net</title>
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="js/lib/modernizr.js"></script>
<script src="js/lib/require.js"></script>
<script type="text/javascript">
// Require.js allows us to configure shortcut alias
require.config({
baseUrl: "js",
paths: {
jquery: 'lib/jquery',
underscore: 'lib/underscore',
backbone: 'lib/backbone',
templates: '../templates'
}
});
define('config', function() {
return {
/** My serverside config */
}
});
//Load the App
require([
'jquery',
'app'
], function($, App) {
alert($);
App.initialize();
});
</script>

I'm not sure what version of jQuery you are using, but if it is not 1.7 or higher, then it will not support amd by default, which would explain why you get undefined. The best solution in that case would be to update it.
Alternatively, try adding a shim with exports: jQuery to your config:
require.config({
baseUrl: "js",
paths: {
jquery: 'lib/jquery',
underscore: 'lib/underscore',
backbone: 'lib/backbone',
templates: '../templates'
},
shim: {
jquery: {
exports: 'jQuery'
}
}
});
Also note that the way you are setting up your serverside config is prone to a race condition, see this answer.

Related

Require.js keep infinite reloading

I want to minify my requirejs project by r.js -o app.build.js
After finishing it, the result breaks my website.
As the attached clip, you can see the page is keeping reloading itself and the console show the minified module reloaded again and again
https://www.youtube.com/watch?v=CQvWQ28nG1c&feature=youtu.be
Any idea?
<script type="text/javascript" src="http://mysite/js/require.js"
data-main="http://mysite/js/dist/app.out.js" defer async="true">
</script>
buggy page is here
http://www.foolpin.com/review/%E9%BB%83%E5%AE%89
app.build.js
{
name: "app.main.js",
mainConfigFile: 'app.main.js',
out: "dist/app.out.js",
optimize: "uglify2",
preserveLicenseComments: false,
generateSourceMaps: false,
optimizeAllPluginResources: false,
findNestedDependencies: false,
wrap: true,
wrapShim: true,
include: ["./require.js"],
}
app.main.js
requirejs.config({
paths: {
require: './require',
jquery: './vendor/js/jquery-2.1.1.min',
underscore: './vendor/js/underscore-min',
backbone: './vendor/js/backbone-min',
hbs: './vendor/js/hbs/hbs',
handlebars: './vendor/js/handlebars-v4.0.5',
},
hbs: { // optional
helpers: true, // default: true
templateExtension: 'hbs', // default: 'hbs'
partialsUrl: '' // default: ''
},
shim: {
handlebars: {
exports: 'Handlebars'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
underscore: {
exports: '_'
}
},
});
requirejs(["app_config", "app"],function(cfg, App, noop_ahoy){
return App.initialize();
});
update
I have multiple files some files has anoymous function for itself
Will it be the problem?
https://gist.github.com/poc7667/555a754a105a88cde13d
define([
...
"jquery"
],function(
The problem is caused by something that may be an easy mistake to do. When you use RequireJS you always load the bundle with the code that you supplied or something similar:
<script type="text/javascript" src="http://mysite/js/require.js"
data-main="http://mysite/js/dist/app.out.js" defer async="true">
</script>
The point being that you just have src="path/to/require.js and data-main="path/to/bundle.js". This is important.
Your mistake was including RequireJS in the bundle, and changing the script tag to something like
<script type="text/javascript" src="http://mysite/js/bundle.js"
data-main="http://mysite/js/bundle.js" defer async="true">
</script>
By some glitch in the Matrix, this causes a recursive loading of the same script over and over again, because somewhere inside bundle.js you require require, and it fetches bundle.js again and everything goes wild. That's the only thing I can think of. Your page as it stands now doesn't seem to use the bundled script anymore, so I can't verify this.
The solution is to not include RequireJS itself in the bundle. It's all there in the documentation.

What does requirejs.config() do?

I am having trouble understanding about requirejs.config() function.
requirejs.config({
paths: {
'text': '../lib/require/text',
'durandal':'../lib/durandal/js',
'plugins' : '../lib/durandal/js/plugins',
'transitions' : '../lib/durandal/js/transitions',
'knockout': '../lib/knockout/knockout-3.1.0',
'bootstrap': '../lib/bootstrap/js/bootstrap',
'jquery': '../lib/jquery/jquery-1.9.1'
},
shim: {
'bootstrap': {
deps: ['jquery'],
exports: 'jQuery'
}
}
});
What does the function do? Please do not direct me to the documentation because I have read it and still found it confusing. I need a simple explanation on what this function does.
Are these scripts loaded asynchronously?
It creates aliases for script paths ant tells how to interpret bootstrap (non-AMD script) when loaded. Nothing is loaded yet. You have to require:
// we load two dependencies here
// `knockout` and `bootstrap` are expanded to values in config
// .js added to values
// callback function called when all dependencies are loaded
require(['knockout', 'bootstap'], function(Knockout, $) {
// jQuery is passed to this function as a second parameter
// as defined in shim config exports
});
The path is like declarations/definitions. So for example,
jquery: '../bower_components/jquery/dist/jquery',
you can later load this lib as follows.
define([
'jquery'
], function (jquery) {
//initialize or do something with jquery
}
You don't have to specify the absolute path of the library.
In shim, you will define dependencies. So for example,
paths: {
template: '../templates',
text: '../bower_components/requirejs-text/text',
jquery: '../bower_components/jquery/dist/jquery',
backbone: '../bower_components/backbone/backbone',
underscore: '../bower_components/underscore/underscore',
Router: 'routes/router'
},
shim: {
'backbone': ['underscore', 'jquery'],
'App': ['backbone']
}
Here backbone is dependent on underscore and jquery. So those two libs will be loaded before backbone starts loading. Similarly App will be loaded after backbone is loaded.
You might find this repo useful if you are familiar with backbone and express.
https://github.com/sohel-rana/backbone-express-boilerplate

load javascript file before onload with requirejs

I would like to use requireJS. However, I have a lib that needs to be loaded before the DOM. However, this is not what happens with requireJS
<html>
<head>
<script data-main="/app" src="/require.js"></script>
</head>
<body>
<bar-foo/>
</body>
</html>
With app.js
require.config({
paths: {
'customElement': '/customElement',
'barfoo': '/barfoo'
},
shim: {
barfoo: {
deps: [ 'customElement' ]
}
}
});
define(['barfoo'], function() {
....
}
For example, if I simply load this script directly in the head (without requireJS) it works fine. Is there a require-config-option so I can load a specific file immediately (synchronously?) ?
Requirejs is known for it's asynchronous power. However when you need some sort of an order in which you want files to be loaded due to dependencies, in require.config there is a shim config:
shim: Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.
So let's say you have a backbone app that depends on Underscore and jQuery, and you want them to load in that order then your would:
require.config({
paths: {
'Backbone': '/Backbone',
'Underscore': '/Underscore',
'jQuery': '/jQuery'
},
shim: {
'Backbone': [ 'Underscore', 'jQuery' ]
}
});
require(['Backbone'], function(Backbone){
//.....
});
So, RequireJS allows us to use the shim config to define the sequence of files which need to be loaded in correct order.

Angular + Requirejs - Loading in the wrong order

I'm trying to have angular and jquery loaded with requirejs. The best I can do is that 50% of the time everything loads correctly, the other half I get the error No Module: mainApp
I'm assuming this is breaking half the time based on the speed on which requirejs is asynchronously loading the scripts.
When it works, I see the "Hello World" test (although I do see {{text}} flash before it is replaced, but I've been reading how to fix that here). The rest of the time I get the error and {{text}} just stays on the screen.
Github Repo
Tree:
index.html
- js
- libs
require.js
- modules
mainApp.js
main.js
main.js
require.config({
paths: {
'jQuery': '//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min',
'angular': '//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular',
},
shim: {
'angular' : {'exports' : 'angular'},
'jQuery': {'exports' : 'jQuery'}
}
});
require(['jQuery', 'angular', 'modules/mainApp'] , function ($, angular, mainApp) {
$(function () { // using jQuery because it will run this even if DOM load already happened
angular.bootstrap(document, ['mainApp']);
});
});
modules/mainApp.js
define(['angular'], function (angular) {
return angular.module('mainApp' , []).controller('MainCtrl', ['$scope', function ($scope) {
$scope.text = 'Hello World';
}]);
});
Relevant index.html
<head>
<script src="js/libs/require.js" data-main="js/main"></script>
</head>
<body>
<div ng-app="mainApp">
<div ng-controller="MainCtrl">
{{text}}
</div>
</div>
</body>
You can use domReady (UPDATED) to make sure that the DOM is fully loaded, i.e. all JS files are there, before bootstrapping your application.
requirejs.config({
paths: {
jquery: '/path/to/jquery',
angular: 'path/to/angular',
domReady: '/path/tp/domReady'
}, shim: {
angular: {
exports: 'angular'
},
}
});
define(['jquery', 'angular', 'modules/mainApp'],
function($, angular, 'mainApp') {
// tell angular to wait until the DOM is ready
// before bootstrapping the application
require(['domReady'], function() {
angular.bootstrap(document, ['mainApp']);
});
});
See the RequireJS official documentation for more information on this gotcha:
It is possible when using RequireJS to load scripts quickly enough
that they complete before the DOM is ready. Any work that tries to
interact with the DOM should wait for the DOM to be ready.
The trick is found on this blog post.
EDIT If you follow the blog post's advice, please use this domReady script instead of the one I previously posted: https://github.com/requirejs/domReady/blob/master/domReady.js.
Add Jquery as a dependency for Angular in the shim.
require.config({
paths: {
'jQuery': '//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min',
'angular': '//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular',
},
shim: {
'angular' : {'exports' : 'angular', deps: ['jQuery']},
'jQuery': {'exports' : 'jQuery'}
}
});
This might be a late response but as Dustin Blake said, you can also use jQuery .ready() instead of including another module like domReady.
requirejs.config({
paths: {
jquery: '/path/to/jquery',
angular: 'path/to/angular'
}, shim: {
angular: {
exports: 'angular'
},
}
});
require(['jquery'], function($) {
$(document).ready(function(){
// I like it this way instead of including
// everything in the parent function so it's easier to read
require(['angular', "modules/mainApp"], function(){
angular.bootstrap(document, ['mainApp']);
})
})
});

RequireJS and common config

Is possible to have requirejs config at one place and reuse it in modules?
such as
main.js:
requirejs.config({
baseUrl: "static/js",
paths: {
"jquery": "http://code.jquery.com/jquery-1.9.1.js",
"jquery-ui": "http://code.jquery.com/ui/1.10.2/jquery-ui.js"
},
shim: {
"jquery-ui": {
deps: ["jquery"]
}
}
});
and
public.js:
define(["main", "jquery", function(main, $) {
// do some public stuff
});
client.js:
define(["main", "jquery", function(main, $) {
// do some client stuff
});
And on my public part of web have
<script type="..." src="js/require.js" data-main="js/public.js"></script>
And on client part of web
<script type="..." src="js/require.js" data-main="js/client.js"></script>
And also I would like to have a module for each page. So for example to have a index module on public
<script ...>
require('public/index');
</script>
and
public/index.js:
define(["jquery", "slideshow"], function($, s) {
$( function() { s.init() } );
});
Is that possible with RequireJS?
Thank you for answers.
data-main is a useful shortcut in the very simple case but I don't find it terribly useful beyond that, the solution is to dump it entirely.
Load your main explicitly on each page, then use the callback to load your view-specific scripts.
So you have in public.html:
<script src="/Scripts/require.js"></script>
<script>
require('main', function(){
require('public');
})
</script>
and in client.html:
<script src="/Scripts/require.js"></script>
<script>
require('main', function(){
require('client');
})
</script>
I've written a blog post expounding on this idea here.
I edit my answer as you make the question clearer.
In any page you include require.js, you should also include main.js to define your RequireJS config.
You can't do things like
define(["main", "jquery", function(main, $) {
// do some public stuff
});
because ReuiqreJS load dependencies asynchronously. Although "main" is placed before "jquery", it's not guaranteed RequireJS will load them in that sequence.
So your public/index.html can be like:
<script type="..." src="js/require.js"></script>
<script type="..." src="js/main.js"></script>
<script ...>
require('public/index');
</script>

Categories

Resources