I was going through some github library wherein I came across the following lines:
//Util.js
(function(exports,global){
global["true"] = exports;
"use strict";
...rest of the code here
})({}, function() {
return this;
}());
The above file was directly included in index.html.
I am aware of the concept of self-executing functions in JS. But what purpose could the above provide ?
The script is referencing the global 'this' to hold a property called 'true' that contains an an object called 'exports' which you probably already figured out. This script appears to be one that initializes some functionality.
My guess as to WHY they are doing it this way is because they are anticipating that 'this' might not just be run in a browser (probably for injecting mocks when unit testing for example) and so it is a way to abstract the global object.
The 'exports' and 'global' parameters are only mentioned as arguments and when setting the property global["true"] in your script. This is why I think it is an initializing script and the exports variable will be used later on by other related scripts. These related scripts which might also be under test (or whatever) and so their global object might be the same as this one.
Related
I have an angular universal project which is using azure application insights to log exceptions.
When using angular universal I get an error because the library uses a shim, which expects 2 global variables to be declared. I understand the declare keyword is used to declare a variable which references a global variable, that way you can write code relying on a global that isnt known in your library.
Here is the shim:
https://github.com/microsoft/ApplicationInsights-JS/blob/master/tools/shims/src/applicationinsights-shims.ts
It has these lines:
declare var __extends:(d: any, b: any) => any;
declare var __assign:(t: any) => any;
And here is the error I get:
ReferenceError: __assign is not defined
Supposedly these two variables are default globals for typescript but I cant find any information on that, clearly something is going wrong with the server side render. If I dont use Angular Universal I dont get the error.
Edit:
I realised I was using a package named domino to polyfill the global window object, and I guess the polyfill was missing something. I removed it because Angular comes with ways to handle cross-platform execution with such a polyfill.
requireJS is giving me a headache atm. requireJS is AMD which by definition says it's asynchronous. Normally I would define a module like this.
define("some Name", ["./moduleOne"],function(moduleOne){
//this would be undefined
moduleOne.whatEver();
var aMethod = function(){
//user aModule.whatever();
}
return {
method: aMethod;
}
});
Ok, I got that I can't directly use moduelOne.whatever because it is loaded asynchronous and it's not there if the callback is being called.
First Question, is this correct?
Now if I change the module definition to this:
define("some Name", function(require, exports){
var moduleOne = require(".moduleOne");
//this is OK
moduleOne.whatEver();
var aMethod = function(){
//user aModule.whatever();
}
exports.method = aMethod;
});
I can use aModule.whatever directly. As I read from the docs, using this (commonJS) style, requires parses the function with Function.prototype.toString, sees the require statement and load the modules directly.
I am pretty sure, I am misunderstanding something here and it would be nice of someone could explain how exactly requireJS works and if the second style is really synchronous.
Thanks
You've misunderstood how it works.
In both examples you give in your question the sequence of execution is:
Something requires the module named some_Name. (I don't think RequireJS is happy with module names that have spaces so I'm assuming a module name with an underscore.)
RequireJS looks for the dependencies and the factory function for the module some_Name. The factory is the function given to define when you define the module.
a. If it happens that define("some_Name"... was called before this step, then RequireJS just gets the dependencies and factory function that was given to define.
b. If define("some_Name"... has not been executed yet, RequireJS will go to the network and attempt to fetch a file that contains the define call and execute it. By convention this will be a file with the same name as the module name + the .js extension, but this can be overridden in RequireJS' configuration.
RequireJS checks whether the dependencies are loaded. If not, then it issues require calls for each dependency that is not loaded yet.
RequireJS calls the factory function with the resolved dependencies.
Note that I did not go over all possible scenarios here. I'm sticking with the most common cases to keep things simple.
So...
Ok, I got that I can't directly use moduelOne.whatever because it is loaded asynchronous and it's not there if the callback is being called.
First Question, is this correct?
No, this is not correct. By the time moduleOne.whatEver(); executes, the module moduleOne must have been loaded already. If moduleOne is undefined this is not because of RequireJS' asynchronous nature but because there is a bug in how moduleOne is defined. For instance, if it exports the value undefined, then moduleOne will be undefined. Or you may get an undefined value for moduleOne.whatEver which will then cause an error when you try to call it, but this would be caused by, for instance, forgetting to export whatEver.
The difference between the 2nd case and the first is that the 2nd uses the CommonJS sugar syntax and this causes step 2 above to have a bit of additional processing. Before RequireJS executes the factory it parses the function (as you mentioned) and then processes the factory function as if the defined had been called like this:
define("some_Name", ['require', 'exports', './moduleOne'], function (require, exports) {
The require and exports modules are special modules defined internally by RequireJS. Note how RequireJS adds ./moduleOne at the end of the list of dependencies. Once this is done, the process is exactly the same as for the 1st case.
By the time var moduleOne = require("./moduleOne"); is executed, the module has already been loaded. So what this line does is merely return a reference to the module.
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 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