Load prototype enhancements with require.js - javascript

I am using require.js to load my modules which generally works fine. Nevertheless, I do have two additonal questions:
1) If you have a module that is like a helper class and defines additional methods for existing prototypes (such as String.isNullOrEmpty), how would you include them? You want to avoid using the reference to the module.
2) What needs to be changed to use jQuery, too. I understand that jQuery needs to be required but do I also need to pass on $?
Thanks!

1) If you have a module that is like a helper class and defines
additional methods for existing prototypes (such as
String.isNullOrEmpty), how would you include them? You want to avoid
using the reference to the module.
If you need to extend prototypes then just don't return a value and use it as your last argument to require:
// helpers/string.js
define(function() {
String.prototype.isNullOrEmpty = function() {
//
}
});
// main.js
require(['moduleA', 'helpers/string'], function(moduleA) {
});
2) What needs to be changed to use jQuery, too. I understand that
jQuery needs to be required but do I also need to pass on $?
The only requirement for jQuery is that you configure the path correct
require.config({
paths: {
jquery: 'path/to/jquery'
}
});
require(['jquery', 'moduleB'], function($, moduleB) {
// Use $.whatever
});
In my opinion it's unnecessary to use the version of RequireJS that has jQuery built into it as this was primarily used when jQuery didn't support AMD.
Nowadays it does and keeping it separate allows you to swap another library out easily (think Zepto).

