I understand how things like proper name-spacing and the Module Pattern help issues associated with leaking into the global-scope.
I also completely see the value of resource dependency-management provided for in the require() protocol outlined in the CommonJS Specification.
However, I am befuddled as to the benefit of the AMD define() function's use and purpose.
The CommonJS signature for define is:
define(id?, dependencies?, factory);
Additionally…
I see people wrapping their Module
Pattern plug-ins with define() when
BOTH create an object at the
global-scope.
A file containing a normal Module
Pattern plug-in can be loaded
asynchronously as well.
At first, it "seemed" like yet-another plug-in wrapper...until I began to see folks use it alongside the Module Pattern.
So My Questions Are:
What does the define() protocol
outlined in CommonJS specification
buy me?
Is it somehow more eloquent?
Is it meant to replace the Modular Pattern?
Is it somehow faster?
If so, why?
// main.js
require("foo.js", function(foo) {
console.log(foo === 42); // true
});
//foo.js
/*
define(42);
define({
"foo": "bar"
});
define(["bar.js"], function(bar) {
return bar.foo;
});
*/
define(function() {
return 42;
});
Define is a great way to pass modular objects back without relying on global scope.
The particular API of define varies from library to library though.
Here the basic idea is that you call define in a file to define what that module is. Then when you require the file you get the module. This cuts out the middle man that is global scope.
It's no faster though (It's slower then injecting into global scope).
Using require and define you only have two global values.
The particular define example above matches the requireJS API
Related
This question already has answers here:
Is 'require(...)' a common javascript pattern or a library function?
(3 answers)
Closed 7 years ago.
I see this in many JS libraries out there, mostly looking through GitHub, currently looking at PeerJS. I'm referring to this:
var util = require('./util');
var EventEmitter = require('eventemitter3');
var Negotiator = require('./negotiator');
var Reliable = require('reliable');
...
window.Socket = require('./socket');
window.MediaConnection = require('./mediaconnection');
window.DataConnection = require('./dataconnection');
window.Peer = require('./peer');
window.RTCPeerConnection = require('./adapter').RTCPeerConnection;
window.RTCSessionDescription = require('./adapter').RTCSessionDescription;
window.RTCIceCandidate = require('./adapter').RTCIceCandidate;
window.Negotiator = require('./negotiator');
window.BinaryPack = require('js-binarypack');
...
Just from intuition, it seems like require() is importing/including whatever is being passed in, i.e., EventEmitter. However, I can't figure out where require() is coming from?
I'm not too familiar with NodeJS, and this seems like it's a NodeJS thing, but I don't understand how require() fits into a web browser context, where NodeJS doesn't exist.
I've seen RequireJS and Browserify, but these are libraries that would need to be included with application in order to use the require() function. In the example of PeerJS, I can just include it:
<script type="text/javascript" src="/static/js/peerjs.v0.3.13.js"></script>
... and it uses require() no problem. However, it doesn't look like there's any 3rd party libraries that are defining require() that are being bundled along with the PeerJS source code.
How is it being included? How is it being initialized? How is it fetching whatever is being passed in, i.e., "EventEmitter"?
It's a way to include external JavaScript (or really any other file) into your script through a single point of entry without introducing globals. It's most often used with Asynchronous Module Definition (AMD) and CommonJS modules. At it's highest level, require() is an API to use JavaScript modules. NodeJS uses the CommonJS syntax for the most part.
There's also no definite "better" one to use. It becomes almost an East Coast/West Coast turf war trying to discuss one vs the other. Some say that AMD modules are too verbose since you have to capture all of your imports in a closure and then use them which means you have to look in two different places for where you are defining your variables and imports:
AMD from RequireJS also Dojo
define('myModule', ['dep1', 'dep2'], function (dep1, dep2) {
return function () {};
});
CommonJS
var foobar = require('./foobar').foobar,
test = new foobar();
test.bar(); // 'Hello bar'
Additionally, some say that the A part of AMD doesn't really benefit you often enough to be worth the overhead.
Where does the "require" part come from?
In the browser, the require() comes from whatever library you are loading whether it be an AMD or CommonJS loader. However, for your above examples, you look like you're using it in a NodeJS context. NodeJS has the require() defined within the environment just like module.exports. In fact, the module.exports is what is given to whatever variable you're assigning to with the require(...).
Contrast the module.exports from CommonJS to how AMD gets your module into your variable's hands which is just the return from the closure that you put in a call to define().
Can these be used together?
One other thing to touch on is that they aren't exclusive to one another. They can be coerced into playing with one another either using some kind of wrapper or by using another convention: UMD. UMD tries to let you create modules that work no matter the environment exposing your module through whatever convention is available be it module.exports or define().
I am using requireJS 2.x. I found out that some tutorials (and the official docs) sometimes use
requirejs.config({ [...] });
requirejs(["module"]) ...
and sometimes
require.config({ [...] });
require(["module"]) ...
Is there any difference between those two functions (require and requirejs)? I could not find any word about that in the docs. :(
They are exactly the same.
The reason is some environments might already have a require, in which case RequireJS doesn't overwrite it and allows usage of the library through requirejs
See this commit - https://github.com/jrburke/requirejs/commit/be45948433b053921dc6a6a57bf06d04e13b3b39
Are requirejs And require the Same?
As of RequireJS 2.1.15, require and requirejs in the global space are indeed "exactly the same", as can be evidenced by this test you can perform in the console:
> require === requirejs
true
That the test returns true tells you they are the exact same function object. They are not two functions that happen to have similar or identical code. They are the same object, period.
Note, however when you execute define(['require'], function (require) { The require passed to the function is normally different from the global require.
Should You Use require or requirejs?
It depends. RequireJS is an AMD loader but it is not the only loader in town. If you want to write code that conforms 100% to the AMD spec, so that someone using your code can use whatever loader they want without having to modify your code, then you should use require at the global level, because requirejs is specific to RequireJS. Another AMD loader won't define it. The AMD spec defines require but not requirejs.
If you are loading something else that defines a global require then you have to use requirejs at the global level to avoid conflict.
Inside a module, always use define to obtain a reference to require. You should do this quite irrespective of whether there is a conflict in the global space.
OK, they may indeed be "exactly the same". Let's then focus on why you would use one versus the other...
What is unclear is what should be considered "best practice": If requirejs provides extra assurance "if some environments might already have a require", then wouldn't it be a good idea to always use the requirejs function to define a require configuration rather than the require function?
Also, what happens if the unthinkable happens and the environment in question not only already has a "require" defined but also has a "requirejs" defined? Does that mean we should have a requirejsjs too? And so on...?
They are Same
Open website which loaded require already
then open Chrome console
type require in console and press enter
type requirejs in console and press enter
you can find that they are same function with different names
I am intermediate level javascript developer trying to understand how great javascript developer write their code and i decide to start looking into Backbone library as starting point.
here is some code snippet for initial setup in backbone please help me to make sense out of it.
code1 -
(function(){
var root = this;
}).call(this);
is there any specific reason to use call method over simply using (), or it is just a coding preference, if i have to write the same code i would do something like this.
(function(root){
})(this);
code2 -
var Backbone;
if (typeof exports !== 'undefined') {
Backbone = exports;
} else {
Backbone = root.Backbone = {};
}
now there is no definition of export in the global scope nor it is defined anywhere in local scope then what is if block is doing here if i was writing the same code i would write
var Backbone = root.Backbone = {};
code 3
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore')._;
again I can't find definition of require anywhere in local or global scope
Code Block 1
This is down to developer preference, you could write that code either way and, indeed, many libraries do prefer your suggested style.
Code Block 2
This block is a take on the AMD Boiler Plate. AMD libraries provide the hooks required to split your JavaScript code into modules. In the code blocks case, the exports object is a global used by the CommonJS Module Standard. If the exports global is not present then Backbone is added to the root object directly.
An interesting side note on this is the fact that Backbone does not support exporting to the popular RequireJS AMD library.
Code Block 3
require is another global introduced by AMD libraries, see above.
In code1 call(this) passes a reference of the current this to the function. In case of doing it in the global scope, this is window. I think it's just preference and doesn't make a difference in that case.
require and exports are provided by NodeJS (or CommonJS compliant library) and they're part of the CommonJS spec.
I think that code 2 is to protect the framework in case someone else defined exports in global scope. So they check if its not undefined meaning someone else did then they just reset it to an empty object.
#JonnyReeves has pretty much answered all of your questions. Not sure you've seen the annotated source code of backbone.js before, this would be useful for you.
http://documentcloud.github.com/backbone/docs/backbone.html
I have searched high and low for documentation on this, but I just cannot find anything anywhere.
I am using Aloha and want to use their sidebar prototype to create a new side bar of my own attached to other plugin functionality.
Their sidebar.js starts off with this, but I can't for the life of me find any documentation that explains what it means.
define( [
'aloha/core',
'aloha/jquery',
'aloha/selection'
], function (Aloha, jQuery, Selection, Plugin) {
It then goes on in that wrapper to define a bunch of functions, so vars and some proptotypes- which I can just about get my head around...
What is that saying or where can I find an explanation?
I can't say for sure without seeing the entire script, but it's likely to be the define function from RequireJS, in particular the "define with dependencies" form of that function. It is used to define a "module":
A module is different from a traditional script file in that it
defines a well-scoped object that avoids polluting the global
namespace. It can explicitly list its dependencies and get a handle on
those dependencies without needing to refer to global objects, but
instead receive the dependencies as arguments to the function that
defines the module.
And the "define with dependencies" form of define is described as follows:
If the module has dependencies, the first argument should be an array
of dependency names, and the second argument should be a definition
function. The function will be called to define the module once all
dependencies have loaded. The function should return an object that
defines the module.
This is AMD pattern for writing modules which AMD stands for Asynchronous Module Definition for when you need to import modules async basically rather than something like commonJS.
define(['module1', 'module2'], function(module1, module2) {
console.log(module1.sayHi());
});
Define takes an array of dependencies and once all those are loaded in the background (async) in a non-blocking way, define calls the callback which in turn accepts arguments (in this case the dependencies).
Another thing to note is that each one of those modules also needs to be defined using "define" keyword. So for instance module1 would be defined like below :
define([], function() {
return {
sayHi: function() {
console.log('Hi Hi');
},
};
});
This way of writing modules (AMD) allows you to write with browser compatibility in mind (no require() like in nodeJS) and also you can define many formats including objects, JSON, etc while for instance commonJS needs modules to be objects.
Keep in mind, AMD has it's own downfalls. Hope this helps someone.
I have a javascript autocomplete plugin that uses the following classes (written in coffeescript): Query, Suggestion, SuggestionCollection, and Autocomplete. Each of these classes has an associated spec written in Jasmine.
The plugin is defined within a module, e.g.:
(function(){
// plugin...
}).call(this);
This prevents the classes from polluting the global namespace, but also hides them from any tests (specs with jasmine, or unit-tests with something like q-unit).
What is the best way to expose javascript classes or objects for testing without polluting the global namespace?
I'll answer with the solution I came up with, but I'm hoping that there is something more standard.
Update: My Attempted Solution
Because I'm a newb with < 100 xp, I can't answer my own question for 8 hours. Instead of waiting I'll just add what I did here.
In order to spec these classes, I invented a global object called _test that I exposed all the classes within for testing. For example, in coffeescript:
class Query
// ...
class Suggestion
// ...
// Use the classes
// Expose the classes for testing
window._test = {
Query: Query
Suggestion: Suggestion
}
Inside my specs, then, I can reveal the class I'm testing:
Query = window._test.Query
describe 'Query', ->
// ...
This has the advantage that only the _test object is polluted, and it is unlikely it will collide with another definition of this object. It is still not as clean as I would like it, though. I'm hoping someone will provide a better solution.
I think something like the CommonJS module system (as used by brunch, for example) would work.
You can separate your code into modules, and the parts that need them would import them via require. The only part that gets "polluted" is the module map maintained by the module management code, very similar to your test object.
In Autocomplete.coffee
class exports.Query
// ...
class exports.Suggestion
// ...
and then in Autocomplete.spec.coffee
{Query, Suggestion} = require 'app/models/Autocomplete'
describe 'Query', ->