Use jQuery with RequireJS separately - javascript

I am trying to load and use jQuery, I do not want to use the RequireJs+jQuery bundle because I am not planning to use the latest version.
However it seems the document ready event it is not getting executed,
require.config({
baseUrl: 'js/'
});
require([
"jquery.min",
"jquery.alpha",
"jquery.beta"
], function($) {
console.log('require js okay');
define(['jquery'], function ($) {
$(document).ready(function() {
console.log('jquery has loaded');
$('body').alpha().beta();
});
});
});

jQuery exports itself as a named module. This means you need to add a path to your config options to properly return jQuery as a module.
paths: {
"jquery": "js/jquery,
},

Related

Vibrant.js library not loading

I am trying to use a js library but am having trouble getting it connected.
https://github.com/Vibrant-Colors/node-vibrant
Downloaded vibrant.js using node.
Js file: var Vibrant = require(['node-vibrant']);
Html file (added this so I can ise require above): <script src="https://requirejs.org/docs/release/2.3.6/minified/require.js"></script>
And I am getting these errors:
There are two things here.
First one is that require() function does not return the module you are requiring, it works async. So you would have to provide a callback which will be executed when the module is loaded:
require(['node-vibrant'], () => {
console.log('Vibrant is loaded');
});
Second thing is your web server does not know what is /node-vibrant, you have to provide full path to it. As someone mentioned in comment, you can use CDN:
requirejs.config({
paths: {
'node-vibrant': 'https://cdnjs.cloudflare.com/ajax/libs/vibrant.js/1.0.0/Vibrant.min'
}
});
require(['node-vibrant'], () => {
console.log('Vibrant is loaded, you can do what you want with it');
console.log(window.Vibrant);
});
Third thing, which is optional is to set shim for this script as it is not AMD module. It won't be injected into your callback, but it will be a global variable. This can be fixed:
requirejs.config({
paths: {
'node-vibrant': 'https://cdnjs.cloudflare.com/ajax/libs/vibrant.js/1.0.0/Vibrant.min'
},
shim: {
'node-vibrant': {
'exports': 'Vibrant'
}
}
});
require(['node-vibrant'], (Vibrant) => {
console.log('Vibrant is loaded and injected, you can do what you want with it');
console.log(Vibrant);
});

RequireJS doesn't load JQuery if widget on page has loaded JQuery already

