I'm new at handling imports with require.js, my question is very simple, let' say I have this config.js script for require:
require.config({
paths: {
jquery: 'libs/jquery/jquery',
underscore: 'libs/underscore/underscore',
backbone: 'libs/backbone/backbone'
}
});
and that is the first script I incorporate in my index.html:
<script data-main="config.js" src="require.js"></script>
From this point on can I use jQuery $, underscore _ and so on or should I also import such libraries in my index.html? It is puzzling how sometimes it works sometimes not, so I guess I am not doing it right.
EDIT: I will explain my question a little better here:
1)
<script data-main="config.js" src="require.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<script>
$( "div.bar" )...
//some other jquery
</script>
<script src="..">//some script which uses require</script>
is jQuery loading twice in this page?
2) I have some libraries which needs jQuery to work, can I just add them to the paths in the require config?
You need to require the modules and provide a callback function to use them:
require(['jquery', 'underscore', 'backbone'],
function ($, _, backbone) {
//the modules are all
//loaded and can be used here now.
});
Related
Please, help to combine require.js and jquery CDN together. I have seen a lot of options to do that, but still have a problem with it. After my code below, I have two errors:
JQuery is not found
problem with a script (where define function placed).
I did everything on prescription from http://requirejs.org/ , but still have those problems.
my code:
<script data-main="js/app" src="js/require.js"</script>
app.js
requirejs.config({
'baseUrl': 'js/',
'path': {
'app': 'app',
'jquery': '//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js',
}
});
requirejs(['app/main']);
main.js
define(["jquery"], function ($) {
$(function() {
$('body').text('hi!');
});
});
Help me to remove these errors
I have an application using some third-party libraries as I also have some plug-ins created by myself using jQuery.
The point is: some third-party libraries are using $ and other ones jQuery as naming convention. The way I'm requiring jQuery through RequireJS is just as that:
[...]
var $ = require('jquery');
[...]
This way, I get the following console message as return:
Uncaught ReferenceError: jQuery is not defined jquery.scrolly.js:79
Uncaught TypeError: undefined is not a function
Then, I figured out a candidate solution by creating two variables and requiring jQuery in both:
var $ = require('jquery'),
jQuery = require('jquery');
So, as you can see this "solution" is redundant, unnecessary and unsophisticated — I need something consistent, something better.
Someone can share an idea with me?
Thanks to Daniel A. White, I could use an elegant-way solution called as shim config.
Let's do this step-by-step. My HTML is calling for app.js as require.js wants:
<!DOCTYPE html>
<head>
<!-- ... -->
<script data-main="js/app" src="js/require.js"></script>
</head>
<body>
<!-- ... -->
</body>
</html>
And this is my old js/app.js:
require.config({
baseUrl: 'js',
paths: {
jquery: 'vendor/jquery-2.1.1.min',
modernizr: 'vendor/modernizr-2.6.2.min',
scrolly: 'vendor/jquery.scrolly'
}
});
require(['main']);
Now, here the magic happens — see yourself my new js/app.js:
require.config({
baseUrl: 'js',
paths: {
jquery: 'vendor/jquery-2.1.1.min',
modernizr: 'vendor/modernizr-2.6.2.min',
scrolly: 'vendor/jquery.scrolly'
},
shim: {
'scrolly': {
deps: ['jquery'],
exports: 'scrolly'
}
}
});
require(['main']);
What's the big deal?
The greatness here is the simplicity as RequireJS thinks. As far I could understand, shim config is something like a "dependency manager" for libraries. For example, scrolly is a third-party library dependant of jQuery that have been already loaded — why then should we load it again? There's no need! We just need to inject its usefulness onto scrolly mechanisms that uses jQuery resources.
Another popular example is BackboneJS. Its single hard dependency is UnderscoreJS. To teach Backbone that Underscore is available for use, we supply its dependency through shim config as that:
[...]
shim: {
'backbone': {
deps: ['underscore'],
exports: '_'
}
}
[...]
So, that's it.
I have an add-on to an application (call it appX) that allows users to create their own customizations using javascript, css and appX's webservices api.
Usually customizations are small and do not involve a lot of external libraries/plugins but when they do have external libs the typical users' library of choice is jQuery.
In the next version of appX they are using jQuery natively which I know is going to break some of the customizations.
So I have a need to modularize this situation. I have some other problems that are coming up and RequireJS seems like a good solution to these issues. I just need to figure out how to apply RequireJS properly for this situation
In my POC I'm loading require.js as follows:
<!--A bunch of other script including jQuery (but not require) are loaded already -->
<script type="text/javascript" src="/custom/js/require.js"></script>
<script type="text/javascript" src="/custom/js/dostuff.js"></script>
We'll call the jQuery loaded with appX jqueryx and the one I want to load jqueryp (p for private)
jQuery utilizes AMD and by default uses this definition internally:
define( "jquery", [], function () { return jQuery; } );
But in this case RequireJS is loaded AFTER jQuery (jqueryx) so there will be no default 'jquery' definition correct?
Some more background before I show you my problem... the file structure is like this:
appx
/js:
jqueryx.js
other.js
appx
/custom/js:
jqueryp.js
dostuff.js
Looking at the RequireJS api it seems that I should be doing something like this:
require.config({
baseUrl : 'custom/js',
paths : { 'jquery' : 'jqueryp'},
map: {
'*': { 'jquery': 'jquery-private' },
'jquery-private': { 'jquery': 'jquery' }
}
});
define(['jquery'], function (jq) {
return jq.noConflict( true );
});
require(['jquery'], function(jq){
console.log(jq.fn.jquery);
});
But when I do this I get an error:
Mismatched anonymous define() module: function (jq)...
I've played around with switching references to jquery, jquery-private as it's kind of confusing but with no progress.
How should I be applying RequireJS to this situation?
Almost a year late but better than no answer at all...
The following part should be moved into a "jquery-private.js" file:
define(['jquery'], function (jq) {
return jq.noConflict( true );
});
You can't define a module in your main entry point. Even if you could, the module has no name so how would you reference it?
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>
Here is my main.js before using domReady:
require.config({
paths : {
loader : 'libs/backbone/loader',
jQuery : 'libs/jquery/jquery-module',
Underscore : 'libs/underscore/underscore-module',
Backbone : 'libs/backbone/backbone-module',
templates : '../Templates'
}
});
require([ 'app' ], function(app) {
app.initialize();
});
And app.js:
define([ 'jQuery', 'Underscore', 'Backbone', 'router',
'services/Initializers/MainFrameInitializer',
'services/Initializers/FlowsViewsInitializer',
'services/Initializers/EditModuleInitializer',
'services/Sandboxes/ModulesNavigationSandbox',
'services/Sandboxes/ApplicationStateSandbox', 'DataModel/Constants' ],
function($, _, Backbone, Router, MainFrameInitializer,
FlowsViewsInitializer, EditModuleInitializer, ModulesNavigationSandbox,
ApplicationStateSandbox, Constants) {
var initialize = function() {
// Pass in our Router module and call it's initialize function
MainFrameInitializer.initialize();
FlowsViewsInitializer.initialize();
EditModuleInitializer.initialize();
ApplicationStateSandbox.startCheckStatus();
ModulesNavigationSandbox.navigate(Constants.Modules.Home);
// Router.initialize();
};
return {
initialize : initialize
};
});
All works fine until I optimize the project. I have figured out, that the script starts to run before the DOM is ready, something that was not true before the optimization. Anyway, I wish to use the domReady plugin to make sure the DOM is loaded first.
But, apparently, I have no idea how to do it correctly. Here is the new version of main.js:
require.config({
paths : {
loader : 'libs/backbone/loader',
jQuery : 'libs/jquery/jquery-module',
Underscore : 'libs/underscore/underscore-module',
Backbone : 'libs/backbone/backbone-module',
templates : '../Templates'
}
});
require([ 'domReady', 'app' ], function(domReady, app) {
domReady(app.initialize);
});
Very neat and very wrong, because app is loaded in parallel with domReady before the DOM is ready.
How do I fix it?
Thanks.
EDIT
I think I have understood our problem. The constructor functions of the app dependencies should not run any DOM dependent code. They should just return functions, capturing the DOM dependent logic. That logic should be executed from app.initialize, which is guaranteed to be run when the DOM is ready.
Perhaps I am missing something, but wouldn't you make your life a lot easier by doing:
require(['jQuery', 'app' ], function(jQuery, app) {
jQuery(function ($) {
app.initialize();
});
});
in your main.js?
By requiring the app from inside the domReady callback function, you should be able to require the domReady module, and then the app module synchronously.
define(['require', 'domReady'], function(require, domReady) {
domReady(function() {
require(['app'], function(app) {
app.initialize();
});
});
});
If you follow the doc at: http://requirejs.org/docs/jquery.html, you will be invited to embed a require-jquery library in the head of your document:
<script data-main="main" src="libs/require-jquery.js"></script>
However, if you look at the source for the example, made available on github, you will see that 'require-jquery.js' is generated by simple concatenation of the require lib file and the jquery lib file:
cat require.js jquery.js > ../jquery-require-sample/webapp/scripts/require-jquery.js
That means that you could replace the script embed in the head part with the following script embeds anywhere in your document (for instance at the very bottom of it).
<script src="libs/require.js"></script>
<script src="libs/jquery-1.8.0.js"></script>
<script>require(["main"]);</script>
Because the jquery lib defines itself as a module with:
define( "jquery", [], function () { return jQuery; } );
You can thereafter use jquery as a require reference in any of your script. For instance:
require(["jquery"], function($) { }