2/ For jquery it's really simple :
require(["jquery", "jquery.alpha", "jquery.beta"], function($) {
//the jquery.alpha.js and jquery.beta.js plugins have been loaded.
$(function() {
$('body').alpha().beta();
});
});
More information on require site : http://requirejs.org/docs/jquery.html#get
1/ in my devs for such extension I did it in a global file without require module code.... and I include it in my app with require... not perfect, but it's work fine
global.js
myglobalvar ="";
(...other global stuff...)
myapp.js
// Filename: app.js
define([
(...)
'metrix.globals'
], function(.....){
myApp = {
(...)

Related

RequireJs - why is Jquery injected and JSZip is not?

I'm trying to understand how requireJs works, could somebody please explain to me, why in the following example:
http://plnkr.co/edit/HEDc8F19wICMy0zeGWpH?p=preview
More specifically here:
require(['ble'], function () {
$('#someDiv').html(Ble.A());//This works fine
var zip = new JSZip();//This fails with JSZip is not defined
console.log(zip);
});
Jquery is defined, but JSZip is not? I also tried other combinations, but only one that seems to work is when I manually specify jszip in require array like this:
require(['jszip','ble'], function (JSZip) {
$('#someDiv').html(Ble.A());
var zip = new JSZip();
console.log(zip);
});
I know that documentation states:
The shim config only sets up code relationships. To load modules that
are part of or use shim config, a normal require/define call is
needed. Setting shim by itself does not trigger code to load.
But then - is jquery some kind of "special case" and I should normally, inject my dependencies manually even if they are specified in shim config section?
ASWER:
So it turns out jQuery is indeed a special case, and normally a manual injection of dependencies is required...
If you look in the source code of jQuery you will find the following:
// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.
// Note that for maximum portability, libraries that are not jQuery should
// declare themselves as anonymous modules, and avoid setting a global if an
// AMD loader is present. jQuery is a special case. For more information, see
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
});
}
This means that jQuery will - when required - define itself as jquery.
require(['jszip','ble'], function (JSZip) {
In this above statement, it imports the jszip and returns a object as JSZip.
var zip = new JSZip();
Here that object is used. So with this code you did not get error.
Thus, For jszip, just require is not enough.

Restore original lodash method overwritten by mixin?

We're using the lodash-contrib package, which includes a camelCase method that behaves differently than the original _.camelCase method.
Is there any way for me to restore the pointer to the original method?
In the requirejs config, we have a shim:
lodashContrib: ['lodash']
As soon as lodashContrib has loaded, it's added mixins to lodash. An example of our code:
define([
'lodashContrib'
], function() {
// our code here. At this point, _.camelCase is overridden by contrib
});
Create a file lodashCustom.js or something you can add to your requirejs configuration, and put the following inside it, then wherever you require lodashContrib you can require this instead:
define(['lodash', 'lodashContrib'], function(_, _c) {
_c.camelCase = _.camelCase;
return _c;
});
Assuming your shim implementation doesn't rely on globals, this should hopefully work fine.

How to include anonymous functions into RequireJS dependencies?

I am starting to use RequireJS now and I was already able to add my project dependencies but I still cannot add a jQuery anonymous function yet.
For example, with my normal_file.js I do something like:
normal_file.js:
define(['dependency1'], function(Dependency) {
var Test1 = ...;
return Test1;
});
Bu from a file that has no module, like the example below, I don't know how to encapsulate it:
lib_file.js:
(function ($) {
// Do stuff...
})(window.jQuery);
the lib_file was not made by me and I'm not sure on how it really works, but I would gess it is an anonymous auto-executed function, is that so?.
Anyway, my goal is to use both files in my main code, like below:
main.js:
requirejs.config({
baseUrl:'/static/editorial/js/',
paths: {
jquery: 'third_party/jquery-1.10.2',
react: 'third_party/react-with-addons'
}
});
var dependencies = [
'third_party/react-with-addons',
'third_party/jquery-1.10.2',
'build/utils/normal_file,
'third_party/lib_file
];
require(dependencies, function(React, $, Test1, ??) {
// do my stuff
});
How should I encapsulate that anonymous function in order to add it as a dependency to my main file?
From the RequireJS docs:
Ideally the scripts you load will be modules that are defined by
calling define(). However, you may need to use some traditional/legacy
"browser globals" scripts that do not express their dependencies via
define(). For those, you can use the shim config. To properly express
their dependencies.
Read this: http://requirejs.org/docs/api.html#config-shim
It has a really good explanation of what you have to do, and gives a nice example.
Basically, you just need to set up a shim config for lib_file.js so Require knows to load the right dependencies before giving you access to that script.

How does AMD (require.js) handle multiple classes in a single non-amd js file?

I'm using a bunch of components from the MootoolsMore library which are all compiled into a single .js file. Is there a way to define the library once in the shim and have access to all the class with in it? The following doesn't work, but how would I do something like this?
shim:{
mootoolsMore:{
deps : ["mootools"]
exports : ["Slider", "Sortables"]
}
}
// then inside my module I could access the Slider component like so
define( function(require) {
var Slider = require('mootoolsMore').Slider
There is no need for "shim" functionality that is specific to RequireJS only. You can just use standard AMD loader API:
require(['js!path/to/MooToolsCore.js'], function(){
// nesting in order to insure that Moo Core runs first
require(['js!path/to/MooToolsMore.js'], function(){
// Your Slider and Sortables will be in global.
// just use them.
window.Slider(/* ... */)
})
})
Note, RequireJS does not need "js!" plugin to be declared explicitly, but, instead, just looks at the extension of the file. If it's ".js" it runs the file through "js" plugin. This is NON-standard behavior (as in not in AMD spec), but on RequireJS you should be able to replace line like:
['js!path/to/MooToolsMore.js']
with this:
['path/to/MooToolsMore.js']

require.js: how can I load a module that defines a name under a different name?

I'm trying to load underscore.js with require.js like this:
require(["libs/underscore-1.2.3.js"], function(_) {
...
});
But this doesn't work because underscore.js exports a module name: define('underscore', function() { ... }).
Without renaming lib/underscore-1.2.3.js, how can I load it with require.js?
Alright, after some more googling, I've found: https://github.com/documentcloud/underscore/pull/338#issuecomment-3245213
Where
#dvdotsenko all AMD loaders allow mapping a module ID to a partial path, usually the configuration is called 'paths', so to do what you want:
requirejs.config({
paths:
underscore: 'js/libs/underscore-1.2.3.min'
}
});
require(['underscore'], function () {});
Since underscore is used by other higher-level modules, like backbone, a common dependency name needs to be used to communicate a common dependency on underscore, and it makes sense to call that dependency 'underscore'. The paths config gives a way to do the mapping to a specific URL you want to use for that dependency.
This doesn't answer my question (ie, I still don't know how I'd go about loading underscore if all I had was a URL), but at least it's a functional workaround.
While this doesn't strike me as the most ideal solution, you can require your external files, and then require their registered module names in the inner block.
JSFiddle Example
require(
['require','http://documentcloud.github.com/underscore/underscore-min.js'],
function(require){
require(['underscore'],function(_){
var a = _.intersection([1,2,3],[2,3,4]);
document.write("Underscore is available in the closure : " + a);
})
}
)
It might not look pretty, but that might be a recommended pattern for loading up initial assets so that they can be required intuitively in dependent modules.

Categories