I'm having some trouble with requirejs, jquery and an embeddable widget that I've written. The widget is loaded via a javascript (that contains a minified version of jQuery).
The problem is that the host site is using requirejs and tries to load jquery. Somehow, requirejs seems to think that jquery is already loaded (because of the minified version in the loader script) and skips loading of jquery. It uses the version that is included by the loader script. This will (due to timing issues?) make the loading of bootstrap fail, because it cannot find jquery.
How can I get requirejs on the host site to load jquery anyway? Why is it affected by the version of jquery that is included by my embeddable widget?
The host site with reqiurejs and the script that loads the widget:
<body>
...
<script async="" src="http://example.com/WidgetLoaderScript.js"></script>
...
<script src="/Scripts/require.js"></script>
<script>
requirejs.config({
baseUrl: "../../Scripts",
paths: {
jquery: "jquery-1.10.2.min",
bootstrap: "bootstrap.min"
},
shim: {
bootstrap: {
deps: ["jquery"]
}
}
});
require(["jquery", "bootstrap"], function ($) {
// Do stuff
});
</script>
</body>
Part of the loader script:
(function (window, document, undefined) {
// Load minified version of jQuery
(function(e,t){var n,r,i ......;
var $abc = $.noConflict();
// Use $abc to append widget into host site
...
})(window, document);
Check this
(function () {
var paths = { ... };
//HANDLE JQUERY IF LOADED ALREADY TO AVOID OVERWRITING EXISTING JQUERY PROPERTIES AND PLUGINS
//CHECK FOR OLD VERSIONS OF JQUERY
var oldjQuery = !!(window.jQuery && !!window.jQuery.fn.jquery.match(/^1\.[0-4]/));
//LOAD JQUERY IF NOT AVAILABLE OR BELOW MIN
if (!window.jQuery || oldjQuery) {
paths.jquery = [
'//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min',
//If the CDN location fails, load from this location
'libs/jquery/jquery.min'
];
} else {
//REGISTER THE CURRENT JQUERY
define('jquery', [], function () { return window.jQuery; });
}
//CONFIGURE REQUIRE JS
require.config({
...
paths: paths,
...
});
//START REQUIRE JS
require([
'jquery',
'app'
], function ($, App) {
//HANDLE MULTIPLE JQUERY VERSIONS IF NECESSARY
if (oldjQuery) $.noConflict(true);
//INITIALIZE APP
App.init();
});
})();
Require.js is basically a script loader so why don't you use it to load your widget.
Take a look at the docs in the path fallback section for an example. You will be able to specify a JQuery dependency for your plugin also.
requirejs.config({
paths: {
....(other script definitions).....
'myWidget': 'http://example.com/WidgetLoaderScript'
},
shim: {
'myWidget': ['jquery']
}
});
The problem I had was due to the fact that jQuery registers itself as an AMD module and this will mess with the host site (if it is using an AMD loader like RequireJs). So I don't want jQuery to do that in my widget loader script.
My solution is the following:
// Set define.amd to false while loading jQuery, so that it won't register itself as an AMD module.
var tempDefineAmd = false;
if (typeof define === "function") {
tempDefineAmd = define.amd;
define.amd = false;
}
// Load minified version of jQuery
(function(e,t){var n,r,i ......;
// Done loading jQuery. Restore the value of define.amd for targets sites using an AMD loader
if (typeof define === "function" && tempDefineAmd !== false) {
define.amd = tempDefineAmd;
}

RequireJS jQuery plugin shim not working?

I'm trying to get a jQuery plugin working properly with RequireJS, when using jQuery in the noconflict/noglobal state to force all modules to indicate whether they require jQuery. However, for non-AMD-friendly plugins, the shim config seems to not be working. Namely, if a jQuery plugin is defined with a wrapper like:
(function($) {
$.extend($.myPlugin, { myPlugin: { version:'0.0.1'} });
})(jQuery);
Then the following RequireJS configuration isn't working:
requirejs.config({
paths: {
jquery: ['//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min', 'jquery-min'],
},
map: {
'*': { 'jquery': 'jquery-noglobal' }, // Force all modules to use the non-global jQuery...
'jquery-noglobal': { 'jquery': 'jquery' } // ...except the wrapper module itself, which needs the real one.
},
shim: {
'sadPlugin': {
deps: ['jquery']
}
}
});
jquery-noglobal.js:
define(['jquery'], function(jq) {
return jq.noConflict( true );
});
The error that fires when the plugin code runs is: "can't call extend on undefined", meaning jQuery was never set at the outer level, so $ is undefined inside the self-executing function. I put breakpoints outside the plugin self-executing function, and inside to verify that.
I'm guessing part of the problem is capitalization; the module was written to expect jQuery (camelCase), while the AMD module name is jquery (lower case). Is there any way in the shim config to specify what the injected requirements' variable names should be?
I've also tried adding a sadPlugin: {'jquery':'jquery'} entry to the map hash, hoping to make shim give that module the global jQuery instead of the non-global one, but still jQuery/$ aren't defined by the time the function gets called.
EDIT: Found one kludge that does answer part of the problem: according to the comment found here, the deps of a shim need to be the full file path of the script to load, and cannot be an alias from the paths configuration.
So, since my CDN-fallback file of jQuery is jquery-min.js, if I do:
shim: {
'sadPlugin': {
deps: ['jquery-min']
}
}
The plugin works! However, since the "real" jQuery is now being used, it pollutes the global namespace, and the $ variable is then available without require()ing it, so defeats the whole purpose of the noglobal wrapper...
Just use
return jQuery.noConflict( true );
instead of
return jq.noConflict( true );
So, as local variable inside requirejs, your plugins can use the variable jQuery for the parameter $
(function($) {$.extend($.myPlugin, { myPlugin: { version:'0.0.1'} });})(jQuery);
The config that work for me is:
-- main.js
-- jquery-private.js
In main.js file:
require.config({
paths: {
},
map: {
'*': { 'jquery': 'jquery-private' },
'jquery-private': { 'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js' }
},
shim: {
myplugins: ['jquery']
}
});
In jquery-private.js file:
define(['jquery'], function () {
jQuery = $.noConflict(true);
return jQuery;
});

Unable to load crossroads.js using RequireJS

I try to load JS files using RequireJS , however crossroads http://millermedeiros.github.io/crossroads.js/ seems not be loaded properly. I have checked using Chrome Dev Toolbar and all JS files are actually loaded. However running window.crossroad returned me undefined?
Below is my requirejs config.. Kindly advice... Thanks!
index.html
<script data-main="scripts/config" src="scripts/require.js"></script>
config.js
require.config({
shim: {
"zepto.min": {
exports: "$"
},
"underscore.min": {
exports: "_"
},
"crossroads.min": {
exports: "crossroads"
} }
});
require(["zepto.min","underscore.min", "crossroads.min",], function() {
console.log("=> Loading app")
require(["main"]);
});
main.js
require(["hp-config", "hp-model", "hp-view", "hp-controller"], function () {
console.log("=> Init");
console.log(window.crossroads);
//$(document).ready( function(){ HP.C.init(); });
});
If you look at the code for crossroads, you'll see that it detects that it is in a AMD environment (which RequireJS is) and calls define by itself. So you should remove the shim you have for it. The basic rule is: a library that does not call define needs a shim but a library that calls define does not. The reason window.crossroads is undefined is that crossroads calls define instead of exporting itself in the global space (on window).
Given the require.config call you currently have, the updated call would be:
require.config({
shim: {
"zepto.min": {
exports: "$"
},
"underscore.min": {
exports: "_"
}
}
});
The above config is the minimum change required. However, I would also advise not using .min in the names you pass to require or define. So your config.js could be instead:
require.config({
paths: {
zepto: "zepto.min",
underscore: "underscore.min",
crossroads: "crossroads.min"
},
shim: {
zepto: {
exports: "$"
},
underscore: {
exports: "_"
}
}
});
require(["zepto","underscore", "crossroads",], function() {
console.log("=> Loading app")
require(["main"]);
});
This way, if you want to switch to the non-minified version (for debugging) you can just change the paths setting instead of having to go everywhere you require these modules and change the names.

How to use the domReady requireJS plugin correctly

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($) { }

Categories

Resources