Adding a implicit dependency in an AMD file - javascript

How do I add implicit requires to a set of AMD files?
I'm porting some code from a bower-managed app to a play, webjars app. The original app has several places that use jquery ($), but do not declare jquery in the define block. How does this happen? How can I do it in my new app?
The code I'm porting looks like:
define(['underscore',
'backbone',
'text!./html/my-view.html'],
function(_,
mvc,
myView) {
'use strict';
...
return {
render: function() {
var el = this.el;
$(el).html(myView);
...

Require js is probably loading Jquery before you define this module.
Backbone.Views has a dependency on Jquery, so without jquery , your views will not work.
Try to find the main module of this app that you're using and there you will figure out how requireJs loads Jquery.
Backbone has this piece of code. Which shows his dependency on Jquery.
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '1.1.2';
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
// the `$` variable.
Backbone.$ = $;

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.

include javascript files in marionette project

I have a marionette project, and I have my main js file which looks like:
define(["marionette", "handlebars"], function(Marionette, Handlebars){
...
});
Now I want to make a structure of my big app. So I would like to separate the content of this function to different files. So how can I do something like:
define(["marionette", "handlebars"], function(Marionette, Handlebars){
include routes.js
include menu/model.js
include menu/views.js
...
});
I think require.js can help me, but I don't know how. Any ideas?
To require a file in the AMD structure (like the one you describe), you can give the path to the file in the array and get the exported value as argument of the callback like this.
define(
[
"marionette",
"handlebars",
"routes",
"menu/model",
"menu/views"
],
function(Marionette, Handlebars, Routes, Model, MenuView){
// ...
});
Since this is a very basic thing in AMD, you should really read the documentation of Require.JS (here) and explanation about AMD modules (like this one). You will find lot of information about the AMD structure, etc
If you prefer, browserify lets you to load front-end javascript modules using the require syntax. It looks like this.
// library includes
var Marionette = require('backbone.marionette');
var handlebars = require('handlebars');
// custom includes
var routes = require('./routes.js');
var models = require('./menu/models.js');
var views = require('./menu/views.js');
var App = new Marionette.Application();
It includes modules recursively and there is less code. It implements the Common.js format so it looks and feels the same as node.js.

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.

Load prototype enhancements with require.js

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 = {
(...)

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']

Categories